val / one-to-many-iterator
一对一连接的辅助迭代器和生成器
v1.0.1
2015-03-02 13:59 UTC
Requires (Dev)
- phpunit/phpunit: 4.*
- squizlabs/php_codesniffer: 1.*
This package is not auto-updated.
Last update: 2024-09-24 08:28:06 UTC
README
一对一连接的辅助迭代器和生成器。
概述
当你想要获取一对一关系时,你可能使用 JOIN
来避免 N+1 查询问题。
尽管如此,迭代结果可能很困难,尤其是在你需要为某个过程加载关系的整个“多”部分时。
这就是我创建这个小型库的原因。它接受一个数组的 Traversable
,有一个共同的键来区分一对一关系的“一”部分,并按此键排序(因此可以流式传输项目,而无需在内存中加载整个集合)。
然后它将关系的“多”部分聚合到一个可配置的键中。
安装
composer require val/one-to-many-iterator
示例
你的数据库结果迭代器,一旦转换为数组,看起来像这样(一个典型的 JOIN
)
<?php [ ['id' => 1, 'parent_column' => 'hello', 'child_column' => 'foo'], ['id' => 1, 'parent_column' => 'hello', 'child_column' => 'bar'], ['id' => 2, 'parent_column' => 'world', 'child_column' => 'baz'], ];
但你想迭代类似这样的内容
<?php [ [ 'id' => 1, 'parent_column' => 'hello', 'children' => [ ['child_column' => 'foo'], ['child_column' => 'bar'], ], ], [ 'id' => 2, 'parent_column' => 'world', 'children' => [ ['child_column' => 'baz'], ], ], ];
为了实现这一点,只需将你的数据库结果传递给 Val\Iterator\OneToManyIterator
或 Val\Iterator\OneToManyGenerator
,同时配置共同的键(这里,id
),以及聚合键(这里,children
)。
假设 $result
包含原始 SQL 结果迭代器
<?php // With an iterator $aggregated = new OneToManyIterator('id', 'children', $result); // With a generator $aggregated = new OneToManyGenerator('id', 'children', $result); foreach ($aggregated as $i => $parent) { $parent['id']; $parent['parent_column']; foreach ($parent['children'] as $child) { $child['child_column']; } }
迭代器和生成器之间的区别在于,前者实现了一个原始的 PHP 迭代器,而后者使用了一个 PHP 生成器(自 5.5 版本以来可用)。
错误
- 当使用
LEFT JOIN
而不是JOIN
时,因此不能保证至少有一个关系项的存在,聚合字段仍然会包含一个值为null
的项。