PHP项目集合与流式操作

wen PHP项目 2

本文目录导读:

PHP项目集合与流式操作

  1. PHP集合操作
  2. PHP流式操作
  3. 实际应用场景

我来详细介绍PHP中的集合(Collection)流式操作(Stream Operations)

PHP集合操作

基础数组集合操作

<?php
// 基础集合数据
$users = [
    ['id' => 1, 'name' => 'Alice', 'age' => 25, 'city' => 'Beijing'],
    ['id' => 2, 'name' => 'Bob', 'age' => 30, 'city' => 'Shanghai'],
    ['id' => 3, 'name' => 'Charlie', 'age' => 22, 'city' => 'Beijing'],
    ['id' => 4, 'name' => 'David', 'age' => 35, 'city' => 'Guangzhou'],
];
// 过滤
$beijingUsers = array_filter($users, fn($user) => $user['city'] === 'Beijing');
// 映射
$names = array_map(fn($user) => $user['name'], $users);
// 排序
usort($users, fn($a, $b) => $a['age'] - $b['age']);
// 分组
$groupByCity = [];
foreach ($users as $user) {
    $groupByCity[$user['city']][] = $user;
}

使用Laravel Collection

<?php
use Illuminate\Support\Collection;
$collection = collect([
    ['id' => 1, 'name' => 'Alice', 'age' => 25],
    ['id' => 2, 'name' => 'Bob', 'age' => 30],
    ['id' => 3, 'name' => 'Charlie', 'age' => 22],
]);
// 链式操作
$result = $collection
    ->where('age', '>', 23)
    ->sortBy('name')
    ->take(2)
    ->values()
    ->toArray();
// 高级操作
$averageAge = $collection->avg('age');
$maxAge = $collection->max('age');
$groupByName = $collection->groupBy(function($item) {
    return strtoupper(substr($item['name'], 0, 1));
});

自定义Collection类

<?php
class SimpleCollection implements ArrayAccess, Countable, IteratorAggregate {
    private array $items;
    public function __construct(array $items = []) {
        $this->items = $items;
    }
    // 过滤
    public function filter(callable $callback): self {
        return new self(array_filter($this->items, $callback));
    }
    // 映射
    public function map(callable $callback): self {
        return new self(array_map($callback, $this->items));
    }
    // 排序
    public function sort(callable $callback): self {
        $items = $this->items;
        usort($items, $callback);
        return new self($items);
    }
    // 获取最大值
    public function max(?string $key = null): mixed {
        if ($key === null) {
            return max($this->items);
        }
        return max(array_column($this->items, $key));
    }
    // 链式操作示例
    public function processChain(): self {
        return $this
            ->filter(fn($item) => $item['active'] === true)
            ->sort(fn($a, $b) => $a['priority'] <=> $b['priority'])
            ->map(fn($item) => array_merge($item, ['processed' => true]));
    }
    public function getIterator(): ArrayIterator {
        return new ArrayIterator($this->items);
    }
    public function count(): int {
        return count($this->items);
    }
    public function offsetExists($offset): bool {
        return isset($this->items[$offset]);
    }
    public function offsetGet($offset): mixed {
        return $this->items[$offset] ?? null;
    }
    public function offsetSet($offset, $value): void {
        if ($offset === null) {
            $this->items[] = $value;
        } else {
            $this->items[$offset] = $value;
        }
    }
    public function offsetUnset($offset): void {
        unset($this->items[$offset]);
    }
}

PHP流式操作

流式文件处理

<?php
// 读取大文件
function processLargeFile(string $filename, callable $handler): void {
    $handle = fopen($filename, 'r');
    if ($handle === false) {
        throw new RuntimeException("Cannot open file: $filename");
    }
    while (($line = fgets($handle)) !== false) {
        $handler(trim($line));
    }
    fclose($handle);
}
// 使用生成器实现流式处理
function readLines(string $filename): Generator {
    $handle = fopen($filename, 'r');
    if ($handle === false) {
        throw new RuntimeException("Cannot open file: $filename");
    }
    while (($line = fgets($handle)) !== false) {
        yield trim($line);
    }
    fclose($handle);
}
// 使用示例
$lines = readLines('large_file.txt');
foreach ($lines as $lineNumber => $line) {
    echo "Line $lineNumber: $line\n";
}

流式数据转换管道

<?php
class StreamPipeline {
    private array $operations = [];
    private mixed $data;
    public function __construct(mixed $data) {
        $this->data = $data;
    }
    public function filter(callable $callback): self {
        $this->operations[] = function($data) use ($callback) {
            return array_filter($data, $callback);
        };
        return $this;
    }
    public function map(callable $callback): self {
        $this->operations[] = function($data) use ($callback) {
            return array_map($callback, $data);
        };
        return $this;
    }
    public function reduce(callable $callback, mixed $initial = null): self {
        $this->operations[] = function($data) use ($callback, $initial) {
            return array_reduce($data, $callback, $initial);
        };
        return $this;
    }
    public function execute(): mixed {
        $result = $this->data;
        foreach ($this->operations as $operation) {
            $result = $operation($result);
        }
        return $result;
    }
}
// 使用示例
$pipeline = new StreamPipeline([1, 2, 3, 4, 5, 6]);
$result = $pipeline
    ->filter(fn($n) => $n % 2 === 0)  // 只保留偶数
    ->map(fn($n) => $n * 2)            // 每个数乘以2
    ->reduce(fn($carry, $n) => $carry + $n, 0)  // 求和
    ->execute();
echo $result; // 输出: 24

高级流式操作实现

<?php
class Stream {
    private array $data;
    private array $pipeline = [];
    public function __construct(array $data) {
        $this->data = $data;
    }
    public static function of(array $data): self {
        return new self($data);
    }
    // 过滤操作
    public function filter(callable $predicate): self {
        $this->pipeline[] = function($data) use ($predicate) {
            return array_values(array_filter($data, $predicate));
        };
        return $this;
    }
    // 映射操作
    public function map(callable $mapper): self {
        $this->pipeline[] = function($data) use ($mapper) {
            return array_map($mapper, $data);
        };
        return $this;
    }
    // 扁平化映射
    public function flatMap(callable $mapper): self {
        $this->pipeline[] = function($data) use ($mapper) {
            $result = [];
            foreach ($data as $item) {
                $result = array_merge($result, $mapper($item));
            }
            return $result;
        };
        return $this;
    }
    // 去重
    public function distinct(): self {
        $this->pipeline[] = function($data) {
            return array_values(array_unique($data, SORT_REGULAR));
        };
        return $this;
    }
    // 排序
    public function sorted(?callable $comparator = null): self {
        $this->pipeline[] = function($data) use ($comparator) {
            $sorted = $data;
            if ($comparator) {
                usort($sorted, $comparator);
            } else {
                sort($sorted);
            }
            return $sorted;
        };
        return $this;
    }
    // 限制数量
    public function limit(int $limit): self {
        $this->pipeline[] = function($data) use ($limit) {
            return array_slice($data, 0, $limit);
        };
        return $this;
    }
    // 跳过
    public function skip(int $count): self {
        $this->pipeline[] = function($data) use ($count) {
            return array_slice($data, $count);
        };
        return $this;
    }
    // 收集结果
    public function collect(): array {
        $result = $this->data;
        foreach ($this->pipeline as $operation) {
            $result = $operation($result);
        }
        return $result;
    }
    // 获取第一个元素
    public function first(): mixed {
        $result = $this->collect();
        return !empty($result) ? $result[0] : null;
    }
    // 统计
    public function count(): int {
        return count($this->collect());
    }
    // 判断是否所有元素满足条件
    public function allMatch(callable $predicate): bool {
        foreach ($this->data as $item) {
            if (!$predicate($item)) {
                return false;
            }
        }
        return true;
    }
    // 判断是否存在满足条件的元素
    public function anyMatch(callable $predicate): bool {
        foreach ($this->data as $item) {
            if ($predicate($item)) {
                return true;
            }
        }
        return false;
    }
}
// 使用示例
$people = [
    ['name' => 'Alice', 'age' => 25, 'department' => 'IT'],
    ['name' => 'Bob', 'age' => 30, 'department' => 'HR'],
    ['name' => 'Charlie', 'age' => 22, 'department' => 'IT'],
    ['name' => 'David', 'age' => 35, 'department' => 'Finance'],
];
$result = Stream::of($people)
    ->filter(fn($p) => $p['age'] > 23)
    ->map(fn($p) => [
        'name' => $p['name'],
        'age' => $p['age'],
        'seniority' => $p['age'] > 30 ? 'Senior' : 'Junior'
    ])
    ->sorted(fn($a, $b) => $a['age'] <=> $b['age'])
    ->limit(3)
    ->collect();
print_r($result);

惰性求值实现

<?php
class LazyStream {
    private Generator $generator;
    private array $operations = [];
    public function __construct(Generator $generator) {
        $this->generator = $generator;
    }
    public function filter(callable $predicate): self {
        $this->operations[] = function(Generator $gen) use ($predicate) {
            foreach ($gen as $item) {
                if ($predicate($item)) {
                    yield $item;
                }
            }
        };
        return $this;
    }
    public function map(callable $mapper): self {
        $this->operations[] = function(Generator $gen) use ($mapper) {
            foreach ($gen as $item) {
                yield $mapper($item);
            }
        };
        return $this;
    }
    // 惰性执行,只在需要时计算结果
    public function execute(): Generator {
        $currentGen = $this->generator;
        foreach ($this->operations as $operation) {
            $currentGen = $operation($currentGen);
        }
        return $currentGen;
    }
}
// 使用示例 - 处理大量数据
function generateLargeDataset(int $count): Generator {
    for ($i = 0; $i < $count; $i++) {
        yield ['id' => $i, 'value' => rand(1, 1000)];
    }
}
$stream = new LazyStream(generateLargeDataset(1000000));
$result = $stream
    ->filter(fn($item) => $item['value'] > 500)
    ->map(fn($item) => $item['id'] * 2)
    ->execute();
// 只在遍历时真正计算
foreach ($result as $value) {
    echo $value . "\n";
}

实际应用场景

数据清洗管道

<?php
class DataCleaningPipeline {
    public function process(array $data): array {
        return Stream::of($data)
            ->filter(fn($item) => !empty($item['email']))  // 过滤空邮箱
            ->map(fn($item) => [
                ...$item,
                'email' => strtolower(trim($item['email'])),  // 清洗数据
                'phone' => preg_replace('/[^0-9]/', '', $item['phone'] ?? '')
            ])
            ->distinct()  // 去重
            ->sorted(fn($a, $b) => $a['created_at'] <=> $b['created_at'])  // 按时间排序
            ->collect();
    }
}

报表生成

<?php
class ReportGenerator {
    public function generateSalesReport(array $transactions): array {
        return Stream::of($transactions)
            ->filter(fn($t) => $t['status'] === 'completed')
            ->groupBy(fn($t) => $t['product_id'])
            ->map(function($group) {
                return [
                    'product_id' => $group[0]['product_id'],
                    'total_sales' => array_sum(array_column($group, 'amount')),
                    'count' => count($group),
                    'average' => array_sum(array_column($group, 'amount')) / count($group)
                ];
            })
            ->sorted(fn($a, $b) => $b['total_sales'] <=> $a['total_sales'])
            ->take(10)
            ->collect();
    }
}

这些集合和流式操作模式可以大幅提高PHP代码的可读性和维护性,特别适合数据处理、批量操作和管道式转换等场景。

抱歉,评论功能暂时关闭!