Вы должны сделать гораздо больше использовать итераторы в 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
, который полностью инкапсулирует разбиение на страницы на собственный объект. См. Мой answer to XML pagination with PHP для получения дополнительной информации.
Он предлагает еще один итератор через $pagination->getLimitIterator($filtered)
, чтобы он предлагал те отфильтрованные файлы, которые находятся на указанной странице ($_GET['page']
в приведенном выше примере). Он также предлагает список страниц, чтобы вы могли выводить ссылки на другие страницы.
Так что было сделано здесь:
- Ваша проблема фильтрации файлов была инкапсулированные в фильтр-итератора.
- Ваша проблема с разбиением на страницы была инкапсулирована в объект pagination, который также предоставляет итератор.
- Ваша проблема с фильтрацией файлов globbed была решена путем превращения массива в итератор.
Технически вы можете решить все эти проблемы с помощью массивов, однако большая польза от итераторов заключается в том, что они гораздо более гибкие, чем массивы.
Вы можете, например, дальнейшее совершенствование пути создания итератора, который будет создавать специальный ребенок SimpleXMLElement
который также несет в себе алгоритм, чтобы получить тип документа и каких knowns о файле тропе. Предоставление этого отдельного интерфейса поможет с фильтром-итератором.
Также при использовании разбиения на страницы может быть целесообразным кэшировать фильтр-итератор, чтобы операция подсчета не слишком сильно нагружалась.
Признаки итераторов здесь явно являются повторным использованием кода, например. объект LimitPagination
работает только с любым типом разбиения на страницы, для которого вы предоставляете данные для разбиения на страницы в виде итератора.
Если вы хотите использовать массивы, вам необходимо превратить его в объект ArrayPagination
, и вместо фильтра-итератора вы можете использовать array_filter()
с функцией обратного вызова, которая фильтрует ваши файлы. И если вы используете массивы для прототипирования, есть также ArrayIterator
, поэтому вы можете переключиться с массивов на итератор между ними (и есть CallbackFilterIterator
, что также должно позволить вам повторно использовать функцию фильтра массива).
Вы должны заглянуть в SPL: http://php.net/class.globiterator + http://php.net/class.limititerator - Это того стоит. Проблема уже решена.) Для разбивки на страницы, я думаю, что я оставил код на этом веб-сайте, переделывая * 'PageIterator' * или *' PagingIterator' *. Related: http://stackoverflow.com/a/15741465/367456 – hakre