您应该更多地使用 PHP 中的迭代器来划分工作,甚至:
//Pages
$perPage = 10; // Avoid magic numbers
$files = new GlobIterator('docs/*.xml');
$filtered = new FileXmlDoctypeFilterIterator($files, $requestedType);
$count = iterator_count($filtered);
$pagination = new LimitPagination($_GET['page'], $count, $perPage);
foreach ($pagination->getLimitIterator($filtered) as $file)
{
$xml = simplexml_load_file($file);
...
}
那么这是如何工作的呢?首先,通过使用预定义GlobIterator
的名称,您可能已经看到了它的作用。但它不是返回一个数组glob()
,而是一个迭代器。
在这里特别这样做是为了允许在这里与其他迭代器堆叠。例如,下一个是具体的FilterIterator
,因此您需要将当前用于过滤器决策的代码移动到此迭代器中。PHP 手册中记录了它是如何工作的。
iterator_count()
然后使用该函数获得所有过滤文件的计数,然后将其与LimitPagination
将分页完全封装到它自己的对象中的对象一起使用。有关它的更多信息,请参阅我对使用 PHP 进行 XML 分页的回答。
它提供了另一个迭代器,$pagination->getLimitIterator($filtered)
因此它将提供指定页面内的那些过滤文件($_GET['page']
在上面的示例中)。它还提供页面列表,以便您可以将链接输出到其他页面。
那么这里做了什么:
- 您过滤文件的问题已被封装到过滤器迭代器中。
- 您的分页问题已被封装到一个分页对象中,该对象也提供了一个迭代器。
- 通过将数组转换为迭代器,您的过滤 globbed 文件的问题已得到解决。
从技术上讲,您也可以使用数组解决所有这些问题,但是这里使用迭代器的最大好处是它们比数组灵活得多。
例如,您可以通过创建一个迭代器来进一步改进这一点,该迭代器将创建一个特殊的子代,SimpleXMLElement
该子代还带有获取文档类型的算法并且知道文件路径。给这个独特的接口将有助于过滤迭代器。
此外,由于涉及分页,缓存过滤器迭代器是有意义的,这样计数操作的权重就不会太重。
这里迭代器的好处显然是代码重用,例如,该LimitPagination
对象仅适用于您提供数据以以迭代器形式进行分页的任何类型的分页。
如果您想坚持使用数组,则需要将其转换为ArrayPagination
对象,而不是过滤器迭代器,您可以使用array_filter()
过滤文件的回调函数。如果您使用数组进行原型设计,ArrayIterator
那么您还可以在两者之间从数组切换到迭代器(并且还CallbackFilterIterator
应该允许您重新使用数组过滤器功能)。