Перейти к содержимому
Поиск
Php Разработка

PHP: полный мануал с примерами, функциями и ООП

Практический мануал PHP: от переменных и читаемого кода до безопасных форм, интеграций, базы данных и ООП на примере магазина. Учебный маршрут, поиск функций, подробные примеры, разбор ошибок и исходники для скачивания.

Александр НекрасовИзменено:
Практический мануал PHP: от переменных и функций к объектной модели интернет-магазина
PHP 8.5.11149 глав4458 карточек справочника
Дерево руководства

Глава 75 · От первого результата к полному справочнику

SPL: полный справочник стандартной библиотеки PHP

Все интерфейсы, исключения, функции, структуры данных, итераторы и файловые классы SPL: от первой понятной задачи до точного контракта каждого официального метода.

Интерфейс SPL: договор, который соединяет ваш код с готовым алгоритмом

Интерфейс нужен, когда готовый алгоритм должен работать с разными объектами одинаковым способом. Например, обходчик дерева не обязан знать, хранится ли каталог в массиве, файлах или ответе API: ему достаточно договора RecursiveIterator. Интерфейс перечисляет обязательные методы и их типы, но не создаёт данные, не пишет реализацию и не запускает методы сам.

Как работает договор
  1. Ваш класс пишет implements и реализует обязательные методы
  2. Клиент принимает объект по имени интерфейса
  3. Клиент вызывает только обещанные операции
  4. Конкретный объект сам решает, откуда взять данные
ИнтерфейсРеальная потребностьГотовый следующий инструмент
OuterIteratorОбернуть источник фильтром или преобразованием и при необходимости достать внутренний итератор.FilterIterator и IteratorIterator
RecursiveIteratorРазличить лист и ветку и пройти дерево неизвестной глубины.рекурсия
SeekableIteratorПерейти к известной позиции: страница, строка, кадр.ArrayIterator и LimitIterator
SplSubject + SplObserverСообщить нескольким получателям об изменении, не вызывая каждого по имени.интерфейсы в ООП

OuterIterator: обёртка сохраняет путь к источнику

Фильтр, ограничитель или преобразователь может выглядеть как самостоятельный Iterator, но внутри у него остаётся исходный Iterator. getInnerIterator() даёт осознанный доступ к источнику — например, для диагностики состава цепочки. Менять внутренний объект через этот доступ можно, но тогда поведение всех обёрток над ним тоже изменится.

Подробные карточки договора: OuterIterator::getInnerIterator.

Официальная страница: The OuterIterator interface.

RecursiveIterator: каждый элемент отвечает, является ли он веткой

Обычный Iterator выдаёт плоскую последовательность. RecursiveIterator добавляет два вопроса: есть ли у текущего элемента дети и каким итератором их обойти. Так RecursiveIteratorIterator может пройти дерево любой конечной глубины. Циклическую структуру он сам не распознаёт: защита от повторного посещения остаётся обязанностью модели.

Подробные карточки договора: RecursiveIterator::hasChildren, RecursiveIterator::getChildren.

Официальная страница: The RecursiveIterator interface.

SeekableIterator: перейти к позиции по номеру

Когда клиент знает смещение, последовательное чтение от начала тратит лишнюю работу. seek($offset) устанавливает текущую позицию. Смещение — позиция, а не произвольный ключ: конкретная реализация определяет допустимый диапазон и должна ясно сообщать об ошибке.

Подробные карточки договора: SeekableIterator::seek.

Официальная страница: The SeekableIterator interface.

SplObserver: получатель уведомления

Observer полезен, когда после одного изменения нужны независимые реакции: записать аудит, обновить индекс, сформировать уведомление. Метод update получает Subject, поэтому состояние или описание события должно быть доступно через сам Subject. Встроенного объекта события интерфейс не предоставляет.

Подробные карточки договора: SplObserver::update.

Официальная страница: The SplObserver interface.

SplSubject: реестр подписчиков и момент уведомления

Subject хранит подписчиков, добавляет и удаляет их, а затем синхронно вызывает update. Удобный контейнер — SplObjectStorage: один и тот же объект-подписчик не появляется дважды. Интерфейс не задаёт очередь, повтор при отказе, порядок транзакции или изоляцию ошибок; эти решения принадлежат приложению.

Подробные карточки договора: SplSubject::attach, SplSubject::detach, SplSubject::notify.

Официальная страница: The SplSubject interface.

Функции SPL: найти договор, обойти данные, загрузить класс и различить объекты

Эти 15 функций решают четыре разные задачи. Функции class_* исследуют уже известный класс; iterator_* выполняют конечный обход; spl_autoload_* управляют очередью загрузчиков; spl_object_* дают временную идентичность живого объекта. Одинаковый префикс SPL не означает общий сценарий или одинаковую стоимость.

ЗадачаФункцииСначала спросите
Исследовать типclass_implements, class_parents, class_uses, spl_classesНужны объявленные связи или фактическое поведение через instanceof?
Материализовать/посчитать обходiterator_apply, iterator_count, iterator_to_arrayКонечен ли источник и допустимо ли потратить память/время на весь поток?
Автоматически подключить классшесть функций spl_autoload*Есть ли Composer и PSR-4, которые уже решают задачу проекта?
Различить два живых объектаspl_object_hash, spl_object_idНужен временный ключ процесса или устойчивый ID предметной сущности?

Карта всего SPL: от задачи к точной карточке

Начинающему удобнее идти от задачи; опытному — открыть точную функцию или метод. Оба маршрута ведут к одной карточке с сигнатурой, параметрами, результатом, ошибками и двумя исполненными примерами.

Мне нужноОткрыть
Обернуть или обойти дерево/перейти к позицииинтерфейсы итераторов
Разослать несколько синхронных реакцийSplSubject и SplObserver
Понять interface/parent/trait классаclass_implements, class_parents, class_uses
Посчитать или материализовать iterableiterator_count, iterator_to_array
Настроить/проверить autoloadspl_autoload_register, spl_autoload_functions
Различить живые объекты текущего процессаspl_object_id, spl_object_hash
Выбрать стандартный тип исключения13 канонических карточек SPL

SPL-исключения: одна иерархия, 13 точных смыслов

Все 13 официальных exception classes уже имеют канонические карточки в полном справочнике исключений. Этот модуль обогатил те же самые sections, сохранив их IDs: открыть дерево и выбор типа.

Выбирайте класс по нарушенному договору, а не по удобному тексту сообщения. Для ожидаемого отсутствия результата null/result-object может быть яснее исключения; для нештатного отказа сохраняйте previous и решайте политику на границе приложения.

Структуры данных SPL: выбрать операцию, а не модное имя

Структура данных определяет, какие действия программа выражает прямо: взять первый запрос, выбрать самый срочный, обратиться к фиксированной позиции, сортировать обёрнутый массив или прикрепить состояние к конкретному объекту. Сначала сформулируйте требование и только потом выбирайте класс. Обычный PHP-массив остаётся универсальным и часто самым понятным вариантом.

Карта выбора
  1. Нужны оба конца и порядок → SplDoublyLinkedList / SplQueue / SplStack
  2. Всегда нужна лучшая по правилу запись → SplHeap / SplPriorityQueue
  3. Известно точное число позиций → SplFixedArray
  4. Нужен объектный API вокруг PHP-массива → ArrayObject
  5. Ключом должен быть object → SplObjectStorage

Это модель операций, а не схема внутренней памяти байт-в-байт. Реальная стоимость зависит от версии PHP, типов значений и нагрузки. Измеряйте тот сценарий, который будет работать в приложении.

Одна заявка: FIFO для обычных и приоритет для срочныхСамостоятельный пример
<?php
$normal = new SplQueue();
$normal->enqueue('Ежедневный отчёт');
$normal->enqueue('Обновить каталог');

$urgent = new SplPriorityQueue();
$urgent->insert('Сбросить пароль', 100);
$urgent->insert('Проверить остаток', 20);

echo 'Срочно: ', $urgent->extract(), "\n";
echo 'По очереди: ', $normal->dequeue(), "\n";
echo 'Следом: ', $normal->dequeue(), "\n";
Ожидаемый результат
Срочно: Сбросить пароль
По очереди: Ежедневный отчёт
Следом: Обновить каталог

SplQueue выбирает первый добавленный элемент. SplPriorityQueue выбирает наибольший priority независимо от времени вставки. Это два разных требования, поэтому структуры не заменяют друг друга. Обе живут только в памяти процесса и не являются сервером фоновых заданий.

Скачать самостоятельный пример с результатом и README

Три требования — три разных контейнераСамостоятельный пример
<?php
$week = new SplFixedArray(2);
$week[0] = 'Пн: 8 заказов';
$week[1] = 'Вт: 11 заказов';

$settings = new ArrayObject(['currency' => 'RUB']);
$order = (object) ['id' => 42];
$states = new SplObjectStorage();
$states[$order] = 'paid';

echo $week[1], "\n";
echo 'Валюта: ', $settings['currency'], "\n";
echo 'Заказ ', $order->id, ': ', $states[$order], "\n";
Ожидаемый результат
Вт: 11 заказов
Валюта: RUB
Заказ 42: paid

SplFixedArray выражает известное число позиций 0…n−1. ArrayObject оборачивает обычные ключи/значения объектным API. SplObjectStorage использует конкретный объект как ключ. Выбор идёт от требуемой операции, а не от слова «быстрее».

Скачать самостоятельный пример с результатом и README

СемействоСильная сторонаКлючевое ограничениеПодробный вход
Связные списки, stack, queueОперации на концах и явный LIFO/FIFO.Произвольный индекс не превращается в быстрый массив; процесс завершится — данные исчезнут.SplDoublyLinkedList
Heap и priority queueВершина по одному правилу сравнения.Полный foreach потребляет кучу; равный priority не гарантирует FIFO.SplPriorityQueue
SplFixedArrayПозиции 0…n−1 и явный размер.Нет строковых ключей; изменение размера может потерять хвост.SplFixedArray
ArrayObject[], count, foreach и свой Iterator вокруг записей.Не валидирует схему и не гарантирует выигрыш памяти.ArrayObject
SplObjectStorageКарта object identity → info и множество объектов.Сильные ссылки; hash не постоянный бизнес-ID.SplObjectStorage

Полный справочник ветки содержит все десять официальных классов и все их официальные методы, включая исторические страницы SplFixedArray и deprecated aliases SplObjectStorage. Каждая карточка объясняет вход, возврат, отказ, версии и два практических контекста.

SplQueue: кто пришёл первым, тот обрабатывается первым

Два файла ждут импорта. Нужно взять первый и оставить второй до следующего шага. Очередь хранит порядок поступления и отдаёт работу по одной. FIFO — сокращение от «первый пришёл, первый вышел».

Два задания и один обработчик
  1. enqueue: Импорт → Отчёт
  2. dequeue: Импорт переходит в $job
  3. В очереди остаётся Отчёт

Модель похожа на очередь к одному окну. В PHP это связанные узлы в памяти, без настоящих людей, ожидания по часам или автоматического исполнения.

new SplQueue() создаёт отдельную пустую очередь; $jobs хранит ссылку на этот объект. Знак -> выбирает его действие — метод. Скобки вызывают действие, аргументы внутри передают значения, а ; завершает команду. У enqueue("Импорт") строка «Импорт» становится значением параметра $value встроенного метода; он сохраняет её в этой очереди. Возврат void означает отсутствие полезного результата вызова. dequeue() возвращает саму строку: в $job = $jobs->dequeue(); она займёт место вызова справа от = и попадёт в $job. Следующий echo $job; выводит полученную работу. Подробно об объектах — в начале ООП.

Получить первое заданиеСамостоятельный пример
<?php
declare(strict_types=1);

$jobs = new SplQueue();
$jobs->enqueue('Импорт');
$jobs->enqueue('Отчёт');
$job = $jobs->dequeue();
echo 'Выполняем: ', $job, "\n";
echo 'Следующее: ', $jobs->bottom(), "\n";
Ожидаемый результат
Выполняем: Импорт
Следующее: Отчёт

После двух enqueue очередь содержит Импорт → Отчёт. dequeue удаляет Импорт и возвращает эту строку в присваивание $job. bottom читает оставшийся Отчёт без удаления. Ни один метод здесь сам не выполняет задание: полезное действие обозначено выводом.

Скачать самостоятельный пример с результатом и README

Для нескольких заданий повторяют один и тот же шаг. Условие while проверяется до очередного dequeue; после извлечения значение используют отдельно от контейнера.

Обработать очередь до концаСамостоятельный пример
<?php
declare(strict_types=1);

$jobs = new SplQueue();
$jobs->enqueue(['file' => 'orders.csv', 'rows' => 3]);
$jobs->enqueue(['file' => 'returns.csv', 'rows' => 1]);
while (!$jobs->isEmpty()) {
    $job = $jobs->dequeue();
    echo $job['file'], ': подготовлено строк ', $job['rows'], "\n";
}
echo 'Осталось заданий: ', $jobs->count(), "\n";
Ожидаемый результат
orders.csv: подготовлено строк 3
returns.csv: подготовлено строк 1
Осталось заданий: 0

Каждое задание теперь массив с именем и числом строк. ! превращает «пуста» в «не пуста»; while повторяет тело, пока это условие истинно. dequeue передаёт ровно один массив в $job и уменьшает очередь. После двух проходов условие ложно, выполняется последний echo. Файлы здесь описаны данными, их чтение не заявляется.

Скачать самостоятельный пример с результатом и README

Обойти связанные разделы без бесконечных повторовСамостоятельный пример
<?php
declare(strict_types=1);

$links = ['Главная' => ['Каталог', 'Контакты'], 'Каталог' => ['Главная', 'Чай'], 'Контакты' => [], 'Чай' => []];
$pending = new SplQueue();
$pending->enqueue('Главная');
$scheduled = ['Главная' => true];
while (!$pending->isEmpty()) {
    $page = $pending->dequeue();
    echo 'Раздел: ', $page, "\n";
    foreach ($links[$page] as $next) {
        if (!isset($scheduled[$next])) {
            $scheduled[$next] = true;
            $pending->enqueue($next);
        }
    }
}
Ожидаемый результат
Раздел: Главная
Раздел: Каталог
Раздел: Контакты
Раздел: Чай

Это конечный граф разделов, уже известный в памяти. foreach получает соседей текущей страницы. isset проверяет отметку; её ставят при постановке в очередь, поэтому две страницы не поставят один раздел дважды. Обратная ссылка Каталог → Главная не зацикливает обработку. Для загружаемого извне графа отдельно нужны пределы страниц, глубины и времени.

Скачать самостоятельный пример с результатом и README

SplQueue наследует SplDoublyLinkedList. enqueue — имя для push, dequeue — имя для shift. Обход фиксирован в FIFO; KEEP оставляет просмотренные элементы, DELETE удаляет их при продвижении итератора. Операции списка вроде unshift способны изменить ожидаемый порядок очереди.

МетодПолный разбор
SplQueue::dequeueSplQueue::dequeue
SplQueue::enqueueSplQueue::enqueue

Методы унаследованного списка разобраны ниже. Для последних изменений первым нужен стек, для срочности — приоритетная очередь.

SplStack: последняя сохранённая запись возвращается первой

Для отмены редактирования нужна последняя сохранённая цена, а не самая старая. Стек даёт такую дисциплину: push кладёт новое значение наверх, pop снимает верхнее.

История цены
  1. push 500, затем push 450
  2. Верх: 450; ниже: 500
  3. pop → цена 450; второй pop → цена 500

Стопка карточек объясняет порядок. PHP не угадывает, что означает «отмена»: вы сами присваиваете возвращённое число цене.

Отменить последнее изменение ценыСамостоятельный пример
<?php
declare(strict_types=1);

$history = new SplStack();
$price = 500;
$history->push($price);
$price = 450;
$history->push($price);
$price = 400;
$price = $history->pop();
echo 'После отмены: ', $price, "\n";
$price = $history->pop();
echo 'После второй отмены: ', $price, "\n";
Ожидаемый результат
После отмены: 450
После второй отмены: 500

Перед изменением сохраняется старая цена. В стек последовательно попали 500 и 450; pop возвращает последнюю — 450 — в присваивание $price. Второй pop возвращает 500. Стек содержит числа, а не команды и не резервную копию базы; отмену связанных изменений нужно проектировать отдельно.

Скачать самостоятельный пример с результатом и README

Посмотреть историю, затем отменить шагСамостоятельный пример
<?php
declare(strict_types=1);

$history = new SplStack();
$history->push('Создан черновик');
$history->push('Изменён заголовок');
foreach ($history as $step) {
    echo 'История: ', $step, "\n";
}
echo 'Отменяем: ', $history->pop(), "\n";
echo 'Остаётся: ', $history->top(), "\n";
Ожидаемый результат
История: Изменён заголовок
История: Создан черновик
Отменяем: Изменён заголовок
Остаётся: Создан черновик

SplStack фиксирует LIFO — «последний пришёл, первый вышел». foreach в режиме KEEP не уничтожает историю; затем pop действительно удаляет последнюю запись. top только читает оставшуюся. Надпись «Отменяем» показывает выбранную запись, а не автоматическое изменение документа.

Скачать самостоятельный пример с результатом и README

SplStack наследует весь SplDoublyLinkedList, но направление LIFO закреплено. Для DELETE нужно передавать LIFO | DELETE: один DELETE содержит FIFO-бит 0 и несовместим со стеком. Константы типизированы как int с PHP 8.4; значения LIFO=2, FIFO=0, DELETE=1, KEEP=0.

Для короткой локальной истории достаточно обычного массива и array_pop. Стек полезен, когда API должен выражать порядок получения; однако наследованные операции списка не запрещают произвольное изменение истории.

SplDoublyLinkedList: цепочка с доступом с двух концов

Маршрут меняется с обоих концов: добавили гараж перед складом, новую доставку после магазина. Двусвязный список хранит для каждого узла соседей слева и справа.

Маршрут
  1. Начало: Гараж
  2. Гараж ↔ Склад ↔ Магазин
  3. Конец: Магазин

Стрелки объясняют соседство. PHP не открывает сами указатели узлов: вы работаете методами и позициями. Индекс 1 не означает прямой доступ к ячейке обычного массива.

Составить порядок остановокСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Склад');
$route->push('Магазин');
$route->unshift('Гараж');
foreach ($route as $index => $stop) {
    echo $index, ': ', $stop, "\n";
}
Ожидаемый результат
0: Гараж
1: Склад
2: Магазин

push добавил Склад и Магазин в конец, unshift — Гараж в начало. foreach передаёт текущий номер в $index, строку в $stop; => связывает две переменные обхода. Это позиции в текущем списке, не постоянные ID адресов.

Скачать самостоятельный пример с результатом и README

Iterator обеспечивает foreach; Countable — count($route); ArrayAccess — запись $route[1]; Serializable — старый парный формат serialize()/unserialize(). Начальный режим FIFO | KEEP: от начала к концу, без удаления. Направление и удаление — независимые настройки.

ОперацияПоведение
push / pop / topДобавить / удалить и вернуть / прочитать конец
unshift / shift / bottomТо же для начала
add / offsetSetВставить новый узел / заменить существующий
next / prev / rewindПередвинуть текущую позицию обхода

Доступ к концам и один шаг по связи имеют стоимость O(1): она не растёт с длиной списка. Поиск узла по числовому индексу требует прохода, поэтому add по позиции не превращается в произвольную вставку O(1). Узлы и связи также занимают память; выбирать структуру нужно по операциям и измерению реальной задачи.

МетодПолный разбор
SplDoublyLinkedList::addSplDoublyLinkedList::add
SplDoublyLinkedList::bottomSplDoublyLinkedList::bottom
SplDoublyLinkedList::countSplDoublyLinkedList::count
SplDoublyLinkedList::currentSplDoublyLinkedList::current
SplDoublyLinkedList::getIteratorModeSplDoublyLinkedList::getIteratorMode
SplDoublyLinkedList::isEmptySplDoublyLinkedList::isEmpty
SplDoublyLinkedList::keySplDoublyLinkedList::key
SplDoublyLinkedList::nextSplDoublyLinkedList::next
SplDoublyLinkedList::offsetExistsSplDoublyLinkedList::offsetExists
SplDoublyLinkedList::offsetGetSplDoublyLinkedList::offsetGet
SplDoublyLinkedList::offsetSetSplDoublyLinkedList::offsetSet
SplDoublyLinkedList::offsetUnsetSplDoublyLinkedList::offsetUnset
SplDoublyLinkedList::popSplDoublyLinkedList::pop
SplDoublyLinkedList::prevSplDoublyLinkedList::prev
SplDoublyLinkedList::pushSplDoublyLinkedList::push
SplDoublyLinkedList::rewindSplDoublyLinkedList::rewind
SplDoublyLinkedList::serializeSplDoublyLinkedList::serialize
SplDoublyLinkedList::setIteratorModeSplDoublyLinkedList::setIteratorMode
SplDoublyLinkedList::shiftSplDoublyLinkedList::shift
SplDoublyLinkedList::topSplDoublyLinkedList::top
SplDoublyLinkedList::unserializeSplDoublyLinkedList::unserialize
SplDoublyLinkedList::unshiftSplDoublyLinkedList::unshift
SplDoublyLinkedList::validSplDoublyLinkedList::valid

SplHeap: наверху значение, выбранное правилом сравнения

Если каждый раз нужна работа с ближайшим сроком, порядок поступления уже не подходит. Куча поддерживает одну доступную вершину: после её извлечения выбирается следующая.

Куча сроков
  1. Вход: 30, 10, 20 минут
  2. Правило: меньшая минута важнее
  3. top → 10; extract → 10; новая вершина → 20

Это дерево отношений приоритета, а не полная сортированная таблица и не «куча памяти» процесса. Каждый родитель имеет не меньший приоритет, чем дети; соседние ветки не обязаны быть отсортированы.

SplHeap — абстрактная основа: напрямую new SplHeap() использовать нельзя. Для чисел готовые SplMinHeap и SplMaxHeap проще. Все они реализуют Iterator и Countable. Сначала посмотрим готовый вариант, затем зададим правило для записей.

Взять ближайшую минуту запускаСамостоятельный пример
<?php
declare(strict_types=1);

$times = new SplMinHeap();
$times->insert(30);
$times->insert(10);
$times->insert(20);
echo 'Ближайшая минута: ', $times->top(), "\n";
$minute = $times->extract();
echo 'Запланировано на минуту: ', $minute, "\n";
echo 'Следующая минута: ', $times->top(), "\n";
Ожидаемый результат
Ближайшая минута: 10
Запланировано на минуту: 10
Следующая минута: 20

insert передал три целых числа в кучу. SplMinHeap держит на вершине наименьшее — 10. top читает его без удаления. extract удаляет вершину и возвращает 10 в $minute; затем наверху 20. Числа — условные минуты от начала расписания, не текущие часы и не автоматический таймер.

Скачать самостоятельный пример с результатом и README

Запись задания — массив title/day. Чтобы встроенный алгоритм знал, какую запись поднять, ему передают метод сравнения через наследование. Положительный результат означает «первый аргумент важнее», отрицательный — «второй», ноль — одинаковый приоритет. <=> возвращает -1, 0 или 1.

Выбирать запись по срокуСамостоятельный пример
<?php
declare(strict_types=1);

class DeadlineHeap extends SplHeap {
    protected function compare(mixed $first, mixed $second): int {
        return $second['day'] <=> $first['day'];
    }
}
$tasks = new DeadlineHeap();
$tasks->insert(['title' => 'Отчёт', 'day' => 18]);
$tasks->insert(['title' => 'Счёт', 'day' => 15]);
while (!$tasks->isEmpty()) {
    $task = $tasks->extract();
    echo $task['day'], ': ', $task['title'], "\n";
}
Ожидаемый результат
15: Счёт
18: Отчёт

class объявляет новый класс, extends наследует механизм SplHeap. protected compare вызывается самой кучей при insert/extract. При сравнении записи day=15 с day=18 параметры $first/$second получают эти записи; 18 <=> 15 возвращает положительное число, значит первая запись поднимается выше. return передаёт знак встроенному алгоритму, а не печатает запись. Позже extract возвращает всю запись в $task. Для равных сроков порядок здесь не обещан.

Скачать самостоятельный пример с результатом и README

Вставка и извлечение выполняют проход по высоте дерева, обычно O(log n) сравнений; чтение вершины O(1). Время одного пользовательского compare тоже входит в стоимость. Для разовой сортировки небольшого массива часто проще sort/usort.

Просмотр без потери исходных значенийСамостоятельный пример
<?php
declare(strict_types=1);

$sizes = new SplMaxHeap();
foreach ([12, 40, 25] as $size) { $sizes->insert($size); }
$preview = clone $sizes;
foreach ($preview as $size) { echo 'Предпросмотр: ', $size, "\n"; }
echo 'Осталось в копии: ', $preview->count(), "\n";
echo 'В исходной куче: ', $sizes->count(), "\n";
echo 'Реально выбран: ', $sizes->extract(), "\n";
Ожидаемый результат
Предпросмотр: 40
Предпросмотр: 25
Предпросмотр: 12
Осталось в копии: 0
В исходной куче: 3
Реально выбран: 40

foreach кучи последовательно удаляет вершины. clone создаёт отдельный контейнер, поэтому обзор опустошает $preview, а не $sizes. Клонирование контейнера поверхностное: вложенные объекты остаются общими, поэтому это не снимок состояния всего графа объектов.

Скачать самостоятельный пример с результатом и README

МетодПолный разбор
SplHeap::compareSplHeap::compare
SplHeap::countSplHeap::count
SplHeap::currentSplHeap::current
SplHeap::extractSplHeap::extract
SplHeap::insertSplHeap::insert
SplHeap::isCorruptedSplHeap::isCorrupted
SplHeap::isEmptySplHeap::isEmpty
SplHeap::keySplHeap::key
SplHeap::nextSplHeap::next
SplHeap::recoverFromCorruptionSplHeap::recoverFromCorruption
SplHeap::rewindSplHeap::rewind
SplHeap::topSplHeap::top
SplHeap::validSplHeap::valid

SplMinHeap: меньшие значения выдаются первыми

Нужна ближайшая минута из заранее известных сроков. SplMinHeap наследует SplHeap и меняет сравнение так, чтобы минимум был наверху. Для однородных чисел собственный класс не нужен.

Время ожидания
  1. Добавлены 30, 10, 20
  2. Первым вернётся 10
  3. Затем 20, затем 30

Куча хранит числа; календарь, часовой пояс и фактическое ожидание выполняет другой код.

Взять ближайшую минуту запускаСамостоятельный пример
<?php
declare(strict_types=1);

$times = new SplMinHeap();
$times->insert(30);
$times->insert(10);
$times->insert(20);
echo 'Ближайшая минута: ', $times->top(), "\n";
$minute = $times->extract();
echo 'Запланировано на минуту: ', $minute, "\n";
echo 'Следующая минута: ', $times->top(), "\n";
Ожидаемый результат
Ближайшая минута: 10
Запланировано на минуту: 10
Следующая минута: 20

insert передал три целых числа в кучу. SplMinHeap держит на вершине наименьшее — 10. top читает его без удаления. extract удаляет вершину и возвращает 10 в $minute; затем наверху 20. Числа — условные минуты от начала расписания, не текущие часы и не автоматический таймер.

Скачать самостоятельный пример с результатом и README

Просмотр без потери исходных значенийСамостоятельный пример
<?php
declare(strict_types=1);

$sizes = new SplMaxHeap();
foreach ([12, 40, 25] as $size) { $sizes->insert($size); }
$preview = clone $sizes;
foreach ($preview as $size) { echo 'Предпросмотр: ', $size, "\n"; }
echo 'Осталось в копии: ', $preview->count(), "\n";
echo 'В исходной куче: ', $sizes->count(), "\n";
echo 'Реально выбран: ', $sizes->extract(), "\n";
Ожидаемый результат
Предпросмотр: 40
Предпросмотр: 25
Предпросмотр: 12
Осталось в копии: 0
В исходной куче: 3
Реально выбран: 40

foreach кучи последовательно удаляет вершины. clone создаёт отдельный контейнер, поэтому обзор опустошает $preview, а не $sizes. Клонирование контейнера поверхностное: вложенные объекты остаются общими, поэтому это не снимок состояния всего графа объектов.

Скачать самостоятельный пример с результатом и README

Унаследованные insert/extract/top/Iterator/Countable работают так же, но вершина минимальна. Смешанные типы сравниваются по общим правилам PHP; нормализуйте все сроки в один тип. Равные значения допускаются, но их относительный порядок не определён.

МетодПолный разбор
SplMinHeap::compareSplMinHeap::compare

SplMaxHeap: больший объём выдаётся первым

Чтобы каждый раз выбирать самый крупный остаток, нужна максимальная вершина. SplMaxHeap — готовый наследник SplHeap с обычным сравнением PHP.

Объёмы на складе
  1. Добавлены 12, 40, 25
  2. Первым вернётся 40
  3. После извлечения наверху 25

Это порядок чисел. Сопутствующие названия не появятся автоматически: храните записи с compare либо пары данные/приоритет.

Выбрать самый крупный остатокСамостоятельный пример
<?php
declare(strict_types=1);

$stock = new SplMaxHeap();
$stock->insert(12);
$stock->insert(40);
$stock->insert(25);
$amount = $stock->extract();
echo 'Первый объём: ', $amount, "\n";
echo 'Следующий объём: ', $stock->top(), "\n";
Ожидаемый результат
Первый объём: 40
Следующий объём: 25

SplMaxHeap выбирает наибольшее значение. extract возвращает 40, следующий top — 25. Мы храним только количества: если нужен ещё и артикул, используйте запись и собственное сравнение либо SplPriorityQueue с количеством как приоритетом.

Скачать самостоятельный пример с результатом и README

Просмотр без потери исходных значенийСамостоятельный пример
<?php
declare(strict_types=1);

$sizes = new SplMaxHeap();
foreach ([12, 40, 25] as $size) { $sizes->insert($size); }
$preview = clone $sizes;
foreach ($preview as $size) { echo 'Предпросмотр: ', $size, "\n"; }
echo 'Осталось в копии: ', $preview->count(), "\n";
echo 'В исходной куче: ', $sizes->count(), "\n";
echo 'Реально выбран: ', $sizes->extract(), "\n";
Ожидаемый результат
Предпросмотр: 40
Предпросмотр: 25
Предпросмотр: 12
Осталось в копии: 0
В исходной куче: 3
Реально выбран: 40

foreach кучи последовательно удаляет вершины. clone создаёт отдельный контейнер, поэтому обзор опустошает $preview, а не $sizes. Клонирование контейнера поверхностное: вложенные объекты остаются общими, поэтому это не снимок состояния всего графа объектов.

Скачать самостоятельный пример с результатом и README

Iterator и Countable унаследованы. Полный foreach уничтожает элементы; для просмотра копируйте контейнер. Не смешивайте цены-строки и целые числа без явного преобразования.

МетодПолный разбор
SplMaxHeap::compareSplMaxHeap::compare

SplPriorityQueue: данные отдельно, срочность отдельно

У задания есть текст и срочность. FIFO не пропустит пароль перед давно ожидающим отчётом. Приоритетная очередь поддерживает максимальный приоритет, а в ответ отдаёт полезное задание.

Две записи
  1. Отчёт: приоритет 10
  2. Сброс пароля: приоритет 50
  3. extract → «Сброс пароля»; следующим будет «Отчёт»

Срочность — наше бизнес-правило. Очередь не знает сроков доставки и не запускает обработчики. Механизм max-heap сравнивает только приоритеты, а не смысл названий.

Срочное письмо получить раньше отчётаСамостоятельный пример
<?php
declare(strict_types=1);

$jobs = new SplPriorityQueue();
$jobs->insert('Отчёт', 10);
$jobs->insert('Сброс пароля', 50);
echo 'Следующее: ', $jobs->top(), "\n";
$job = $jobs->extract();
echo 'Обработать: ', $job, "\n";
echo 'После него: ', $jobs->extract(), "\n";
Ожидаемый результат
Следующее: Сброс пароля
Обработать: Сброс пароля
После него: Отчёт

Первый аргумент insert — полезные данные, второй — приоритет. Большее число 50 важнее 10, поэтому «Сброс пароля» возвращается раньше. top не удаляет, extract удаляет. По умолчанию возвращаются данные; код лишь показывает выбранные задания и не отправляет письма.

Скачать самостоятельный пример с результатом и README

insert($value, $priority) принимает две разные части. Большее значение приоритета выбирается первым. top/current/extract по умолчанию возвращают данные; EXTR_PRIORITY возвращает только приоритет, EXTR_BOTH — массив data/priority. Константы int типизированы с PHP 8.4.

Получить вместе задание и его приоритетСамостоятельный пример
<?php
declare(strict_types=1);

$jobs = new SplPriorityQueue();
$jobs->insert('Сброс пароля', 50);
$saved = $jobs->getExtractFlags();
$jobs->setExtractFlags(SplPriorityQueue::EXTR_PRIORITY);
echo 'Приоритет: ', $jobs->top(), "\n";
$jobs->setExtractFlags(SplPriorityQueue::EXTR_BOTH);
$entry = $jobs->current();
echo $entry['data'], ': ', $entry['priority'], "\n";
$jobs->setExtractFlags($saved);
echo 'К исполнению: ', $jobs->extract(), "\n";
Ожидаемый результат
Приоритет: 50
Сброс пароля: 50
К исполнению: Сброс пароля

EXTR_PRIORITY меняет форму чтения на число; EXTR_BOTH возвращает массив с ключами data и priority. Это не меняет очередность. getExtractFlags сохранил прежнюю настройку EXTR_DATA, setExtractFlags восстановил её, поэтому extract снова вернул строку задания.

Скачать самостоятельный пример с результатом и README

Сохранить FIFO внутри одинаковой срочностиСамостоятельный пример
<?php
declare(strict_types=1);

class StableJobs extends SplPriorityQueue {
    public function compare(mixed $first, mixed $second): int {
        $urgency = $first['level'] <=> $second['level'];
        if ($urgency !== 0) { return $urgency; }
        return $second['sequence'] <=> $first['sequence'];
    }
}
$jobs = new StableJobs();
$jobs->insert('Отчёт A', ['level' => 10, 'sequence' => 1]);
$jobs->insert('Отчёт B', ['level' => 10, 'sequence' => 2]);
$jobs->insert('Пароль', ['level' => 50, 'sequence' => 3]);
while (!$jobs->isEmpty()) { echo $jobs->extract(), "\n"; }
Ожидаемый результат
Пароль
Отчёт A
Отчёт B

Второй аргумент insert теперь массив приоритета из двух полей. Встроенная куча вызывает compare с двумя такими массивами, не со строками задания. Сначала return отдаёт знак сравнения level. При одинаковом level меньший sequence получает больший приоритет через обратное сравнение. Возврат compare используется только алгоритмом; extract позже возвращает строку. Счётчик sequence должен быть уникальным и возрастающим в пределах этого планировщика.

Скачать самостоятельный пример с результатом и README

Сначала разобран простой вызов, затем наследник с compare. Такой метод должен всегда возвращать согласованный знак и не менять саму очередь. Для единственного разового списка сортировка массива может быть проще; при постоянных вставках и выборке вершины куча выражает нужные операции.

МетодПолный разбор
SplPriorityQueue::compareSplPriorityQueue::compare
SplPriorityQueue::countSplPriorityQueue::count
SplPriorityQueue::currentSplPriorityQueue::current
SplPriorityQueue::extractSplPriorityQueue::extract
SplPriorityQueue::getExtractFlagsSplPriorityQueue::getExtractFlags
SplPriorityQueue::insertSplPriorityQueue::insert
SplPriorityQueue::isCorruptedSplPriorityQueue::isCorrupted
SplPriorityQueue::isEmptySplPriorityQueue::isEmpty
SplPriorityQueue::keySplPriorityQueue::key
SplPriorityQueue::nextSplPriorityQueue::next
SplPriorityQueue::recoverFromCorruptionSplPriorityQueue::recoverFromCorruption
SplPriorityQueue::rewindSplPriorityQueue::rewind
SplPriorityQueue::setExtractFlagsSplPriorityQueue::setExtractFlags
SplPriorityQueue::topSplPriorityQueue::top
SplPriorityQueue::validSplPriorityQueue::valid

SplFixedArray: заранее известные места с числовыми индексами

Три датчика должны дать три показания, но второй ещё не ответил. Нужно сохранить его место, не смешивая отсутствие замера с нулевой температурой. Фиксированный массив начинает с заданного количества null-ячеек.

Три места
  1. Индексы: 0 | 1 | 2
  2. После записи: 18 | null | 21
  3. getSize → 3; значение [0] → 18

Пронумерованные ячейки объясняют диапазон. Это объект PHP с отдельным API; обычный array устроен как упорядоченная таблица ключей и не обязан иметь непрерывные числовые индексы.

new SplFixedArray(3) создаёт объект и передаёт конструктору размер. Размер — число мест, последняя допустимая позиция меньше него на один. Нельзя добавлять $array[] без номера: сначала setSize, затем запись в допустимый индекс.

Зарезервировать три места для показанийСамостоятельный пример
<?php
declare(strict_types=1);

$readings = new SplFixedArray(3);
$readings[0] = 18;
$readings[2] = 21;
echo 'Первое показание: ', $readings[0], "\n";
echo 'Мест: ', $readings->getSize(), "\n";
foreach ($readings as $index => $value) {
    echo $index, ': ', $value === null ? 'нет замера' : $value, "\n";
}
Ожидаемый результат
Первое показание: 18
Мест: 3
0: 18
1: нет замера
2: 21

Число 3 в конструкторе задаёт количество мест: индексы 0, 1, 2. Каждое сначала содержит null. Квадратные скобки выбирают место; запись меняет его значение. count/getSize считают места, включая незаполненные. foreach проходит все три; строгая проверка === null выбирает подпись отсутствующего измерения, сохраняя настоящий ноль.

Скачать самостоятельный пример с результатом и README

Увеличить сетку, затем явно отбросить хвостСамостоятельный пример
<?php
declare(strict_types=1);

$readings = SplFixedArray::fromArray([18, 19]);
$readings->setSize(4);
$readings[3] = 22;
echo 'До сокращения: ', json_encode($readings), "\n";
$readings->setSize(2);
$readings->setSize(4);
echo 'После расширения: ', json_encode($readings), "\n";
Ожидаемый результат
До сокращения: [18,19,null,22]
После расширения: [18,19,null,null]

fromArray создаёт новый контейнер из обычного массива. setSize(4) добавляет два null. Сокращение до 2 уничтожает значения за новой границей; повторное увеличение не возвращает 22. json_encode здесь только делает всю уже объяснённую структуру видимой: внутри скобок значения идут по индексам.

Скачать самостоятельный пример с результатом и README

Записать, очистить и проверить ячейкуСамостоятельный пример
<?php
declare(strict_types=1);

$readings = new SplFixedArray(3);
$readings->offsetSet(1, 0);
if ($readings->offsetExists(1)) {
    echo 'Есть показание: ', $readings->offsetGet(1), "\n";
}
$readings->offsetUnset(1);
if (!$readings->offsetExists(1)) { echo "Показание очищено\n"; }
echo 'Мест после очистки: ', $readings->count(), "\n";
echo 'В ячейке: ', $readings[1] === null ? 'null' : 'другое', "\n";
Ожидаемый результат
Есть показание: 0
Показание очищено
Мест после очистки: 3
В ячейке: null

offsetSet/offsetGet соответствуют записи/чтению квадратными скобками. offsetUnset, как unset($readings[1]), очищает значение до null, но не сжимает контейнер. offsetExists имеет isset-смысл: для null false, для 0 true. Проверку допустимого номера выполняют отдельно: 0 <= индекс < getSize().

Скачать самостоятельный пример с результатом и README

ArrayAccess даёт квадратные скобки, Countable — count. С PHP 8 вместо Iterator реализован IteratorAggregate, с 8.1 — JsonSerializable, с 8.2 есть новые hooks сериализации. Пять старых методов указателя сохранены в справочнике как исторические страницы и сопровождаются современным переходом.

Получить отдельный указатель вместо старых методовСамостоятельный пример
<?php
declare(strict_types=1);

$readings = SplFixedArray::fromArray([18, 22]);
$iterator = $readings->getIterator();
$iterator->rewind();
while ($iterator->valid()) {
    echo 'Замер ', $iterator->key(), ': ', $iterator->current(), "\n";
    $iterator->next();
}
$iterator->rewind();
echo 'Снова первый: ', $iterator->current(), "\n";
Ожидаемый результат
Замер 0: 18
Замер 1: 22
Снова первый: 18

С PHP 8 SplFixedArray реализует IteratorAggregate: контейнер выдаёт отдельный Iterator. rewind/current/key/next/valid вызываются у $iterator, не у $readings. getIterator возвращает объект в переменную; затем цикл читает индекс и значение, продвигается, останавливается. Значения не удаляются.

Скачать самостоятельный пример с результатом и README

SPL описывает возможность экономить память благодаря непрерывным местам и отсутствию произвольных ключей. Это не универсальное обещание выигрыша: PHP-массивы тоже имеют оптимизации, а множество маленьких объектов добавляет накладные расходы. Сравнивайте одинаковые данные и реальные операции; цифры старых микротестов не являются свойством класса.

МетодПолный разбор
SplFixedArray::__constructSplFixedArray::__construct
SplFixedArray::countSplFixedArray::count
SplFixedArray::currentSplFixedArray::current
SplFixedArray::fromArraySplFixedArray::fromArray
SplFixedArray::getIteratorSplFixedArray::getIterator
SplFixedArray::getSizeSplFixedArray::getSize
SplFixedArray::jsonSerializeSplFixedArray::jsonSerialize
SplFixedArray::keySplFixedArray::key
SplFixedArray::nextSplFixedArray::next
SplFixedArray::offsetExistsSplFixedArray::offsetExists
SplFixedArray::offsetGetSplFixedArray::offsetGet
SplFixedArray::offsetSetSplFixedArray::offsetSet
SplFixedArray::offsetUnsetSplFixedArray::offsetUnset
SplFixedArray::rewindSplFixedArray::rewind
SplFixedArray::__serializeSplFixedArray::__serialize
SplFixedArray::setSizeSplFixedArray::setSize
SplFixedArray::toArraySplFixedArray::toArray
SplFixedArray::__unserializeSplFixedArray::__unserialize
SplFixedArray::validSplFixedArray::valid
SplFixedArray::__wakeupSplFixedArray::__wakeup

ArrayObject: когда массиву нужен объектный интерфейс

Задача: несколько методов проекта должны передавать и изменять один набор настроек через квадратные скобки, count() и foreach, а иногда подставлять собственный итератор. ArrayObject оборачивает PHP-массив в объект, реализующий ArrayAccess, Countable и IteratorAggregate. Обычный массив остаётся правильным и более простым выбором, если методы объекта не нужны.

Один объект — одно хранилище записей
  1. Исходный array передан в new ArrayObject
  2. Объект хранит свою таблицу key → value
  3. [] вызывает offsetGet/offsetSet
  4. foreach получает отдельный Iterator
  5. getArrayCopy экспортирует неглубокую копию

Модель «контейнер» не означает специального непрерывного массива в памяти. Внутри ArrayObject обычно остаётся семантика PHP-массива: строковые/целые ключи, порядок вставки и значения любых типов.

Объект настроек: чтение, изменение и исходный массивСамостоятельный пример
<?php
$input = ['currency' => 'RUB', 'pageSize' => 20];
$settings = new ArrayObject($input);

$settings['pageSize'] = 50;
echo 'В объекте: ', $settings['pageSize'], "\n";
echo 'В исходном массиве: ', $input['pageSize'], "\n";
echo 'Записей: ', $settings->count(), "\n";
Ожидаемый результат
В объекте: 50
В исходном массиве: 20
Записей: 2

new ArrayObject($input) создаёт объект-обёртку с собственным хранилищем. Квадратные скобки вызывают методы ArrayAccess: чтение соответствует offsetGet, присваивание — offsetSet. Изменение обёртки не переписывает переменную $input. count() считает записи текущего хранилища.

Скачать самостоятельный пример с результатом и README

Снимок массива: скаляры независимы, вложенный объект общийСамостоятельный пример
<?php
$state = (object) ['status' => 'new'];
$order = new ArrayObject(['quantity' => 2, 'state' => $state]);
$copy = $order->getArrayCopy();

$copy['quantity'] = 5;
$copy['state']->status = 'checked';

echo 'Количество в объекте: ', $order['quantity'], "\n";
echo 'Количество в копии: ', $copy['quantity'], "\n";
echo 'Статус в объекте: ', $order['state']->status, "\n";
Ожидаемый результат
Количество в объекте: 2
Количество в копии: 5
Статус в объекте: checked

getArrayCopy возвращает отдельный PHP-массив. Скаляр quantity меняется только в копии. Копирование неглубокое: обе структуры всё ещё ссылаются на тот же вложенный объект $state, поэтому его свойство изменилось в обеих. Для независимого снимка вложенные объекты надо копировать по выбранным правилам домена.

Скачать самостоятельный пример с результатом и README

ВозможностьКогда выбирать
Обычный arrayЛокальный набор данных без отдельного поведения.
ArrayObjectНужен объект, []/foreach/count и настраиваемый ArrayIterator вокруг одного набора.
DTO/свой классНужны известные поля, типы, инварианты и методы предметной области.
SplFixedArrayНужны позиции 0…n−1 фиксированного размера, без строковых ключей.
Доступ к записям как к свойствам — явный режимСамостоятельный пример
<?php
$profile = new ArrayObject(
    ['name' => 'Анна'],
    ArrayObject::ARRAY_AS_PROPS
);

echo 'Флаг: ', $profile->getFlags(), "\n";
echo 'Имя: ', $profile->name, "\n";
$profile->city = 'Казань';
echo 'Через скобки: ', $profile['city'], "\n";

$profile->setFlags(0);
echo 'Флаг после возврата: ', $profile->getFlags(), "\n";
Ожидаемый результат
Флаг: 2
Имя: Анна
Через скобки: Казань
Флаг после возврата: 0

ARRAY_AS_PROPS равен 2 и перенаправляет $profile->name к записи name. Присваивание свойства добавляет запись city, которую видно и через скобки. setFlags(0) отключает этот режим. Такой синтаксис удобен только при контролируемых ключах: запись с именем метода или настоящего свойства может сделать код двусмысленным.

Скачать самостоятельный пример с результатом и README

Подставить итератор, который форматирует только выводСамостоятельный пример
<?php
class UpperTitleIterator extends ArrayIterator {
    public function current(): mixed {
        return strtoupper((string) parent::current());
    }
}

$titles = new ArrayObject(['draft' => 'php guide']);
echo 'Итератор по умолчанию: ', $titles->getIteratorClass(), "\n";
$titles->setIteratorClass(UpperTitleIterator::class);
echo 'Выбранный итератор: ', $titles->getIteratorClass(), "\n";

$iterator = $titles->getIterator();
echo 'Класс экземпляра: ', $iterator::class, "\n";
echo 'При обходе: ', $iterator->current(), "\n";
echo 'В хранилище: ', $titles['draft'], "\n";
Ожидаемый результат
Итератор по умолчанию: ArrayIterator
Выбранный итератор: UpperTitleIterator
Класс экземпляра: UpperTitleIterator
При обходе: PHP GUIDE
В хранилище: php guide

setIteratorClass сохраняет имя подкласса ArrayIterator. getIterator создаёт новый экземпляр этого класса. Переопределённый current форматирует отдаваемое значение, но не меняет хранилище: квадратные скобки по-прежнему возвращают исходную строку.

Скачать самостоятельный пример с результатом и README

МетодПолный разбор
ArrayObject::appendArrayObject::append
ArrayObject::asortArrayObject::asort
ArrayObject::__constructArrayObject::__construct
ArrayObject::countArrayObject::count
ArrayObject::exchangeArrayArrayObject::exchangeArray
ArrayObject::getArrayCopyArrayObject::getArrayCopy
ArrayObject::getFlagsArrayObject::getFlags
ArrayObject::getIteratorArrayObject::getIterator
ArrayObject::getIteratorClassArrayObject::getIteratorClass
ArrayObject::ksortArrayObject::ksort
ArrayObject::natcasesortArrayObject::natcasesort
ArrayObject::natsortArrayObject::natsort
ArrayObject::offsetExistsArrayObject::offsetExists
ArrayObject::offsetGetArrayObject::offsetGet
ArrayObject::offsetSetArrayObject::offsetSet
ArrayObject::offsetUnsetArrayObject::offsetUnset
ArrayObject::serializeArrayObject::serialize
ArrayObject::setFlagsArrayObject::setFlags
ArrayObject::setIteratorClassArrayObject::setIteratorClass
ArrayObject::uasortArrayObject::uasort
ArrayObject::uksortArrayObject::uksort
ArrayObject::unserializeArrayObject::unserialize

SplObjectStorage: объект как ключ, данные как info

Задача: во время одного процесса отметить, какие конкретные объекты уже обработаны, и прикрепить к каждому служебное состояние, не меняя класс этих объектов. В обычном PHP-массиве object нельзя напрямую использовать как ключ. SplObjectStorage реализует карту «идентичность объекта → info» и может служить множеством объектов, если info не требуется.

Три независимые части записи
  1. object-key: конкретный экземпляр Document
  2. hash: техническая идентичность внутри storage
  3. info: статус, счётчик или другие метаданные
  4. current() возвращает object; getInfo() возвращает info

Сходство с гардеробной биркой помогает только различить ключ и данные. getHash не является постоянным ID, storage не сохраняет объект в базу и не синхронизирует процессы.

Связать состояние обработки с конкретными объектамиСамостоятельный пример
<?php
class Document {
    public function __construct(public string $number) {}
}

$first = new Document('A-17');
$second = new Document('A-17');
$states = new SplObjectStorage();
$states[$first] = 'проверен';
$states[$second] = 'ожидает';

echo 'Объектов: ', $states->count(), "\n";
echo 'Первый: ', $states[$first], "\n";
echo 'Второй: ', $states[$second], "\n";
Ожидаемый результат
Объектов: 2
Первый: проверен
Второй: ожидает

Одинаковое поле number не делает два экземпляра одним ключом. SplObjectStorage сопоставляет info конкретной идентичности объекта. Запись $states[$first] = ... вызывает offsetSet; чтение — offsetGet. Это удобно для временной метаинформации, которую не надо добавлять в сам Document.

Скачать самостоятельный пример с результатом и README

Обновить массив метаданных через read–modify–writeСамостоятельный пример
<?php
$job = (object) ['id' => 42];
$states = new SplObjectStorage();
$states[$job] = ['attempt' => 1, 'status' => 'queued'];

$info = $states[$job];
$info['attempt']++;
$info['status'] = 'sent';
$states[$job] = $info;

echo 'Попытка: ', $states[$job]['attempt'], "\n";
echo 'Статус: ', $states[$job]['status'], "\n";
Ожидаемый результат
Попытка: 2
Статус: sent

offsetGet возвращает metadata по значению. Поэтому массив сначала читается в $info, изменяется и целиком записывается обратно. Выражение $states[$job]["attempt"]++ пытается косвенно менять временный результат и не является надёжным обновлением хранилища.

Скачать самостоятельный пример с результатом и README

Пройти объекты и их метаданные вручнуюСамостоятельный пример
<?php
class Task {
    public function __construct(public string $name) {}
}
$build = new Task('Сборка');
$test = new Task('Тесты');
$states = new SplObjectStorage();
$states[$build] = 'done';
$states[$test] = 'waiting';

$states->rewind();
while ($states->valid()) {
    $position = $states->key();
    $task = $states->current();
    $info = $states->getInfo();
    echo $position, ': ', $task->name, ' — ', $info, "\n";
    $states->next();
}
Ожидаемый результат
0: Сборка — done
1: Тесты — waiting

rewind ставит итератор на первую запись. valid разрешает current/getInfo/key. current возвращает объект-ключ, getInfo — связанную метаинформацию, key — позицию обхода 0,1… . next переводит к следующей записи. Позиция не является ID объекта.

Скачать самостоятельный пример с результатом и README

ЗадачаПодход
Временный статус конкретного экземпляраSplObjectStorage.
Ключ — строковый ID из базы/APIОбычный array/предметная map по ID.
Не удерживать объект в памятиWeakMap, если подходит его жизненный цикл.
Сохранить связь между запросамиБаза/кеш с явным постоянным ID, а не object hash.
Увидеть, что хранилище удерживает объект живымСамостоятельный пример
<?php
$storage = new SplObjectStorage();
$object = (object) ['id' => 5];
$weak = WeakReference::create($object);
$storage[$object] = 'held';
unset($object);
gc_collect_cycles();
echo 'Пока в storage: ', $weak->get() !== null ? 'жив' : 'удалён', "\n";

$storage->rewind();
$held = $storage->current();
$storage->offsetUnset($held);
unset($held);
gc_collect_cycles();
echo 'После удаления: ', $weak->get() !== null ? 'жив' : 'удалён', "\n";
Ожидаемый результат
Пока в storage: жив
После удаления: удалён

SplObjectStorage хранит сильную ссылку на object-key, поэтому unset внешней переменной не уничтожает объект. После offsetUnset и удаления временной $held сильных ссылок не остаётся, WeakReference возвращает null. Если таблица не должна продлевать жизнь объектов, рассмотрите WeakMap.

Скачать самостоятельный пример с результатом и README

МетодПолный разбор
SplObjectStorage::addAllSplObjectStorage::addAll
SplObjectStorage::attachSplObjectStorage::attach
SplObjectStorage::containsSplObjectStorage::contains
SplObjectStorage::countSplObjectStorage::count
SplObjectStorage::currentSplObjectStorage::current
SplObjectStorage::detachSplObjectStorage::detach
SplObjectStorage::getHashSplObjectStorage::getHash
SplObjectStorage::getInfoSplObjectStorage::getInfo
SplObjectStorage::keySplObjectStorage::key
SplObjectStorage::nextSplObjectStorage::next
SplObjectStorage::offsetExistsSplObjectStorage::offsetExists
SplObjectStorage::offsetGetSplObjectStorage::offsetGet
SplObjectStorage::offsetSetSplObjectStorage::offsetSet
SplObjectStorage::offsetUnsetSplObjectStorage::offsetUnset
SplObjectStorage::removeAllSplObjectStorage::removeAll
SplObjectStorage::removeAllExceptSplObjectStorage::removeAllExcept
SplObjectStorage::rewindSplObjectStorage::rewind
SplObjectStorage::seekSplObjectStorage::seek
SplObjectStorage::serializeSplObjectStorage::serialize
SplObjectStorage::setInfoSplObjectStorage::setInfo
SplObjectStorage::unserializeSplObjectStorage::unserialize
SplObjectStorage::validSplObjectStorage::valid

Итераторы SPL: выбрать маршрут по задаче

Обычный foreach уже умеет читать массивы и объекты Traversable. Классы SPL нужны, когда поверх существующего источника требуется явно выразить ещё одну операцию: ограничить окно, объединить потоки, фильтровать лениво, обойти дерево или выбрать форму файловой записи. Начинайте с задачи и самого простого результата; затем открывайте точный метод.

ЗадачаПодходящие классыЧто проверить до выбора
Объединить несколько готовых источниковAppendIterator, MultipleIteratorИсточники идут подряд или синхронно по позициям? Что делать при разной длине?
Получить окно, повторение или продолжить с текущего курсораLimitIterator, InfiniteIterator, NoRewindIteratorГде находится явная конечная граница? Можно ли перематывать исходный поток?
Адаптировать Traversable или управлять массивом как объектомIteratorIterator, ArrayIterator, EmptyIteratorНужен новый контейнер, декоратор того же курсора или корректный пустой источник?
Фильтровать либо видеть соседний элемент/накопленный кешCallbackFilterIterator, FilterIterator, RegexIterator, CachingIteratorПредикат работает с типизированными данными или со строковой формой? Сколько памяти может занять кеш?
Прочитать одну папку или имена по маскеDirectoryIterator, FilesystemIterator, GlobIteratorНужна ли рекурсия? Какими должны быть current/key? Не перепутаны ли . и .. с dotfiles?
Обойти вложенный массив или дерево каталоговRecursiveArrayIterator, RecursiveDirectoryIterator, RecursiveIteratorIteratorЧто является контейнером, что листом, каков порядок и предел глубины?
Фильтровать, кешировать или нарисовать деревоParentIterator, RecursiveFilterIterator, RecursiveCallbackFilterIterator, RecursiveRegexIterator, RecursiveCachingIterator, RecursiveTreeIteratorНужно сохранить путь к подходящему листу? Представление дерева отделено от исходных данных?

Каждый класс ниже начинается с видимой задачи и двух результатов. После обзора доступна таблица всех методов; каждая карточка сохраняет полный официальный контракт и добавляет два разных практических применения.

AppendIterator: несколько источников как один поток

Заказы сайта и магазина уже представлены отдельными итераторами. Их нужно обработать подряд и видеть источник каждой записи, не копируя всё в общий массив.

Что происходит во время обхода
  1. append сохраняет ссылку на каждый Iterator
  2. current/key приходят из активного источника
  3. после его конца курсор переходит к следующему

Эта схема показывает значения и переходы именно приведённого примера. Внутри PHP объект хранит служебное состояние, а не нарисованные коробки или стрелки.

Два отдела уже отдали по Iterator. Нужно обработать их подряд, но не создавать третий массив со всеми заказами.

Объединить заказы сайта и магазинаСамостоятельный пример
<?php
declare(strict_types=1);

$web = new ArrayIterator(['web-42', 'web-43']);
$shop = new ArrayIterator(['shop-7']);
$orders = new AppendIterator();
$orders->append($web);
$orders->append($shop);
foreach ($orders as $key => $order) {
    echo $orders->getIteratorIndex(), '|', $key, '|', $order, "\n";
}
echo 'Источников: ', $orders->getArrayIterator()->count(), "\n";
Ожидаемый результат
0|0|web-42
0|1|web-43
1|0|shop-7
Источников: 2

append() сохранил оба объекта-источника. Во время foreach getIteratorIndex() показывает, откуда пришла строка; key() остаётся ключом конкретного источника. getArrayIterator() здесь считает подключённые источники, а не заказы.

Скачать самостоятельный пример с fixtures, результатом и README

Для диагностики нужно увидеть не только значение, но и переход курсора между источниками.

Пройти общий поток вручную и вернуться к началуСамостоятельный пример
<?php
declare(strict_types=1);

$all = new AppendIterator();
$all->append(new ArrayIterator(['A-1']));
$all->append(new ArrayIterator(['B-1', 'B-2']));
$all->rewind();
while ($all->valid()) {
    echo $all->getIteratorIndex(), ':', $all->key(), '=', $all->current(), "\n";
    $all->next();
}
$all->rewind();
echo 'Снова первый: ', $all->current(), "\n";
Ожидаемый результат
0:0=A-1
1:0=B-1
1:1=B-2
Снова первый: A-1

rewind() поставил курсор в начало первого непустого источника. Цикл проверял valid(), читал current()/key(), затем next() переходил дальше; после конца повторный rewind() вернул первый элемент, потому что оба ArrayIterator повторяемы.

Скачать самостоятельный пример с fixtures, результатом и README

Полный справочник методов этого класса:

МетодЗачем открыть карточку
AppendIterator::appendдобавить ещё один источник в конец общего обхода
AppendIterator::__constructсоздать и настроить объект для дальнейшего обхода
AppendIterator::currentполучить текущее значение без продвижения курсора
AppendIterator::getArrayIteratorполучить объект, содержащий подключённые внутренние итераторы
AppendIterator::getIteratorIndexузнать номер внутреннего источника, который сейчас отдаёт значение
AppendIterator::keyполучить ключ или позицию текущего элемента
AppendIterator::nextперевести курсор к следующему элементу
AppendIterator::rewindпопытаться установить курсор на первый элемент
AppendIterator::validпроверить, указывает ли курсор на существующий элемент

ArrayIterator: массив с объектным курсором и операциями

Каталог уже загружен как массив, но компоненту нужны seek, ArrayAccess, сортировка и общий Iterator-протокол.

Что происходит во время обхода
  1. new получает исходные элементы и флаги
  2. rewind/seek выбирают позицию; current/key читают её
  3. offset/sort операции меняют состояние объекта

Эта схема показывает значения и переходы именно приведённого примера. Внутри PHP объект хранит служебное состояние, а не нарисованные коробки или стрелки.

Интерфейс хранит текущую позицию списка, а ключи товаров остаются строковыми артикулами.

Перейти ко второму товару каталогаСамостоятельный пример
<?php
declare(strict_types=1);

$catalog = new ArrayIterator([
    'sku-10' => 'Кисть',
    'sku-20' => 'Лак',
    'sku-30' => 'Валик',
]);
$catalog->seek(1);
echo $catalog->key(), ': ', $catalog->current(), "\n";
$catalog->next();
echo $catalog->key(), ': ', $catalog->current(), "\n";
Ожидаемый результат
sku-20: Лак
sku-30: Валик

seek(1) выбрал вторую позицию порядка обхода, хотя её ключ — sku-20. current() вернул название, key() — артикул, next() передвинул курсор на третью позицию.

Скачать самостоятельный пример с fixtures, результатом и README

Остатки уже находятся в ArrayIterator. Нужно добавить именованный товар, добавить значение с автоматическим ключом и удалить старый ключ.

Обновить остатки и получить обычный массивСамостоятельный пример
<?php
declare(strict_types=1);

$stock = new ArrayIterator(['brush' => 2]);
$stock->offsetSet('paint', 3);
$stock->append(7);
echo 'brush exists: ', $stock->offsetExists('brush') ? 'yes' : 'no', "\n";
echo 'paint: ', $stock->offsetGet('paint'), "\n";
$stock->offsetUnset('brush');
echo 'count: ', $stock->count(), "\n";
echo json_encode($stock->getArrayCopy(), JSON_UNESCAPED_UNICODE), "\n";
Ожидаемый результат
brush exists: yes
paint: 3
count: 2
{"paint":3,"0":7}

offsetSet("paint", 3) создал именованный элемент, append(7) выбрал следующий целочисленный ключ 0. После offsetUnset("brush") count() равен двум, а getArrayCopy() вернул независимое обычное представление данных.

Скачать самостоятельный пример с fixtures, результатом и README

Таблица содержит собственные ключи. Перед сортировкой нужно решить: меняется порядок по цене или по артикулу.

Сравнить сортировку по значениям и по ключамСамостоятельный пример
<?php
declare(strict_types=1);

$byValue = new ArrayIterator(['b' => 10, 'a' => 20]);
$byValue->asort();
echo 'asort: ', json_encode($byValue->getArrayCopy()), "\n";
$byKey = new ArrayIterator(['b' => 10, 'a' => 20]);
$byKey->ksort();
echo 'ksort: ', json_encode($byKey->getArrayCopy()), "\n";
Ожидаемый результат
asort: {"b":10,"a":20}
ksort: {"a":20,"b":10}

asort() сравнил значения 10 и 20 и сохранил ключи. ksort() сравнил ключи a и b. Обе операции изменили порядок самого объекта.

Скачать самостоятельный пример с fixtures, результатом и README

Полный справочник методов этого класса:

МетодЗачем открыть карточку
ArrayIterator::appendдобавить ещё один источник в конец общего обхода
ArrayIterator::asortотсортировать значения, сохранив их ключи
ArrayIterator::__constructсоздать и настроить объект для дальнейшего обхода
ArrayIterator::countполучить число элементов, которое определяет этот класс
ArrayIterator::currentполучить текущее значение без продвижения курсора
ArrayIterator::getArrayCopyполучить обычный массив с текущими данными контейнера
ArrayIterator::getFlagsпрочитать действующую битовую маску режима объекта
ArrayIterator::keyполучить ключ или позицию текущего элемента
ArrayIterator::ksortотсортировать элементы по ключам
ArrayIterator::natcasesortотсортировать значения естественно без учёта регистра
ArrayIterator::natsortотсортировать значения естественно с учётом регистра
ArrayIterator::nextперевести курсор к следующему элементу
ArrayIterator::offsetExistsпроверить наличие элемента по ключу без чтения несуществующего значения
ArrayIterator::offsetGetпрочитать элемент по ключу через ArrayAccess
ArrayIterator::offsetSetзаписать или добавить элемент через ArrayAccess
ArrayIterator::offsetUnsetудалить элемент по ключу через ArrayAccess
ArrayIterator::rewindпопытаться установить курсор на первый элемент
ArrayIterator::seekперейти к заданной позиции обхода
ArrayIterator::serializeполучить сериализованное представление состояния
ArrayIterator::setFlagsзаменить действующую битовую маску режима
ArrayIterator::uasortотсортировать значения пользовательским сравнением, сохранив ключи
ArrayIterator::uksortотсортировать ключи пользовательским сравнением
ArrayIterator::unserializeвосстановить состояние из совместимой сериализованной строки
ArrayIterator::validпроверить, указывает ли курсор на существующий элемент

EmptyIterator: честный пустой источник

Функция должна вернуть Iterator независимо от того, есть строки или нет. Пустой объект избавляет потребителя от отдельного типа null.

Что происходит во время обхода
  1. valid всегда false
  2. foreach сразу завершает обход
  3. current/key запрещены и не выдумывают значение

Эта схема показывает значения и переходы именно приведённого примера. Внутри PHP объект хранит служебное состояние, а не нарисованные коробки или стрелки.

Общий отчёт ожидает Iterator даже тогда, когда фильтр заранее установил отсутствие строк.

Безопасно пройти пустой источникСамостоятельный пример
<?php
declare(strict_types=1);

$rows = new EmptyIterator();
$rows->rewind();
echo 'valid: ', $rows->valid() ? 'yes' : 'no', "\n";
$rows->next();
echo 'after next: ', $rows->valid() ? 'yes' : 'no', "\n";
foreach ($rows as $row) { echo 'unreachable', "\n"; }
echo "Обход завершён без строк\n";
Ожидаемый результат
valid: no
after next: no
Обход завершён без строк

rewind() и next() ничего не сделали, valid() всегда вернул false, поэтому foreach не вызвал тело. Это корректная пустота, а не ошибка чтения.

Скачать самостоятельный пример с fixtures, результатом и README

Пустой Iterator специально запрещает выдавать выдуманное текущее значение или ключ.

Не читать current и key без validСамостоятельный пример
<?php
declare(strict_types=1);

$rows = new EmptyIterator();
foreach (['current', 'key'] as $method) {
    try {
        $rows->$method();
    } catch (Exception $error) {
        echo $method, ': ', $error::class, "\n";
    }
}
echo 'valid: ', $rows->valid() ? 'yes' : 'no', "\n";
Ожидаемый результат
current: BadMethodCallException
key: BadMethodCallException
valid: no

current() и key() завершились BadMethodCallException, которое пример перехватил. valid() остаётся безопасной проверкой и возвращает false. Точный класс подтверждается запуском текущего runtime.

Скачать самостоятельный пример с fixtures, результатом и README

Полный справочник методов этого класса:

МетодЗачем открыть карточку
EmptyIterator::currentполучить текущее значение без продвижения курсора
EmptyIterator::keyполучить ключ или позицию текущего элемента
EmptyIterator::nextперевести курсор к следующему элементу
EmptyIterator::rewindпопытаться установить курсор на первый элемент
EmptyIterator::validпроверить, указывает ли курсор на существующий элемент

InfiniteIterator: повторяем цикл только под внешним пределом

Конечный шаблон смен или задержек нужно повторить заранее известное число раз.

Что происходит во время обхода
  1. внутренний Iterator доходит до конца
  2. InfiniteIterator перематывает его
  3. LimitIterator останавливает общий поток

Эта схема показывает значения и переходы именно приведённого примера. Внутри PHP объект хранит служебное состояние, а не нарисованные коробки или стрелки.

Конечный список дежурных нужно повторять, но расписание содержит ровно пять смен.

Назначить пять смен двум дежурнымСамостоятельный пример
<?php
declare(strict_types=1);

$rotation = new InfiniteIterator(new ArrayIterator(['Анна', 'Борис']));
$fiveShifts = new LimitIterator($rotation, 0, 5);
$shift = 1;
foreach ($fiveShifts as $person) {
    echo $shift, ': ', $person, "\n";
    $shift++;
}
Ожидаемый результат
1: Анна
2: Борис
3: Анна
4: Борис
5: Анна

InfiniteIterator после Бориса снова начал внутренний ArrayIterator с Анны. Его исходные ключи тоже повторяются, поэтому отдельный счётчик $shift нумерует итоговое расписание. Внешний LimitIterator остановил обход после пяти значений; без него foreach не завершился бы.

Скачать самостоятельный пример с fixtures, результатом и README

Учебный план повтора использует цикл 1–2–5 секунд, но число попыток обязано быть конечным.

Повторить ограниченную схему задержекСамостоятельный пример
<?php
declare(strict_types=1);

$delays = new InfiniteIterator(new ArrayIterator([1, 2, 5]));
$attempts = new LimitIterator($delays, 0, 7);
$attempt = 1;
foreach ($attempts as $seconds) {
    echo 'Попытка ', $attempt, ': пауза ', $seconds, " сек.\n";
    $attempt++;
}
Ожидаемый результат
Попытка 1: пауза 1 сек.
Попытка 2: пауза 2 сек.
Попытка 3: пауза 5 сек.
Попытка 4: пауза 1 сек.
Попытка 5: пауза 2 сек.
Попытка 6: пауза 5 сек.
Попытка 7: пауза 1 сек.

next() InfiniteIterator сам перемотал внутренний источник после третьего значения. Ключи внутреннего массива повторяются, поэтому номер попытки хранится отдельно. Пример только печатает план: он не вызывает sleep() и не отправляет запросы. Семь попыток ограничены явно.

Скачать самостоятельный пример с fixtures, результатом и README

Полный справочник методов этого класса:

МетодЗачем открыть карточку
InfiniteIterator::__constructсоздать и настроить объект для дальнейшего обхода
InfiniteIterator::nextперевести курсор к следующему элементу

IteratorIterator: адаптер Traversable к Iterator

DatePeriod можно читать foreach, но следующий декоратор принимает именно Iterator. Обёртка добавляет нужный интерфейс без копирования дат.

Что происходит во время обхода
  1. конструктор принимает Traversable
  2. внешний протокол делегируется Iterator-слою
  3. для DatePeriod PHP создаёт InternalIterator, который виден через getInnerIterator

Эта схема показывает значения и переходы именно приведённого примера. Внутри PHP объект хранит служебное состояние, а не нарисованные коробки или стрелки.

DatePeriod реализует Traversable, но не обычный Iterator. Декоратор нужен, когда следующий компонент требует именно Iterator.

Обойти фиксированный DatePeriod как IteratorСамостоятельный пример
<?php
declare(strict_types=1);

$period = new DatePeriod(
    new DateTimeImmutable('2026-10-12'),
    new DateInterval('P1D'),
    new DateTimeImmutable('2026-10-15')
);
$days = new IteratorIterator($period);
foreach ($days as $day) {
    echo $day->format('Y-m-d'), "\n";
}
echo 'inner: ', $days->getInnerIterator()::class, "\n";
Ожидаемый результат
2026-10-12
2026-10-13
2026-10-14
inner: InternalIterator

IteratorIterator передал foreach три даты до исключительной конечной даты. Поскольку DatePeriod — Traversable, но не Iterator, PHP показывает внутренний адаптер InternalIterator; getInnerIterator() возвращает именно активный Iterator-слой, а не массив-копию и не обязуется вернуть исходный DatePeriod.

Скачать самостоятельный пример с fixtures, результатом и README

Чтобы понять декоратор, полезно один раз вызвать протокол вручную.

Увидеть делегирование пяти операций курсораСамостоятельный пример
<?php
declare(strict_types=1);

$inner = new ArrayIterator(['new', 'paid']);
$outer = new IteratorIterator($inner);
$outer->rewind();
while ($outer->valid()) {
    echo $outer->key(), '=', $outer->current(), "\n";
    $outer->next();
}
$outer->rewind();
echo 'again: ', $outer->current(), "\n";
Ожидаемый результат
0=new
1=paid
again: new

Каждый outer-метод делегировал действие inner ArrayIterator. После конца rewind() снова перемотал повторяемый источник; обёртка не создала второго набора данных.

Скачать самостоятельный пример с fixtures, результатом и README

Полный справочник методов этого класса:

МетодЗачем открыть карточку
IteratorIterator::__constructсоздать и настроить объект для дальнейшего обхода
IteratorIterator::currentполучить текущее значение без продвижения курсора
IteratorIterator::getInnerIteratorполучить непосредственно обёрнутый итератор текущего уровня
IteratorIterator::keyполучить ключ или позицию текущего элемента
IteratorIterator::nextперевести курсор к следующему элементу
IteratorIterator::rewindпопытаться установить курсор на первый элемент
IteratorIterator::validпроверить, указывает ли курсор на существующий элемент

LimitIterator: конечное окно существующего обхода

Экрану нужна только одна страница каталога, а циклической схеме — только несколько значений.

Что происходит во время обхода
  1. offset пропускает предыдущие позиции
  2. limit разрешает ограниченное число current
  3. после окна valid становится false

Эта схема показывает значения и переходы именно приведённого примера. Внутри PHP объект хранит служебное состояние, а не нарисованные коробки или стрелки.

В памяти пять товаров, а интерфейс показывает окно из двух значений, начиная с позиции 2.

Показать вторую страницу каталогаСамостоятельный пример
<?php
declare(strict_types=1);

$catalog = new ArrayIterator(['A', 'B', 'C', 'D', 'E']);
$page = new LimitIterator($catalog, 2, 2);
foreach ($page as $key => $item) {
    echo 'source=', $page->getPosition(), '; key=', $key, '; item=', $item, "\n";
}
$page->seek(3);
echo 'seek result: ', $page->current(), "\n";
Ожидаемый результат
source=2; key=2; item=C
source=3; key=3; item=D
seek result: D

Конструктор ограничил видимый диапазон C–D. getPosition() показал абсолютную позицию внутреннего источника. seek(3) допустим внутри окна и выбрал D.

Скачать самостоятельный пример с fixtures, результатом и README

InfiniteIterator сам не остановится. Смещение пропускает первый day, лимит разрешает четыре следующих значения.

Остановить циклический источник после четырёх значенийСамостоятельный пример
<?php
declare(strict_types=1);

$cycle = new InfiniteIterator(new ArrayIterator(['day', 'night']));
$limited = new LimitIterator($cycle, 1, 4);
$limited->rewind();
$position = 1;
while ($limited->valid()) {
    echo $position, ':', $limited->current(), "\n";
    $position++;
    $limited->next();
}
Ожидаемый результат
1:night
2:day
3:night
4:day

rewind() LimitIterator позиционировал внутренний цикл на offset 1. Ключи InfiniteIterator повторяют ключи day/night, поэтому итоговую позицию считает отдельная переменная. valid() стал false после четырёх элементов, хотя сам InfiniteIterator оставался способен продолжаться.

Скачать самостоятельный пример с fixtures, результатом и README

Полный справочник методов этого класса:

МетодЗачем открыть карточку
LimitIterator::__constructсоздать и настроить объект для дальнейшего обхода
LimitIterator::currentполучить текущее значение без продвижения курсора
LimitIterator::getPositionполучить позицию внутри окна LimitIterator
LimitIterator::keyполучить ключ или позицию текущего элемента
LimitIterator::nextперевести курсор к следующему элементу
LimitIterator::rewindпопытаться установить курсор на первый элемент
LimitIterator::seekперейти к заданной позиции обхода
LimitIterator::validпроверить, указывает ли курсор на существующий элемент

MultipleIterator: несколько колонок на одной позиции

Названия и остатки приходят отдельными упорядоченными источниками. На каждом шаге требуется составить одну строку отчёта.

Что происходит во время обхода
  1. attachIterator связывает источник с именем
  2. rewind/next двигают все курсоры
  3. current/key возвращают составные массивы

Эта схема показывает значения и переходы именно приведённого примера. Внутри PHP объект хранит служебное состояние, а не нарисованные коробки или стрелки.

Две колонки уже упорядочены одинаково. Нужно читать пару значений на каждом шаге без ручного управления двумя курсорами.

Собрать товар и остаток по одной позицииСамостоятельный пример
<?php
declare(strict_types=1);

$names = new ArrayIterator(['brush', 'paint']);
$qty = new ArrayIterator([2, 0]);
$rows = new MultipleIterator(MultipleIterator::MIT_NEED_ALL | MultipleIterator::MIT_KEYS_ASSOC);
$rows->attachIterator($names, 'name');
$rows->attachIterator($qty, 'qty');
foreach ($rows as $keys => $row) {
    echo $keys['name'], ':', $row['name'], '=', $row['qty'], "\n";
}
Ожидаемый результат
0:brush=2
1:paint=0

attachIterator() закрепил имена name и qty. current() сформировал ассоциативную пару, key() — ассоциативную пару исходных ключей. MIT_NEED_ALL потребовал наличие обеих колонок.

Скачать самостоятельный пример с fixtures, результатом и README

Источники имеют разную длину. Для отчёта допустима строка с null после окончания короткой колонки.

Проверить, перенастроить и отключить источникСамостоятельный пример
<?php
declare(strict_types=1);

$left = new ArrayIterator(['A']);
$right = new ArrayIterator([10, 20]);
$rows = new MultipleIterator();
$rows->attachIterator($left);
$rows->attachIterator($right);
echo 'count: ', $rows->countIterators(), "\n";
echo 'contains left: ', $rows->containsIterator($left) ? 'yes' : 'no', "\n";
$rows->setFlags(MultipleIterator::MIT_NEED_ANY | MultipleIterator::MIT_KEYS_NUMERIC);
echo 'need-any: ', (($rows->getFlags() & MultipleIterator::MIT_NEED_ALL) === MultipleIterator::MIT_NEED_ANY) ? 'yes' : 'no', "\n";
foreach ($rows as $row) { echo json_encode($row), "\n"; }
$rows->detachIterator($left);
echo 'after detach: ', $rows->countIterators(), "\n";
Ожидаемый результат
count: 2
contains left: yes
need-any: yes
["A",10]
[null,20]
after detach: 1

MIT_NEED_ANY разрешил второй ряд; отсутствующее значение стало null. Эта константа равна нулевому варианту битовой группы, поэтому режим проверяется сравнением замаскированной группы, а не обычным truthy-тестом. containsIterator() проверил идентичность объекта. detachIterator() отключил именно $left, и countIterators() уменьшился до одного.

Скачать самостоятельный пример с fixtures, результатом и README

Этот пример раскрывает общий Iterator-протокол для двух синхронных источников.

Пройти составной итератор вручнуюСамостоятельный пример
<?php
declare(strict_types=1);

$rows = new MultipleIterator();
$rows->attachIterator(new ArrayIterator(['x', 'y']));
$rows->attachIterator(new ArrayIterator([1, 2]));
$rows->rewind();
while ($rows->valid()) {
    echo json_encode($rows->key()), '=', json_encode($rows->current()), "\n";
    $rows->next();
}
$rows->rewind();
echo 'again: ', json_encode($rows->current()), "\n";
Ожидаемый результат
[0,0]=["x",1]
[1,1]=["y",2]
again: ["x",1]

rewind()/next()/valid() управляли обоими внутренними курсорами. key() и current() вернули составные массивы. Повторный rewind() сработал, потому что оба ArrayIterator повторяемы.

Скачать самостоятельный пример с fixtures, результатом и README

Полный справочник методов этого класса:

МетодЗачем открыть карточку
MultipleIterator::attachIteratorподключить ещё один синхронно читаемый итератор
MultipleIterator::__constructсоздать и настроить объект для дальнейшего обхода
MultipleIterator::containsIteratorпроверить, подключён ли конкретный объект-итератор
MultipleIterator::countIteratorsполучить число подключённых синхронных источников
MultipleIterator::currentполучить текущее значение без продвижения курсора
MultipleIterator::detachIteratorотключить конкретный итератор от синхронного обхода
MultipleIterator::getFlagsпрочитать действующую битовую маску режима объекта
MultipleIterator::keyполучить ключ или позицию текущего элемента
MultipleIterator::nextперевести курсор к следующему элементу
MultipleIterator::rewindпопытаться установить курсор на первый элемент
MultipleIterator::setFlagsзаменить действующую битовую маску режима
MultipleIterator::validпроверить, указывает ли курсор на существующий элемент

NoRewindIterator: не начинать поток заново

Первый потребитель прочитал часть одноразовой последовательности; второй должен продолжить с текущего места.

Что происходит во время обхода
  1. rewind разрешает начальную позицию, но не возвращает назад
  2. current можно прочитать снова на той же позиции
  3. next окончательно продвигает внутренний курсор

Эта схема показывает значения и переходы именно приведённого примера. Внутри PHP объект хранит служебное состояние, а не нарисованные коробки или стрелки.

Первый обработчик остановился на B. Второй foreach не должен незаметно вернуться к A.

Передать остаток одноразового потока второму обработчикуСамостоятельный пример
<?php
declare(strict_types=1);

$stream = new NoRewindIterator(new ArrayIterator(['A', 'B', 'C']));
foreach ($stream as $value) {
    echo 'first: ', $value, "\n";
    if ($value === 'B') { break; }
}
foreach ($stream as $value) {
    echo 'second: ', $value, "\n";
}
Ожидаемый результат
first: A
first: B
second: B
second: C

После break курсор всё ещё указывал на B. Второй foreach вызвал rewind(), но NoRewindIterator его проигнорировал, поэтому B был прочитан повторно, затем next() перевёл курсор к C. Класс защищает от перемотки, но не от повторного чтения current().

Скачать самостоятельный пример с fixtures, результатом и README

Явный протокол показывает, что rewind() после продвижения ничего не меняет.

Управлять оставшимся курсором явноСамостоятельный пример
<?php
declare(strict_types=1);

$stream = new NoRewindIterator(new ArrayIterator(['header', 'body']));
$stream->rewind();
echo $stream->key(), ':', $stream->current(), "\n";
$stream->next();
$stream->rewind();
echo $stream->key(), ':', $stream->current(), "\n";
$stream->next();
echo 'valid: ', $stream->valid() ? 'yes' : 'no', "\n";
Ожидаемый результат
0:header
1:body
valid: no

Первый rewind() позволил начать с header. После next() курсор был на body; второй rewind() сохранил эту позицию. Ещё один next() закончил источник, valid() вернул false.

Скачать самостоятельный пример с fixtures, результатом и README

Полный справочник методов этого класса:

МетодЗачем открыть карточку
NoRewindIterator::__constructсоздать и настроить объект для дальнейшего обхода
NoRewindIterator::currentполучить текущее значение без продвижения курсора
NoRewindIterator::keyполучить ключ или позицию текущего элемента
NoRewindIterator::nextперевести курсор к следующему элементу
NoRewindIterator::rewindпопытаться установить курсор на первый элемент
NoRewindIterator::validпроверить, указывает ли курсор на существующий элемент

Перед фильтрами: predicate, bool и callback простыми словами

Фильтр отвечает на один вопрос для каждого элемента: «оставить его?» Функция, которая отвечает на такой вопрос, называется предикатом. Значение true означает «да, оставить», false — «нет, пропустить». Это не строки "true" и "false", а отдельный тип bool.

Как один заказ проходит фильтр
  1. Iterator ставит курсор на заказ №102.
  2. Callback получает массив заказа и проверяет status === paid.
  3. Предикат возвращает true, поэтому foreach видит заказ №102.
  4. Для следующего заказа вопрос задаётся заново; исходный массив не переписывается.

Callback — значение, по которому PHP может вызвать функцию: например, имя isPaidOrder или анонимная функция. Начните с именованной функции: её проще отдельно прочитать и проверить. Когда правило должно хранить настройки и повторно использоваться как самостоятельный тип, переходите к подклассу FilterIterator.

ИнструментКогда он понятнее
CallbackFilterIteratorОдно короткое правило для готового Iterator.
FilterIteratorПовторно используемый класс правила с параметрами и именем предметной области.
RegexIteratorПравило действительно описывает форму строки: префикс, расширение, шаблон журнала.
Обычный foreachНужно разложить элементы в accepted/rejected, изменить каждый элемент либо выполнить побочный эффект.

CachingIterator: сосед справа и уже прочитанная часть потока

При формировании цепочки нужен признак следующего элемента, а при диагностике импорта — только уже прочитанные записи. CachingIterator оборачивает существующий Iterator и добавляет эти два вида состояния.

Что происходит во время обхода
  1. rewind/next двигают внутренний Iterator и обновляют текущую позицию
  2. hasNext заглядывает к соседу, не отдавая его потребителю
  3. FULL_CACHE накапливает пройденные ключи и значения; без него getCache/Countable/ArrayAccess недоступны

Эта схема показывает значения и переходы именно приведённого примера. Внутри PHP объект хранит служебное состояние, а не нарисованные коробки или стрелки.

Интерфейс показывает цепочку этапов. После последнего этапа стрелка не нужна, но обычный foreach сам по себе не сообщает, есть ли сосед справа.

Поставить разделитель только между этапами заказаСамостоятельный пример
<?php
declare(strict_types=1);

$steps = new CachingIterator(
    new ArrayIterator(['received', 'paid', 'shipped'])
);

foreach ($steps as $step) {
    echo $steps->key(), ':', (string) $steps;
    echo $steps->hasNext() ? ' -> ' : "\n";
}
Ожидаемый результат
0:received -> 1:paid -> 2:shipped

foreach вызвал rewind(), valid(), current() и next(). На каждой позиции hasNext() заглянул на один шаг вперёд, не потребляя соседний элемент. Поэтому разделитель появился только между значениями. __toString() безопасен здесь, потому что значения — строки и действует стандартный CALL_TOSTRING.

Скачать самостоятельный пример с fixtures, результатом и README

Импорт заказов читается постепенно. Для диагностики нужно посмотреть только реально пройденные записи и временно пометить одну из них, не изменяя исходный ArrayIterator.

Увидеть только уже прочитанную часть потокаСамостоятельный пример
<?php
declare(strict_types=1);

$orders = new CachingIterator(
    new ArrayIterator([
        'order-101' => 'new',
        'order-102' => 'paid',
        'order-103' => 'sent',
    ]),
    CachingIterator::FULL_CACHE
);

$orders->rewind();
echo 'key=', $orders->key(), '; full-cache=',
    ($orders->getFlags() & CachingIterator::FULL_CACHE) !== 0 ? 'yes' : 'no',
    "\n";
echo json_encode($orders->getCache()), "\n";

$orders->next();
echo json_encode($orders->getCache()), "\n";
echo 'count=', count($orders),
    '; exists=', isset($orders['order-102']) ? 'yes' : 'no',
    '; value=', $orders['order-102'], "\n";

$orders['review'] = 'manual';
echo json_encode($orders->getCache()), "\n";
unset($orders['review']);
echo json_encode($orders->getCache()), "\n";
Ожидаемый результат
key=order-101; full-cache=yes
{"order-101":"new"}
{"order-101":"new","order-102":"paid"}
count=2; exists=yes; value=paid
{"order-101":"new","order-102":"paid","review":"manual"}
{"order-101":"new","order-102":"paid"}

FULL_CACHE добавил текущую запись при rewind() и следующую при next(). getCache(), count() и ArrayAccess работают с накопленным кешем: непрочитанный order-103 ещё отсутствует. Запись review появилась только в кеше и была удалена; это не команда изменить исходный источник.

Скачать самостоятельный пример с fixtures, результатом и README

Один диагностический экран должен сначала показывать артикул, а затем название товара. Источник и курсор остаются прежними; меняется только правило __toString().

Переключить строковое представление с ключа на значениеСамостоятельный пример
<?php
declare(strict_types=1);

function cachingFlagNames(int $flags): string
{
    $names = [];
    foreach (['TOSTRING_USE_KEY', 'TOSTRING_USE_CURRENT', 'FULL_CACHE'] as $name) {
        $value = constant("CachingIterator::$name");
        if (($flags & $value) === $value) {
            $names[] = $name;
        }
    }
    return implode('|', $names);
}

$items = new CachingIterator(
    new ArrayIterator(['SKU-1' => 'Brush', 'SKU-2' => 'Paint']),
    CachingIterator::FULL_CACHE | CachingIterator::TOSTRING_USE_KEY
);

$items->rewind();
echo cachingFlagNames($items->getFlags()), ':', (string) $items,
    '; next=', $items->hasNext() ? 'yes' : 'no', "\n";

$items->setFlags(
    CachingIterator::FULL_CACHE | CachingIterator::TOSTRING_USE_CURRENT
);
echo cachingFlagNames($items->getFlags()), ':', (string) $items, "\n";

$items->next();
echo cachingFlagNames($items->getFlags()), ':', (string) $items,
    '; next=', $items->hasNext() ? 'yes' : 'no', "\n";
Ожидаемый результат
TOSTRING_USE_KEY|FULL_CACHE:SKU-1; next=yes
TOSTRING_USE_CURRENT|FULL_CACHE:Brush
TOSTRING_USE_CURRENT|FULL_CACHE:Paint; next=no

getFlags() вернул битовую маску. Оператор & проверил отдельные биты, а | объединил режимы. setFlags() заменил всю маску, поэтому FULL_CACHE включён повторно вместе с новым TOSTRING_USE_CURRENT. hasNext() подтвердил сосед только на первой позиции.

Скачать самостоятельный пример с fixtures, результатом и README

Полный справочник методов этого класса:

МетодЗачем открыть карточку
CachingIterator::__constructсоздать и настроить объект для дальнейшего обхода
CachingIterator::countполучить число элементов, которое определяет этот класс
CachingIterator::currentполучить текущее значение без продвижения курсора
CachingIterator::getCacheполучить значения, уже помещённые в кэш во время обхода
CachingIterator::getFlagsпрочитать действующую битовую маску режима объекта
CachingIterator::hasNextпроверить наличие следующего элемента без его потребления
CachingIterator::keyполучить ключ или позицию текущего элемента
CachingIterator::nextперевести курсор к следующему элементу
CachingIterator::offsetExistsпроверить наличие элемента по ключу без чтения несуществующего значения
CachingIterator::offsetGetпрочитать элемент по ключу через ArrayAccess
CachingIterator::offsetSetзаписать или добавить элемент через ArrayAccess
CachingIterator::offsetUnsetудалить элемент по ключу через ArrayAccess
CachingIterator::rewindпопытаться установить курсор на первый элемент
CachingIterator::setFlagsзаменить действующую битовую маску режима
CachingIterator::__toStringполучить строковое представление текущего элемента
CachingIterator::validпроверить, указывает ли курсор на существующий элемент
Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

The CachingIterator class

(PHP 5, PHP 7, PHP 8)

Introduction

This object supports cached iteration over another iterator.

Class synopsis

class CachingIterator

extends IteratorIterator

implements ArrayAccess,

Countable,

Stringable {

/* Constants */

public const int CALL_TOSTRING;

public const int CATCH_GET_CHILD;

public const int TOSTRING_USE_KEY;

public const int TOSTRING_USE_CURRENT;

public const int TOSTRING_USE_INNER;

public const int FULL_CACHE;

/* Methods */

public function __construct(Iterator $iterator, int $flags = CachingIterator::CALL_TOSTRING)

public function count(): int

public function current(): mixed

public function getCache(): array

public function getFlags(): int

public function hasNext(): bool

public function key(): scalar

public function next(): void

public function offsetExists(string $key): bool

public function offsetGet(string $key): mixed

public function offsetSet(string $key, mixed $value): void

public function offsetUnset(string $key): void

public function rewind(): void

public function setFlags(int $flags): void

public function __toString(): string

public function valid(): bool

/* Inherited methods */

public function IteratorIterator::current(): mixed

public function IteratorIterator::getInnerIterator(): ?Iterator

public function IteratorIterator::key(): mixed

public function IteratorIterator::next(): void

public function IteratorIterator::rewind(): void

public function IteratorIterator::valid(): bool

}

Predefined Constants

CachingIterator::CALL_TOSTRING

Convert every element to string.

CachingIterator::CATCH_GET_CHILD

Don't throw exception in accessing children.

CachingIterator::TOSTRING_USE_KEY

Use key for conversion to string.

CachingIterator::TOSTRING_USE_CURRENT

Use current for conversion to string.

CachingIterator::TOSTRING_USE_INNER

Use inner for conversion to string.

CachingIterator::FULL_CACHE

Cache all read data.

Changelog

Version Description

8.0.0

CachingIterator implements Stringable now.

Changelog

Version Description

8.4.0

The class constants are now typed.

Table of Contents CachingIterator::__construct — Construct a new CachingIterator object for the iterator CachingIterator::count — The number of elements in the iterator CachingIterator::current — Return the current element CachingIterator::getCache — Retrieve the contents of the cache CachingIterator::getFlags — Get flags used CachingIterator::hasNext — Check whether the inner iterator has a valid next element CachingIterator::key — Return the key for the current element CachingIterator::next — Move the iterator forward CachingIterator::offsetExists — The offsetExists purpose CachingIterator::offsetGet — The offsetGet purpose CachingIterator::offsetSet — The offsetSet purpose CachingIterator::offsetUnset — The offsetUnset purpose CachingIterator::rewind — Rewind the iterator CachingIterator::setFlags — The setFlags purpose CachingIterator::__toString — Return the string representation of the current element CachingIterator::valid — Check whether the current element is valid

CallbackFilterIterator: одно понятное правило true/false

Есть готовый Iterator заказов. Нужно оставить оплаченные строки или доступные позиции веб-витрины, не создавая новый массив и отдельный класс.

Что происходит во время обхода
  1. конструктор получает внутренний Iterator и callable
  2. для текущего значения callback получает value, key и внутренний Iterator
  3. true пропускает элемент наружу, false заставляет фильтр искать следующий

Эта схема показывает значения и переходы именно приведённого примера. Внутри PHP объект хранит служебное состояние, а не нарисованные коробки или стрелки.

Платёжный обработчик получил три заказа, но чек нужен только для статуса paid. Сначала правило записано обычной именованной функцией, чтобы было видно вход и bool-результат.

Отправить чеки только по оплаченным заказамСамостоятельный пример
<?php
declare(strict_types=1);

$orders = new ArrayIterator([
    ['id' => 101, 'status' => 'new'],
    ['id' => 102, 'status' => 'paid'],
    ['id' => 103, 'status' => 'paid'],
]);

function isPaidOrder(array $order): bool
{
    return $order['status'] === 'paid';
}

$paidOrders = new CallbackFilterIterator($orders, 'isPaidOrder');
foreach ($paidOrders as $order) {
    echo 'send receipt #', $order['id'], "\n";
}
Ожидаемый результат
send receipt #102
send receipt #103

isPaidOrder — предикат: вопрос с ответом true или false. Callback — ссылка на вызываемую функцию; строка isPaidOrder передана конструктору, а итератор вызвал её для каждой строки. true оставил заказ, false пропустил его.

Скачать самостоятельный пример с fixtures, результатом и README

Один источник содержит склад и веб-витрину. Для публикации нужны ключи web-* с положительным остатком.

Выбрать доступные остатки веб-витрины по значению и ключуСамостоятельный пример
<?php
declare(strict_types=1);

$stock = new ArrayIterator([
    'web-brush' => 3,
    'store-paint' => 7,
    'web-tape' => 0,
    'web-gloves' => 2,
]);

$webAvailable = new CallbackFilterIterator(
    $stock,
    function (int $quantity, string $key, Iterator $iterator) use ($stock): bool {
        return $iterator === $stock
            && str_starts_with($key, 'web-')
            && $quantity > 0;
    }
);

foreach ($webAvailable as $sku => $quantity) {
    echo "$sku=$quantity\n";
}
Ожидаемый результат
web-brush=3
web-gloves=2

Анонимный callback получил значение, ключ и внутренний Iterator. Проверка идентичности показывает, какой именно объект приходит третьим аргументом; в обычном предикате она чаще не нужна. Условия соединены &&: только true по всем трём проверкам оставляет элемент.

Скачать самостоятельный пример с fixtures, результатом и README

Полный справочник методов этого класса:

МетодЗачем открыть карточку
CallbackFilterIterator::acceptрешить, попадёт ли текущий элемент в результат
CallbackFilterIterator::__constructсоздать и настроить объект для дальнейшего обхода
Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

The CallbackFilterIterator class

(PHP 5 >= 5.4.0, PHP 7, PHP 8)

Introduction

Class synopsis

class CallbackFilterIterator

extends FilterIterator {

/* Methods */

public function __construct(Iterator $iterator, callable $callback)

public function accept(): bool

/* Inherited methods */

public function FilterIterator::accept(): bool

public function FilterIterator::current(): mixed

public function FilterIterator::key(): mixed

public function FilterIterator::next(): void

public function FilterIterator::rewind(): void

public function FilterIterator::valid(): bool

public function IteratorIterator::current(): mixed

public function IteratorIterator::getInnerIterator(): ?Iterator

public function IteratorIterator::key(): mixed

public function IteratorIterator::next(): void

public function IteratorIterator::rewind(): void

public function IteratorIterator::valid(): bool

}

FilterIterator: повторно используемое правило как класс

Правило доступности товара используется в разных каталогах и должно иметь собственное имя, параметры и тестируемый метод. Абстрактный FilterIterator задаёт механизм, подкласс отвечает только за accept().

Что происходит во время обхода
  1. подкласс вызывает parent::__construct с готовым Iterator
  2. rewind/next двигают источник до позиции, где accept вернул true
  3. current/key отдают принятую строку, valid сообщает о конце принятых строк

Эта схема показывает значения и переходы именно приведённого примера. Внутри PHP объект хранит служебное состояние, а не нарисованные коробки или стрелки.

Правило «остаток больше нуля» используется в двух каталогах и будет нужно в других отчётах. Отдельный класс даёт правилу имя и одно место изменения.

Повторно использовать один класс правила для двух каталоговСамостоятельный пример
<?php
declare(strict_types=1);

final class AvailableProducts extends FilterIterator
{
    public function accept(): bool
    {
        $product = parent::current();
        return is_array($product) && $product['stock'] > 0;
    }
}

$catalogs = [
    new ArrayIterator([
        ['name' => 'Brush', 'stock' => 2],
        ['name' => 'Paint', 'stock' => 0],
    ]),
    new ArrayIterator([
        ['name' => 'Tape', 'stock' => 4],
        ['name' => 'Gloves', 'stock' => 0],
    ]),
];

foreach ($catalogs as $catalog) {
    foreach (new AvailableProducts($catalog) as $product) {
        echo $product['name'], "\n";
    }
}
Ожидаемый результат
Brush
Tape

FilterIterator абстрактный: его нельзя создать напрямую, поэтому AvailableProducts реализует accept(). parent::current() читает текущую строку внутреннего итератора. Один класс отфильтровал два разных ArrayIterator без копирования условия.

Скачать самостоятельный пример с fixtures, результатом и README

Нужно понять не только результат foreach, но и пять операций Iterator-протокола. Минимальная цена хранится в объекте фильтра.

Увидеть, как курсор пропускает неподходящие ценыСамостоятельный пример
<?php
declare(strict_types=1);

final class PriceAtLeast extends FilterIterator
{
    public function __construct(Iterator $iterator, private int $minimum)
    {
        parent::__construct($iterator);
    }

    public function accept(): bool
    {
        return parent::current() >= $this->minimum;
    }
}

$prices = new PriceAtLeast(
    new ArrayIterator(['pen' => 40, 'brush' => 120, 'paint' => 300]),
    100
);

$prices->rewind();
while ($prices->valid()) {
    echo $prices->key(), '=', $prices->current(), "\n";
    $prices->next();
}
Ожидаемый результат
brush=120
paint=300

rewind() перемотал источник и сразу продвинул его мимо pen=40 до первого accept() === true. current()/key() прочитали brush. next() снова двигал внутренний курсор до следующего принятого элемента, а valid() завершил цикл после paint.

Скачать самостоятельный пример с fixtures, результатом и README

Полный справочник методов этого класса:

МетодЗачем открыть карточку
FilterIterator::acceptрешить, попадёт ли текущий элемент в результат
FilterIterator::__constructсоздать и настроить объект для дальнейшего обхода
FilterIterator::currentполучить текущее значение без продвижения курсора
FilterIterator::keyполучить ключ или позицию текущего элемента
FilterIterator::nextперевести курсор к следующему элементу
FilterIterator::rewindпопытаться установить курсор на первый элемент
FilterIterator::validпроверить, указывает ли курсор на существующий элемент
Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

The FilterIterator class

(PHP 5 >= 5.1.0, PHP 7, PHP 8)

Introduction

This abstract iterator filters out unwanted values. This class should be extended to implement custom iterator filters. The FilterIterator::accept() must be implemented in the subclass.

Class synopsis

abstract class FilterIterator

extends IteratorIterator {

/* Methods */

public function __construct(Iterator $iterator)

public function accept(): bool

public function current(): mixed

public function key(): mixed

public function next(): void

public function rewind(): void

public function valid(): bool

/* Inherited methods */

public function IteratorIterator::current(): mixed

public function IteratorIterator::getInnerIterator(): ?Iterator

public function IteratorIterator::key(): mixed

public function IteratorIterator::next(): void

public function IteratorIterator::rewind(): void

public function IteratorIterator::valid(): bool

}

Table of Contents FilterIterator::accept — Check whether the current element of the iterator is acceptable FilterIterator::__construct — Construct a filterIterator FilterIterator::current — Get the current element value FilterIterator::key — Get the current key FilterIterator::next — Move the iterator forward FilterIterator::rewind — Rewind the iterator FilterIterator::valid — Check whether the current element is valid

RegexIterator: фильтрация и преобразование формы строки

Имена файлов, коды и старые строки журналов имеют текстовый шаблон. RegexIterator применяет регулярное выражение к значению либо ключу и может вернуть совпадение, все совпадения, части или замену.

Что происходит во время обхода
  1. pattern описывает именно форму текста, режим определяет форму current()
  2. USE_KEY переносит сопоставление на ключ, INVERT_MATCH инвертирует принятие
  3. pregFlags меняют структуру результата GET_MATCH, ALL_MATCHES или SPLIT

Эта схема показывает значения и переходы именно приведённого примера. Внутри PHP объект хранит служебное состояние, а не нарисованные коробки или стрелки.

Есть две строковые задачи: распознать расширение файла в значении и распознать служебный префикс в ключе. Обе действительно относятся к форме текста.

Отобрать изображения по значению и исключить черновики по ключуСамостоятельный пример
<?php
declare(strict_types=1);

$images = new RegexIterator(
    new ArrayIterator(['notes.txt', 'PHOTO.JPG', 'icon.png']),
    '/\.(?:jpe?g|png)$/i'
);
foreach ($images as $name) {
    echo $name, "\n";
}

$published = new RegexIterator(
    new ArrayIterator([
        'draft-1' => 'A',
        'order-2' => 'B',
        'draft-3' => 'C',
    ]),
    '/^draft-/'
);
$published->setFlags(RegexIterator::USE_KEY | RegexIterator::INVERT_MATCH);
echo 'flags=', $published->getFlags(),
    '; regex=', $published->getRegex(), "\n";
foreach ($published as $key => $value) {
    echo "$key=$value\n";
}
Ожидаемый результат
PHOTO.JPG
icon.png
flags=3; regex=/^draft-/
order-2=B

Стандартный MATCH оставил совпавшие значения; модификатор i отключил зависимость от регистра. Во втором фильтре USE_KEY перенёс проверку на ключ, INVERT_MATCH инвертировал решение, а | объединил оба флага. Для статуса заказа из отдельного поля лучше callback со строгим сравнением, а не regex.

Скачать самостоятельный пример с fixtures, результатом и README

Старая строка журнала содержит номер заказа внутри текста. Нужно получить первое совпадение и место, с которого начинается захваченная группа.

Извлечь номер заказа и позицию совпаденияСамостоятельный пример
<?php
declare(strict_types=1);

$orders = new RegexIterator(
    new ArrayIterator(['order #104 costs 3500', 'broken record']),
    '/order #(?<id>\d+)/'
);
$orders->setMode(RegexIterator::GET_MATCH);
$orders->setPregFlags(PREG_OFFSET_CAPTURE);

foreach ($orders as $match) {
    echo 'id=', $match['id'][0],
        '; offset=', $match['id'][1], "\n";
}
Ожидаемый результат
id=104; offset=7

GET_MATCH заменил current() массивом результата preg_match(). Именованная группа id дала понятный ключ. PREG_OFFSET_CAPTURE превратил каждое совпадение в пару [текст, смещение]. broken record не совпал и не попал в обход.

Скачать самостоятельный пример с fixtures, результатом и README

Одна строка аудита может содержать несколько артикулов. Первого совпадения недостаточно.

Собрать все артикулы из каждой строки журналаСамостоятельный пример
<?php
declare(strict_types=1);

$logs = new RegexIterator(
    new ArrayIterator([
        'added SKU-12 and SKU-77',
        'nothing',
        'removed SKU-5',
    ]),
    '/SKU-\d+/',
    RegexIterator::ALL_MATCHES
);

foreach ($logs as $matches) {
    echo implode(',', $matches[0]), "\n";
}
Ожидаемый результат
SKU-12,SKU-77
SKU-5

ALL_MATCHES использовал семантику preg_match_all(): $matches[0] содержит все полные совпадения текущей строки. Строка nothing отфильтрована. Если вход уже является массивом SKU, цикл и строгая проверка структуры яснее регулярного выражения.

Скачать самостоятельный пример с fixtures, результатом и README

Импорт старого поля хранит теги с несколькими видами разделителей. Требуется массив непустых частей.

Разделить строку тегов по пробелам, запятым и точкам с запятойСамостоятельный пример
<?php
declare(strict_types=1);

$lines = new RegexIterator(
    new ArrayIterator(['php, spl; iterators', 'single']),
    '/[\s,;]+/',
    RegexIterator::SPLIT
);
$lines->setPregFlags(PREG_SPLIT_NO_EMPTY);

echo 'mode=', $lines->getMode(),
    '; preg-flags=', $lines->getPregFlags(), "\n";
foreach ($lines as $parts) {
    echo implode('|', $parts), "\n";
}
Ожидаемый результат
mode=3; preg-flags=1
php|spl|iterators

SPLIT возвращает результат preg_split() для совпавших строк. PREG_SPLIT_NO_EMPTY убрал пустые части. Строка single не содержит разделителя и поэтому не была принята итератором; если её тоже нужно сохранить как один тег, обычный цикл с preg_split() для каждой строки выразит требование точнее.

Скачать самостоятельный пример с fixtures, результатом и README

Старые коды order-N надо показать как ID:N, а заголовок не является кодом.

Нормализовать только совпавшие коды заказовСамостоятельный пример
<?php
declare(strict_types=1);

$codes = new RegexIterator(
    new ArrayIterator(['header', 'order-17', 'order-25']),
    '/^order-(\d+)$/',
    RegexIterator::REPLACE
);
$codes->replacement = 'ID:$1';

foreach ($codes as $key => $code) {
    echo "$key:$code\n";
}
Ожидаемый результат
1:ID:17
2:ID:25

REPLACE выполнил preg_replace() и вернул преобразованные совпавшие элементы с исходными ключами. header исчез: RegexIterator остаётся фильтром и не обещает сохранить несовпавшие строки. Если нужен map, сохраняющий каждый элемент, используйте обычный цикл или array_map(). Официальная документация помечает REPLACE как реализованный не полностью, поэтому критичный код требует теста целевой версии.

Скачать самостоятельный пример с fixtures, результатом и README

Полный справочник методов этого класса:

МетодЗачем открыть карточку
RegexIterator::acceptрешить, попадёт ли текущий элемент в результат
RegexIterator::__constructсоздать и настроить объект для дальнейшего обхода
RegexIterator::getFlagsпрочитать действующую битовую маску режима объекта
RegexIterator::getModeпрочитать режим сопоставления RegexIterator
RegexIterator::getPregFlagsпрочитать флаги preg_match(), используемые регулярным выражением
RegexIterator::getRegexполучить исходную строку регулярного выражения
RegexIterator::setFlagsзаменить действующую битовую маску режима
RegexIterator::setModeзаменить режим результата RegexIterator
RegexIterator::setPregFlagsзадать флаги preg_match() для режима совпадений
Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

The RegexIterator class

(PHP 5 >= 5.2.0, PHP 7, PHP 8)

Introduction

This iterator can be used to filter another iterator based on a regular expression.

Class synopsis

class RegexIterator

extends FilterIterator {

/* Constants */

public const int USE_KEY;

public const int INVERT_MATCH;

public const int MATCH;

public const int GET_MATCH;

public const int ALL_MATCHES;

public const int SPLIT;

public const int REPLACE;

/* Properties */

public ?string $replacement = null;

/* Methods */

public function __construct(    Iterator $iterator,    string $pattern,    int $mode = RegexIterator::MATCH,    int $flags = 0,    int $pregFlags = 0)

public function accept(): bool

public function getFlags(): int

public function getMode(): int

public function getPregFlags(): int

public function getRegex(): string

public function setFlags(int $flags): void

public function setMode(int $mode): void

public function setPregFlags(int $pregFlags): void

/* Inherited methods */

public function FilterIterator::accept(): bool

public function FilterIterator::current(): mixed

public function FilterIterator::key(): mixed

public function FilterIterator::next(): void

public function FilterIterator::rewind(): void

public function FilterIterator::valid(): bool

public function IteratorIterator::current(): mixed

public function IteratorIterator::getInnerIterator(): ?Iterator

public function IteratorIterator::key(): mixed

public function IteratorIterator::next(): void

public function IteratorIterator::rewind(): void

public function IteratorIterator::valid(): bool

}

Predefined Constants

RegexIterator operation modes

RegexIterator::ALL_MATCHES

Return all matches for the current entry (see preg_match_all()).

RegexIterator::GET_MATCH

Return the first match for the current entry (see preg_match()).

RegexIterator::MATCH

Only execute match (filter) for the current entry (see preg_match()).

RegexIterator::REPLACE

Replace the current entry (see preg_replace(); Not fully implemented yet)

RegexIterator::SPLIT

Returns the split values for the current entry (see preg_split()).

RegexIterator Flags

RegexIterator::USE_KEY

Special flag: Match the entry key instead of the entry value.

RegexIterator::INVERT_MATCH

Inverts the return value of RegexIterator::accept().

Properties

replacement

Changelog

Version Description

8.4.0

The class constants are now typed.

Table of Contents RegexIterator::accept — Get accept status RegexIterator::__construct — Create a new RegexIterator RegexIterator::getFlags — Get flags RegexIterator::getMode — Returns operation mode RegexIterator::getPregFlags — Returns the regular expression flags RegexIterator::getRegex — Returns current regular expression RegexIterator::setFlags — Sets the flags RegexIterator::setMode — Sets the operation mode RegexIterator::setPregFlags — Sets the regular expression flags

ParentIterator: показать только узлы, в которые можно войти

Нужно построить список раскрываемых разделов меню или категорий и не смешать их с конечными ссылками. Сначала пример делает ту же проверку обычным foreach, затем ParentIterator оставляет только текущие узлы с детьми.

Что происходит во время обхода
  1. Исходный RecursiveIterator ставит курсор на очередной узел.
  2. ParentIterator спрашивает hasChildren() и принимает только true.
  3. foreach получает parent; getChildren() открывает следующий уровень по запросу.

Эта схема показывает значения и переходы именно приведённого примера. Внутри PHP объект хранит служебное состояние, а не нарисованные коробки или стрелки.

До SPL задача формулируется просто: пройти первый уровень и оставить только значения-массивы.

Сначала увидеть родителей обычным foreachСамостоятельный пример
<?php
$catalog = [
    'lamps' => ['desk' => 3, 'floor' => 2],
    'delivery' => 'free',
    'cables' => ['usb' => 8],
];
foreach ($catalog as $name => $value) {
    if (is_array($value)) {
        echo $name, ': ', count($value), " дочерних\n";
    }
}
Ожидаемый результат
lamps: 2 дочерних
cables: 1 дочерних

Обычный foreach полезно увидеть первым: ParentIterator автоматизирует именно эту проверку, а не создаёт новое дерево.

Скачать самостоятельный пример с fixtures, результатом и README

Теперь то же правило поручено объекту: ParentIterator пропускает листья и отдаёт узлы, в которые можно спуститься.

Получить только разделы меню через ParentIteratorСамостоятельный пример
<?php
$menu = new RecursiveArrayIterator([
    'shop' => ['catalog' => '/catalog', 'cart' => '/cart'],
    'contacts' => '/contacts',
    'help' => ['faq' => '/faq'],
]);
$parents = new ParentIterator($menu);
foreach ($parents as $key => $children) {
    echo $key, ': ', count($children), " пунктов\n";
}
Ожидаемый результат
shop: 2 пунктов
help: 1 пунктов

Результат содержит shop и help, но не contacts: строка является листом, даже если по смыслу это пункт меню.

Скачать самостоятельный пример с fixtures, результатом и README

Полный справочник методов этого класса:

МетодЗачем открыть карточку
ParentIterator::acceptрешить, попадёт ли текущий элемент в результат
ParentIterator::__constructсоздать и настроить объект для дальнейшего обхода
ParentIterator::getChildrenполучить рекурсивный итератор дочернего уровня текущего узла
ParentIterator::hasChildrenпроверить, можно ли открыть дочерний уровень текущего узла
ParentIterator::nextперевести курсор к следующему элементу
ParentIterator::rewindпопытаться установить курсор на первый элемент

RecursiveArrayIterator: вложенный массив как дерево

Обычный PHP-массив может содержать другой массив. RecursiveArrayIterator не скрывает это устройство: он добавляет к текущему курсору два явных действия — спросить о детях и открыть их.

Что происходит во время обхода
  1. current/key указывают на один элемент массива.
  2. hasChildren() отличает вложенный контейнер от листа.
  3. getChildren() создаёт итератор ровно следующего уровня; рекурсия повторяет эти шаги.

Эта схема показывает значения и переходы именно приведённого примера. Внутри PHP объект хранит служебное состояние, а не нарисованные коробки или стрелки.

Обычный foreach первым показывает физическую форму данных: customer хранит ещё один массив, а id — число.

Увидеть вложенный массив до рекурсивных объектовСамостоятельный пример
<?php
$order = [
    'id' => 41,
    'customer' => ['name' => 'Ирина', 'city' => 'Тула'],
];
foreach ($order as $key => $value) {
    echo $key, ': ', is_array($value) ? 'вложенный массив' : $value, "\n";
}
Ожидаемый результат
id: 41
customer: вложенный массив

RecursiveArrayIterator не меняет эту модель; он даёт единый протокол hasChildren()/getChildren().

Скачать самостоятельный пример с fixtures, результатом и README

На каждой позиции объект умеет ответить, является ли значение дочерним уровнем.

Открыть вложенный заказ через рекурсивный протоколСамостоятельный пример
<?php
$tree = new RecursiveArrayIterator([
    'id' => 41,
    'customer' => ['name' => 'Ирина', 'city' => 'Тула'],
]);
foreach ($tree as $key => $value) {
    echo $key, ': ', $tree->hasChildren() ? 'ветка' : 'лист', "\n";
}
Ожидаемый результат
id: лист
customer: ветка

Это ещё не рекурсивный обход: foreach остаётся на первом уровне, а решение о спуске принимает вызывающий код.

Скачать самостоятельный пример с fixtures, результатом и README

Полный справочник методов этого класса:

МетодЗачем открыть карточку
RecursiveArrayIterator::getChildrenполучить рекурсивный итератор дочернего уровня текущего узла
RecursiveArrayIterator::hasChildrenпроверить, можно ли открыть дочерний уровень текущего узла

RecursiveCachingIterator: сосед, кэш и дочерний уровень

При печати дерева или списка разделитель зависит от того, есть ли следующий сосед. Этот класс добавляет к рекурсивному источнику look-ahead и, при выбранном FULL_CACHE, историю уже пройденных элементов каждого уровня.

Что происходит во время обхода
  1. RecursiveIterator остаётся источником текущего уровня.
  2. Обёртка кэширует позицию и отвечает hasNext().
  3. Для ветви getChildren() возвращает новую кэширующую обёртку дочернего уровня.

Эта схема показывает значения и переходы именно приведённого примера. Внутри PHP объект хранит служебное состояние, а не нарисованные коробки или стрелки.

Сначала полезный результат: при форматировании этапов нужно знать, есть ли сосед справа.

Увидеть кэш и следующий элемент на одном уровнеСамостоятельный пример
<?php
$cache = new RecursiveCachingIterator(
    new RecursiveArrayIterator(['draft', 'review', 'publish']),
    CachingIterator::FULL_CACHE
);
foreach ($cache as $stage) {
    echo $stage, ' | дальше: ', $cache->hasNext() ? 'да' : 'нет', "\n";
}
Ожидаемый результат
draft | дальше: да
review | дальше: да
publish | дальше: нет

RecursiveCachingIterator добавляет к обычному курсору кэш; рекурсивная часть понадобится, когда текущий элемент окажется ветвью.

Скачать самостоятельный пример с fixtures, результатом и README

На shop объект сообщает о детях и возвращает новый RecursiveCachingIterator для дочернего уровня.

Открыть кэшируемый дочерний уровеньСамостоятельный пример
<?php
$cache = new RecursiveCachingIterator(
    new RecursiveArrayIterator(['shop' => ['cart', 'checkout']]),
    CachingIterator::FULL_CACHE
);
$cache->rewind();
echo 'Ветка: ', $cache->hasChildren() ? 'да' : 'нет', "\n";
$children = $cache->getChildren();
foreach ($children as $page) {
    echo $page, "\n";
}
Ожидаемый результат
Ветка: да
cart
checkout

Кэш каждого уровня отдельный; это помогает форматировать дерево, но увеличивает использование памяти.

Скачать самостоятельный пример с fixtures, результатом и README

Полный справочник методов этого класса:

МетодЗачем открыть карточку
RecursiveCachingIterator::__constructсоздать и настроить объект для дальнейшего обхода
RecursiveCachingIterator::getChildrenполучить рекурсивный итератор дочернего уровня текущего узла
RecursiveCachingIterator::hasChildrenпроверить, можно ли открыть дочерний уровень текущего узла

RecursiveCallbackFilterIterator: фильтр, который не теряет путь к листу

Нужно скрыть секретные или неподходящие листья во вложенной конфигурации. Callback обязан пропустить родителей, иначе обход не попадёт внутрь и потеряет даже разрешённые дочерние значения.

Что происходит во время обхода
  1. Callback получает current, key и итератор текущего уровня.
  2. Если у узла есть дети, parent сохраняется ради спуска.
  3. Для листа callback применяет бизнес-условие; getChildren() переносит его на следующий уровень.

Эта схема показывает значения и переходы именно приведённого примера. Внутри PHP объект хранит служебное состояние, а не нарисованные коробки или стрелки.

Сначала задача решена двумя обычными foreach: родитель database нужен, даже если лист password надо скрыть.

Отфильтровать листья вручную и не потерять путьСамостоятельный пример
<?php
$config = [
    'database' => ['host' => 'db.local', 'password' => 'secret'],
    'debug' => true,
];
foreach ($config as $group => $value) {
    if (is_array($value)) {
        foreach ($value as $key => $item) {
            if ($key !== 'password') echo $group, '.', $key, '=', $item, "\n";
        }
    }
}
Ожидаемый результат
database.host=db.local

Это важная граница: удалив родителя слишком рано, код уже не доберётся до разрешённого host.

Скачать самостоятельный пример с fixtures, результатом и README

Callback получает значение, ключ и текущий рекурсивный итератор. Родители проходят по hasChildren(), листья — по отдельному правилу.

Сохранить родителей и выбрать безопасные листья callback-фильтромСамостоятельный пример
<?php
$source = new RecursiveArrayIterator([
    'database' => ['host' => 'db.local', 'password' => 'secret'],
    'debug' => true,
]);
$safe = new RecursiveCallbackFilterIterator(
    $source,
    function (mixed $current, mixed $key, RecursiveIterator $iterator): bool {
        return $iterator->hasChildren() || $key !== 'password';
    }
);
$flat = new RecursiveIteratorIterator($safe, RecursiveIteratorIterator::LEAVES_ONLY);
foreach ($flat as $key => $value) echo $key, '=', var_export($value, true), "\n";
Ожидаемый результат
host='db.local'
debug=true

Так путь к host сохраняется, password исключается, а корневой лист debug остаётся. Фильтр не маскирует исходный массив.

Скачать самостоятельный пример с fixtures, результатом и README

Полный справочник методов этого класса:

МетодЗачем открыть карточку
RecursiveCallbackFilterIterator::__constructсоздать и настроить объект для дальнейшего обхода
RecursiveCallbackFilterIterator::getChildrenполучить рекурсивный итератор дочернего уровня текущего узла
RecursiveCallbackFilterIterator::hasChildrenпроверить, можно ли открыть дочерний уровень текущего узла

RecursiveDirectoryIterator: безопасно обойти собственное дерево файлов

Нужно построить манифест проекта или найти файлы в подкаталогах. Корень задаётся явно, точки пропускаются через SKIP_DOTS, а символические ссылки по умолчанию не превращаются в ветви.

Что происходит во время обхода
  1. Объект читает одну запись текущего каталога.
  2. hasChildren(false) разрешает спуск только в настоящий каталог, не следуя по ссылке.
  3. getChildren() открывает подкаталог; относительные getSubPath/getSubPathname не раскрывают абсолютный корень.

Эта схема показывает значения и переходы именно приведённого примера. Внутри PHP объект хранит служебное состояние, а не нарисованные коробки или стрелки.

DirectoryIterator показывает только один уровень. Здесь явно убраны специальные записи . и .., а вывод отсортирован для повторяемости.

Сначала пройти собственную папку на одном уровнеСамостоятельный пример
<?php
$dir = new DirectoryIterator(__DIR__ . '/fixture');
$names = [];
foreach ($dir as $entry) {
    if (!$entry->isDot()) $names[] = $entry->getFilename();
}
sort($names);
echo implode(', ', $names), "\n";
Ожидаемый результат
docs, root.txt, src

Вложенные api.md и App.php пока не видны: для дерева нужен рекурсивный источник.

Скачать самостоятельный пример с fixtures, результатом и README

RecursiveDirectoryIterator сообщает о дочерних каталогах, а RecursiveIteratorIterator повторяет спуск до файлов.

Пройти всё дерево без точек и символических ссылокСамостоятельный пример
<?php
$flags = FilesystemIterator::SKIP_DOTS;
$root = new RecursiveDirectoryIterator(__DIR__ . '/fixture', $flags);
$flat = new RecursiveIteratorIterator($root, RecursiveIteratorIterator::LEAVES_ONLY);
$paths = [];
foreach ($flat as $file) {
    if ($file->isFile()) $paths[] = str_replace('\\', '/', $flat->getSubPathname());
}
sort($paths);
echo implode("\n", $paths), "\n";
echo 'FOLLOW_SYMLINKS: ', ($flags & FilesystemIterator::FOLLOW_SYMLINKS) ? 'да' : 'нет', "\n";
Ожидаемый результат
docs/api.md
docs/readme.txt
root.txt
src/App.php
FOLLOW_SYMLINKS: нет

SKIP_DOTS убирает . и ... FOLLOW_SYMLINKS намеренно не включён: учебный обход не следует по ссылкам и не рискует попасть в цикл.

Скачать самостоятельный пример с fixtures, результатом и README

Полный справочник методов этого класса:

МетодЗачем открыть карточку
RecursiveDirectoryIterator::__constructсоздать и настроить объект для дальнейшего обхода
RecursiveDirectoryIterator::getChildrenполучить рекурсивный итератор дочернего уровня текущего узла
RecursiveDirectoryIterator::getSubPathполучить относительный путь от корня обхода до текущей подпапки
RecursiveDirectoryIterator::getSubPathnameполучить относительный путь от корня обхода до текущей записи
RecursiveDirectoryIterator::hasChildrenпроверить, можно ли открыть дочерний уровень текущего узла
RecursiveDirectoryIterator::keyполучить ключ или позицию текущего элемента
RecursiveDirectoryIterator::nextперевести курсор к следующему элементу
RecursiveDirectoryIterator::rewindпопытаться установить курсор на первый элемент

RecursiveFilterIterator: именованное правило для всего дерева

Когда условие фильтрации повторяется и заслуживает отдельного теста, его оформляют подклассом с accept(). Родители сохраняются ради пути, а листья проходят предметную проверку.

Что происходит во время обхода
  1. Подкласс получает RecursiveIterator в конструкторе.
  2. accept() читает current/key и отдельно пропускает parent.
  3. getChildren() создаёт тот же класс для дочернего уровня, поэтому конструктор должен оставаться совместимым.

Эта схема показывает значения и переходы именно приведённого примера. Внутри PHP объект хранит служебное состояние, а не нарисованные коробки или стрелки.

Когда правило используется повторно и заслуживает имени, его помещают в подкласс и реализуют accept().

Сформулировать повторяемое правило для дереваСамостоятельный пример
<?php
class PublicConfigFilter extends RecursiveFilterIterator {
    public function accept(): bool {
        return $this->hasChildren() || !str_starts_with((string) $this->key(), '_');
    }
}
$filter = new PublicConfigFilter(new RecursiveArrayIterator([
    'app' => ['name' => 'Store', '_token' => 'secret'],
]));
foreach (new RecursiveIteratorIterator($filter) as $key => $value) echo $key, '=', $value, "\n";
Ожидаемый результат
name=Store

Родитель app остаётся для спуска; служебный _token исключается только на уровне листа.

Скачать самостоятельный пример с fixtures, результатом и README

Второй подкласс хранит бизнес-правило «остаток больше нуля», но всегда пропускает родителей.

Сохранить путь к доступным товарамСамостоятельный пример
<?php
class AvailableFilter extends RecursiveFilterIterator {
    public function accept(): bool {
        return $this->hasChildren() || (int) $this->current() > 0;
    }
}
$filter = new AvailableFilter(new RecursiveArrayIterator([
    'lamps' => ['desk' => 2, 'floor' => 0],
    'cables' => ['usb' => 5],
]));
foreach (new RecursiveIteratorIterator($filter) as $sku => $qty) echo $sku, '=', $qty, "\n";
Ожидаемый результат
desk=2
usb=5

За счёт сохранённых parents обходчик достигает desk и usb; пустой floor отсеивается.

Скачать самостоятельный пример с fixtures, результатом и README

Полный справочник методов этого класса:

МетодЗачем открыть карточку
RecursiveFilterIterator::__constructсоздать и настроить объект для дальнейшего обхода
RecursiveFilterIterator::getChildrenполучить рекурсивный итератор дочернего уровня текущего узла
RecursiveFilterIterator::hasChildrenпроверить, можно ли открыть дочерний уровень текущего узла

RecursiveIteratorIterator: один foreach поверх всей глубины

Нужно превратить вложенную конфигурацию в плоский поток, сохранив глубину и возможность восстановить путь. Сначала показана обычная рекурсивная функция, затем тот же стек ведёт стандартный обходчик.

Что происходит во время обхода
  1. RecursiveIterator сообщает hasChildren()/getChildren().
  2. Обходчик хранит стек активных уровней и выбранный порядок LEAVES_ONLY, SELF_FIRST или CHILD_FIRST.
  3. foreach получает очередной узел; getDepth/getSubIterator позволяют восстановить его положение.

Эта схема показывает значения и переходы именно приведённого примера. Внутри PHP объект хранит служебное состояние, а не нарисованные коробки или стрелки.

Обычная функция показывает рекурсию без SPL: для массива она вызывает себя, для листа печатает путь и значение.

Сначала развернуть конфигурацию обычной рекурсивной функциейСамостоятельный пример
<?php
$config = ['app' => ['cache' => ['driver' => 'file'], 'debug' => true], 'version' => '1'];
function flatten(array $items, string $prefix = ''): void {
    foreach ($items as $key => $value) {
        $path = $prefix === '' ? (string) $key : $prefix . '.' . $key;
        if (is_array($value)) flatten($value, $path);
        else echo $path, '=', var_export($value, true), "\n";
    }
}
flatten($config);
Ожидаемый результат
app.cache.driver='file'
app.debug=true
version='1'

Преимущество модели — полный контроль над путём. Цена — свой код стека, остановки и обработки разных источников.

Скачать самостоятельный пример с fixtures, результатом и README

RecursiveIteratorIterator повторяет hasChildren/getChildren до листа и отдаёт плоский foreach.

Развернуть ту же конфигурацию одним foreachСамостоятельный пример
<?php
$flat = new RecursiveIteratorIterator(
    new RecursiveArrayIterator(['app' => ['cache' => ['driver' => 'file'], 'debug' => true], 'version' => '1']),
    RecursiveIteratorIterator::LEAVES_ONLY
);
foreach ($flat as $key => $value) {
    $parts = [];
    for ($level = 0; $level < $flat->getDepth(); $level++) {
        $parts[] = (string) $flat->getSubIterator($level)->key();
    }
    $parts[] = (string) $key;
    echo implode('.', $parts), '=', var_export($value, true), "\n";
}
Ожидаемый результат
app.cache.driver='file'
app.debug=true
version='1'

Путь не появляется автоматически: пример собирает его из активных подытераторов. Это реальный стек текущей ветви, а не копия всего дерева.

Скачать самостоятельный пример с fixtures, результатом и README

Полный справочник методов этого класса:

МетодЗачем открыть карточку
RecursiveIteratorIterator::beginChildrenвыполнить hook перед входом в очередной набор дочерних узлов
RecursiveIteratorIterator::beginIterationвыполнить hook один раз перед началом рекурсивного обхода
RecursiveIteratorIterator::callGetChildrenвызвать getChildren() текущего рекурсивного источника через обходчик
RecursiveIteratorIterator::callHasChildrenспросить текущий рекурсивный источник, есть ли у узла дети
RecursiveIteratorIterator::__constructсоздать и настроить объект для дальнейшего обхода
RecursiveIteratorIterator::currentполучить текущее значение без продвижения курсора
RecursiveIteratorIterator::endChildrenвыполнить hook после выхода из очередного набора детей
RecursiveIteratorIterator::endIterationвыполнить hook один раз после завершения рекурсивного обхода
RecursiveIteratorIterator::getDepthполучить текущую глубину плоского рекурсивного обхода
RecursiveIteratorIterator::getInnerIteratorполучить непосредственно обёрнутый итератор текущего уровня
RecursiveIteratorIterator::getMaxDepthпрочитать установленное ограничение глубины обхода
RecursiveIteratorIterator::getSubIteratorполучить активный рекурсивный итератор на выбранном уровне
RecursiveIteratorIterator::keyполучить ключ или позицию текущего элемента
RecursiveIteratorIterator::nextперевести курсор к следующему элементу
RecursiveIteratorIterator::nextElementвыполнить hook при готовности очередного элемента рекурсивного обхода
RecursiveIteratorIterator::rewindпопытаться установить курсор на первый элемент
RecursiveIteratorIterator::setMaxDepthограничить максимальную глубину рекурсивного обхода
RecursiveIteratorIterator::validпроверить, указывает ли курсор на существующий элемент

RecursiveRegexIterator: регулярное выражение на каждом уровне

Нужно выбрать ключи известного строкового формата во вложенном массиве. Pattern должен принимать и нужные листья, и их родителей, иначе путь исчезнет до достижения совпадения.

Что происходит во время обхода
  1. RegexIterator сопоставляет current или key согласно flags.
  2. Совпавший parent остаётся доступным для hasChildren().
  3. getChildren() переносит pattern, mode и pregFlags на следующий уровень.

Эта схема показывает значения и переходы именно приведённого примера. Внутри PHP объект хранит служебное состояние, а не нарисованные коробки или стрелки.

Обычный foreach первым показывает условие: регулярное выражение применяется к ключу листа.

Сначала выбрать ключи обычной проверкойСамостоятельный пример
<?php
$config = ['services' => ['cache' => 'redis', 'password' => 'secret']];
foreach ($config['services'] as $key => $value) {
    if (preg_match('/^(cache|timeout)$/', $key)) echo $key, '=', $value, "\n";
}
Ожидаемый результат
cache=redis

В дереве нельзя забыть родителя services, иначе рекурсивный фильтр не войдёт внутрь.

Скачать самостоятельный пример с fixtures, результатом и README

USE_KEY направляет regex на ключи. Шаблон принимает и parent services, и нужные листья cache/timeout.

Сохранить родителя и отобрать ключи регулярным выражениемСамостоятельный пример
<?php
$source = new RecursiveArrayIterator([
    'services' => ['cache' => 'redis', 'timeout' => '30', 'password' => 'secret'],
]);
$filter = new RecursiveRegexIterator(
    $source,
    '/^(services|cache|timeout)$/',
    RecursiveRegexIterator::MATCH,
    RecursiveRegexIterator::USE_KEY
);
foreach (new RecursiveIteratorIterator($filter) as $key => $value) echo $key, '=', $value, "\n";
Ожидаемый результат
cache=redis
timeout=30

password не совпадает. Регулярное выражение выбирает строки, но не проверяет тип или допустимость самих значений.

Скачать самостоятельный пример с fixtures, результатом и README

Полный справочник методов этого класса:

МетодЗачем открыть карточку
RecursiveRegexIterator::__constructсоздать и настроить объект для дальнейшего обхода
RecursiveRegexIterator::getChildrenполучить рекурсивный итератор дочернего уровня текущего узла
RecursiveRegexIterator::hasChildrenпроверить, можно ли открыть дочерний уровень текущего узла

RecursiveTreeIterator: линии дерева как представление

Нужно показать структуру человеку в журнале или CLI. Класс строит prefix/entry/postfix из текущей позиции RecursiveIteratorIterator; линии помогают читать результат, но не становятся частью исходных данных.

Что происходит во время обхода
  1. Рекурсивный обходчик выбирает очередной узел и знает соседей.
  2. Кэширующий слой определяет, продолжать ли вертикальную линию.
  3. current() соединяет prefix, entry и postfix; BYPASS-флаги оставляют программный key или current исходным.

Эта схема показывает значения и переходы именно приведённого примера. Внутри PHP объект хранит служебное состояние, а не нарисованные коробки или стрелки.

Обычная функция первой показывает смысл: напечатать узел и увеличить отступ только при входе в массив.

Сначала нарисовать дерево обычной рекурсивной функциейСамостоятельный пример
<?php
$menu = ['shop' => ['catalog' => ['lamp' => '2'], 'cart' => '0'], 'status' => 'open'];
function draw(array $nodes, string $indent = ''): void {
    foreach ($nodes as $key => $value) {
        echo $indent, $key, is_array($value) ? '/' : '=' . $value, "\n";
        if (is_array($value)) draw($value, $indent . '  ');
    }
}
draw($menu);
Ожидаемый результат
shop/
  catalog/
    lamp=2
  cart=0
status=open

Линии здесь являются представлением. Они не изменяют ключи и не становятся частью исходных данных.

Скачать самостоятельный пример с fixtures, результатом и README

RecursiveTreeIterator использует сведения о соседях на каждом уровне и добавляет к current() префикс ветвей.

Получить ветви автоматически через RecursiveTreeIteratorСамостоятельный пример
<?php
$tree = new RecursiveTreeIterator(
    new RecursiveArrayIterator(['shop' => ['catalog' => ['lamp' => '2'], 'cart' => '0'], 'status' => 'open']),
    RecursiveTreeIterator::BYPASS_KEY,
    CachingIterator::CATCH_GET_CHILD,
    RecursiveTreeIterator::LEAVES_ONLY
);
foreach ($tree as $key => $decorated) echo $key, ':', $decorated, "\n";
Ожидаемый результат
lamp:| | \-2
cart:| \-0
status:\-open

В LEAVES_ONLY выведены только значения-листья. Префикс объясняет положение, но не содержит имён родителей; путь собирают отдельно из ключей стека.

Скачать самостоятельный пример с fixtures, результатом и README

Полный справочник методов этого класса:

МетодЗачем открыть карточку
RecursiveTreeIterator::beginChildrenвыполнить hook перед входом в очередной набор дочерних узлов
RecursiveTreeIterator::beginIterationвыполнить hook один раз перед началом рекурсивного обхода
RecursiveTreeIterator::callGetChildrenвызвать getChildren() текущего рекурсивного источника через обходчик
RecursiveTreeIterator::callHasChildrenспросить текущий рекурсивный источник, есть ли у узла дети
RecursiveTreeIterator::__constructсоздать и настроить объект для дальнейшего обхода
RecursiveTreeIterator::currentполучить текущее значение без продвижения курсора
RecursiveTreeIterator::endChildrenвыполнить hook после выхода из очередного набора детей
RecursiveTreeIterator::endIterationвыполнить hook один раз после завершения рекурсивного обхода
RecursiveTreeIterator::getEntryполучить строковое представление текущего исходного узла без нарисованного префикса
RecursiveTreeIterator::getPostfixполучить строку, добавляемую после текущего узла дерева
RecursiveTreeIterator::getPrefixполучить уже собранный префикс ветви для текущего узла
RecursiveTreeIterator::keyполучить ключ или позицию текущего элемента
RecursiveTreeIterator::nextперевести курсор к следующему элементу
RecursiveTreeIterator::nextElementвыполнить hook при готовности очередного элемента рекурсивного обхода
RecursiveTreeIterator::rewindпопытаться установить курсор на первый элемент
RecursiveTreeIterator::setPostfixзадать строку после каждого узла текстового дерева
RecursiveTreeIterator::setPrefixPartзаменить выбранную часть префикса текстового дерева
RecursiveTreeIterator::validпроверить, указывает ли курсор на существующий элемент

DirectoryIterator: одна папка как курсор

Нужно увидеть записи одной локальной папки и для каждой безопасно получить имя, расширение и тип, не загружая всё дерево в массив.

Что происходит во время обхода
  1. new DirectoryIterator(path) открывает существующую папку
  2. курсор по очереди указывает на ., .. и реальные записи
  3. valid() разрешает чтение, current()/key() дают запись и позицию
  4. next() двигает курсор, rewind()/seek() меняют его позицию

Эта схема показывает значения и переходы именно приведённого примера. Внутри PHP объект хранит служебное состояние, а не нарисованные коробки или стрелки.

Нужно построить локальный индекс вложений каталога, не заходя в подпапку sub. Порядок файловой системы заранее неизвестен, поэтому результат явно сортируется по имени.

Собрать предсказуемый список файлов одной папкиСамостоятельный пример
<?php
declare(strict_types=1);

$directory = new DirectoryIterator(__DIR__ . '/fixtures/catalog');
$rows = [];
$directory->rewind();
while ($directory->valid()) {
    if (!$directory->isDot()) {
        $entry = $directory->current();
        $filename = $entry->getFilename();
        $basename = $entry->getBasename();
        if ($filename !== $basename) {
            throw new RuntimeException('Unexpected basename');
        }
        $rows[] = [
            $filename,
            $entry->getExtension(),
            $entry->isDir() ? 'dir' : 'file',
        ];
    }
    $directory->next();
}
usort($rows, fn(array $left, array $right): int => $left[0] <=> $right[0]);
foreach ($rows as [$name, $extension, $type]) {
    echo $name, '|', $extension, '|', $type, "\n";
}
Ожидаемый результат
.env|env|file
README||file
photo.final.jpg|jpg|file
report.csv|csv|file
sub||dir

Конструктор открыл одну папку. На каждой допустимой позиции current() вернул тот же объект DirectoryIterator с данными текущей записи; getFilename()/getBasename()/getExtension() выделили части имени. У .env расширением считается env. Каталог sub виден как запись, но его содержимое не обходилось.

Скачать самостоятельный пример с fixtures, результатом и README

При чтении папки нужно пропустить специальные переходы «эта папка» и «родительская папка», но оставить реальный конфигурационный файл с точкой в начале имени.

Отличить служебные точки от файла .envСамостоятельный пример
<?php
declare(strict_types=1);

$directory = new DirectoryIterator(__DIR__ . '/fixtures/dots');
$dotEntries = 0;
$ordinaryNames = [];
foreach ($directory as $entry) {
    if ($entry->isDot()) {
        $dotEntries++;
        continue;
    }
    $ordinaryNames[] = $entry->getFilename();
}
sort($ordinaryNames);
echo 'dotEntries=', $dotEntries, "\n";
echo 'ordinary=', implode(',', $ordinaryNames), "\n";
Ожидаемый результат
dotEntries=2
ordinary=.env,public.txt

isDot() вернул true только для записей . и ... Файл .env начинается с точки, но является обычной записью и не был потерян. Поэтому проверка имени на первый символ была бы ошибочной.

Скачать самостоятельный пример с fixtures, результатом и README

Инструмент диагностики должен вручную поставить курсор на известный файл, прочитать запись и понять, когда элементы закончились.

Найти запись, прочитать current() и увидеть конец курсораСамостоятельный пример
<?php
declare(strict_types=1);

$directory = new DirectoryIterator(__DIR__ . '/fixtures/one');
$filePosition = null;
foreach ($directory as $position => $entry) {
    if ($entry->getFilename() === 'only.txt') {
        $filePosition = $position;
        break;
    }
}
if (!is_int($filePosition)) {
    throw new RuntimeException('Fixture not found');
}
$directory->seek($filePosition);
$current = $directory->current();
echo 'keyIsInt=', is_int($directory->key()) ? 'yes' : 'no', "\n";
echo 'class=', $current::class, "\n";
echo 'sameObject=', $current === $directory ? 'yes' : 'no', "\n";
echo 'name=', (string) $current, "\n";
$directory->next();
echo 'afterFileValid=', $directory->valid() ? 'yes' : 'no', "\n";
$directory->rewind();
echo 'rewindIsDot=', $directory->isDot() ? 'yes' : 'no', "\n";
Ожидаемый результат
keyIsInt=yes
class=DirectoryIterator
sameObject=yes
name=only.txt
afterFileValid=no
rewindIsDot=yes

Сначала имя было найдено без предположения о позиции. seek() вернул тот же курсор к сохранённому целочисленному месту. current() не создал независимую копию: он вернул сам DirectoryIterator в состоянии only.txt. После next() valid() стал false; rewind() вернул позицию 0 — служебную точку.

Скачать самостоятельный пример с fixtures, результатом и README

Полный справочник методов этого класса:

МетодЗачем открыть карточку
DirectoryIterator::__constructсоздать и настроить объект для дальнейшего обхода
DirectoryIterator::currentполучить текущее значение без продвижения курсора
DirectoryIterator::getBasenameполучить имя текущей записи без пути и, при необходимости, без указанного суффикса
DirectoryIterator::getExtensionполучить расширение имени текущей записи без ведущей точки
DirectoryIterator::getFilenameполучить только имя текущей записи без родительского пути
DirectoryIterator::isDotраспознать специальные записи текущей и родительской папки
DirectoryIterator::keyполучить ключ или позицию текущего элемента
DirectoryIterator::nextперевести курсор к следующему элементу
DirectoryIterator::rewindпопытаться установить курсор на первый элемент
DirectoryIterator::seekперейти к заданной позиции обхода
DirectoryIterator::__toStringполучить строковое представление текущего элемента
DirectoryIterator::validпроверить, указывает ли курсор на существующий элемент

FilesystemIterator: выбрать форму ключа и текущего значения

Один потребитель хочет короткие имена, другой — полные пути, третий — SplFileInfo с размером. Требуется задать этот договор до цикла.

Что происходит во время обхода
  1. KEY_AS_FILENAME или KEY_AS_PATHNAME задаёт форму key()
  2. CURRENT_AS_PATHNAME, CURRENT_AS_FILEINFO или CURRENT_AS_SELF задаёт current()
  3. SKIP_DOTS независимо убирает только . и ..
  4. setFlags() заменяет полную маску, поэтому нужные группы собирают заново

Эта схема показывает значения и переходы именно приведённого примера. Внутри PHP объект хранит служебное состояние, а не нарисованные коробки или стрелки.

Шаблонизатору нужен короткий ключ для подписи и полный путь-строка для передачи функции чтения файла.

Получить имя-ключ и строку полного путиСамостоятельный пример
<?php
declare(strict_types=1);

$flags = FilesystemIterator::KEY_AS_FILENAME
    | FilesystemIterator::CURRENT_AS_PATHNAME
    | FilesystemIterator::SKIP_DOTS;
$iterator = new FilesystemIterator(__DIR__ . '/fixtures/storage', $flags);
$rows = [];
foreach ($iterator as $key => $current) {
    $rows[] = $key . '|current=' . get_debug_type($current)
        . '|basename=' . basename($current);
}
sort($rows);
echo implode("\n", $rows), "\n";
Ожидаемый результат
.env|current=string|basename=.env
a.txt|current=string|basename=a.txt
b.log|current=string|basename=b.log
data|current=string|basename=data

KEY_AS_FILENAME сделал ключом только имя, CURRENT_AS_PATHNAME сделал текущим значением строку пути. Флаги из разных групп объединены оператором |; SKIP_DOTS убрал только . и ...

Скачать самостоятельный пример с fixtures, результатом и README

Перед отправкой файлов нужно узнать их размер, не открывая содержимое.

Читать размер через объекты SplFileInfoСамостоятельный пример
<?php
declare(strict_types=1);

$flags = FilesystemIterator::KEY_AS_FILENAME
    | FilesystemIterator::CURRENT_AS_FILEINFO
    | FilesystemIterator::SKIP_DOTS;
$iterator = new FilesystemIterator(__DIR__ . '/fixtures/files', $flags);
$rows = [];
foreach ($iterator as $name => $file) {
    if ($file->isFile()) {
        $rows[] = $name . '|class=' . $file::class . '|bytes=' . $file->getSize();
    }
}
sort($rows);
echo implode("\n", $rows), "\n";
Ожидаемый результат
a.txt|class=SplFileInfo|bytes=3
b.log|class=SplFileInfo|bytes=5

CURRENT_AS_FILEINFO вернул для каждой позиции SplFileInfo. Объект дал isFile() и getSize(); значение 0 этой константы проверяют сравнением маски режима, а не условием if ($flags & CURRENT_AS_FILEINFO).

Скачать самостоятельный пример с fixtures, результатом и README

Код меняет форму current(), но должен понимать, почему после небрежной смены режима внезапно появились . и ...

Показать, что setFlags() заменяет маску целикомСамостоятельный пример
<?php
declare(strict_types=1);

$initial = FilesystemIterator::KEY_AS_FILENAME
    | FilesystemIterator::CURRENT_AS_PATHNAME
    | FilesystemIterator::SKIP_DOTS;
$iterator = new FilesystemIterator(__DIR__ . '/fixtures/flags', $initial);
echo 'initialSkip=', ($iterator->getFlags() & FilesystemIterator::SKIP_DOTS) !== 0 ? 'yes' : 'no', "\n";

$iterator->setFlags(
    FilesystemIterator::KEY_AS_FILENAME
    | FilesystemIterator::CURRENT_AS_PATHNAME
);
echo 'afterReplaceSkip=', ($iterator->getFlags() & FilesystemIterator::SKIP_DOTS) !== 0 ? 'yes' : 'no', "\n";
$dotEntries = 0;
foreach ($iterator as $entry) {
    if ($iterator->isDot()) {
        $dotEntries++;
    }
}
echo 'dotEntries=', $dotEntries, "\n";

$iterator->setFlags(
    FilesystemIterator::KEY_AS_FILENAME
    | FilesystemIterator::CURRENT_AS_FILEINFO
    | FilesystemIterator::SKIP_DOTS
);
$mode = $iterator->getFlags() & FilesystemIterator::CURRENT_MODE_MASK;
echo 'fileInfoMode=', $mode === FilesystemIterator::CURRENT_AS_FILEINFO ? 'yes' : 'no', "\n";
Ожидаемый результат
initialSkip=yes
afterReplaceSkip=no
dotEntries=2
fileInfoMode=yes

Первый setFlags() получил новую полную маску без SKIP_DOTS, поэтому служебные точки вернулись. Второй вызов явно собрал все требуемые группы. CURRENT_AS_FILEINFO равен 0, поэтому текущий режим извлечён через CURRENT_MODE_MASK и проверен строгим равенством.

Скачать самостоятельный пример с fixtures, результатом и README

Сканер конфигурации должен пропустить переходы . и .., но прочитать реальный файл .env.

Не потерять .env при включённом SKIP_DOTSСамостоятельный пример
<?php
declare(strict_types=1);

$flags = FilesystemIterator::KEY_AS_FILENAME
    | FilesystemIterator::CURRENT_AS_FILEINFO
    | FilesystemIterator::SKIP_DOTS;
$iterator = new FilesystemIterator(__DIR__ . '/fixtures/hidden', $flags);
$names = [];
$dotEntries = 0;
$iterator->rewind();
while ($iterator->valid()) {
    $names[] = $iterator->key();
    $dotEntries += $iterator->isDot() ? 1 : 0;
    $iterator->next();
}
sort($names);
echo 'names=', implode(',', $names), "\n";
echo 'serviceDotEntries=', $dotEntries, "\n";
Ожидаемый результат
names=.env,public.txt
serviceDotEntries=0

SKIP_DOTS относится только к двум служебным записям. Он не является фильтром скрытых или начинающихся с точки файлов: .env остался в результате. Для отдельной политики скрытых файлов проверяйте имя самостоятельно.

Скачать самостоятельный пример с fixtures, результатом и README

Полный справочник методов этого класса:

МетодЗачем открыть карточку
FilesystemIterator::__constructсоздать и настроить объект для дальнейшего обхода
FilesystemIterator::currentполучить текущее значение без продвижения курсора
FilesystemIterator::getFlagsпрочитать действующую битовую маску режима объекта
FilesystemIterator::keyполучить ключ или позицию текущего элемента
FilesystemIterator::nextперевести курсор к следующему элементу
FilesystemIterator::rewindпопытаться установить курсор на первый элемент
FilesystemIterator::setFlagsзаменить действующую битовую маску режима

GlobIterator: файловая маска и число совпадений

В одной известной папке нужно взять только файлы с подходящими именами — например JPG для превью или CSV за выбранный месяц.

Что происходит во время обхода
  1. pattern содержит путь и glob-маску имени
  2. конструктор вычисляет совпавшие записи одного уровня
  3. count() сообщает число совпадений до или после foreach
  4. итерация возвращает формы key/current, выбранные флагами FilesystemIterator

Эта схема показывает значения и переходы именно приведённого примера. Внутри PHP объект хранит служебное состояние, а не нарисованные коробки или стрелки.

Генератор превью должен взять только JPG непосредственно из uploads и не читать notes.txt или вложенную папку.

Выбрать только JPG текущей папкиСамостоятельный пример
<?php
declare(strict_types=1);

$pattern = __DIR__ . '/fixtures/uploads/*.jpg';
$iterator = new GlobIterator($pattern, FilesystemIterator::KEY_AS_FILENAME);
$names = [];
foreach ($iterator as $name => $file) {
    $names[] = $name;
}
sort($names);
echo 'matched=', $iterator->count(), "\n";
echo 'names=', implode(',', $names), "\n";
echo 'nestedIncluded=', in_array('deep.jpg', $names, true) ? 'yes' : 'no', "\n";
Ожидаемый результат
matched=2
names=hero.jpg,thumb.jpg
nestedIncluded=no

Шаблон *.jpg сопоставился с двумя именами одного уровня. count() вернул число совпавших путей. GlobIterator не выполняет рекурсивный поиск: sub/deep.jpg не попал в список.

Скачать самостоятельный пример с fixtures, результатом и README

Архиватор ищет файлы выбранного года, у которых после дефиса ровно два символа месяца.

Отобрать резервные копии с двухзначным месяцемСамостоятельный пример
<?php
declare(strict_types=1);

$pattern = __DIR__ . '/fixtures/backups/report-2026-??.csv';
$iterator = new GlobIterator($pattern, FilesystemIterator::KEY_AS_FILENAME);
$names = [];
foreach ($iterator as $name => $file) {
    $names[] = $name;
}
sort($names);
echo 'matched=', count($iterator), "\n";
echo implode("\n", $names), "\n";
Ожидаемый результат
matched=2
report-2026-01.csv
report-2026-10.csv

Каждый знак ? в glob-шаблоне соответствует одному символу имени. Поэтому два цифровых по факту имени совпали, а report-2026-final.csv и файл другого года — нет. Маска не проверяет, что символы являются цифрами; строгую проверку можно добавить после отбора.

Скачать самостоятельный пример с fixtures, результатом и README

Папка существует, но сегодня XML-файлов нет. Это нормальный пустой результат, а не повод падать.

Отличить ноль совпадений от ошибки конструктораСамостоятельный пример
<?php
declare(strict_types=1);

$iterator = new GlobIterator(
    __DIR__ . '/fixtures/documents/*.xml',
    FilesystemIterator::KEY_AS_FILENAME
);
$iterations = 0;
foreach ($iterator as $file) {
    $iterations++;
}
echo 'matched=', $iterator->count(), "\n";
echo 'iterations=', $iterations, "\n";
Ожидаемый результат
matched=0
iterations=0

Конструктор создал допустимый GlobIterator. count() вернул 0, foreach не выполнил тело ни разу. Отсутствующий каталог и пустой результат маски — разные состояния, их не следует объединять в одно сообщение.

Скачать самостоятельный пример с fixtures, результатом и README

Полный справочник методов этого класса:

МетодЗачем открыть карточку
GlobIterator::__constructсоздать и настроить объект для дальнейшего обхода
GlobIterator::countполучить число элементов, которое определяет этот класс

Файлы в SPL: сначала одна полезная строка

Задача начинается не с перечня методов. Есть сохранённая квитанция, и программе нужно показать её заголовок. Для этого достаточно пути, объекта открытого файла и одного чтения. Результат ниже можно увидеть сразу.

Что происходит с input/receipt.txt
  1. $path получает строку …/input/receipt.txt.
  2. new SplFileObject($path, "rb") просит ОС открыть именно этот путь для чтения.
  3. $file->fgets() двигает позицию после первой строки и возвращает "Заказ 42\n".
  4. rtrim даёт подпись "Заказ 42"; echo показывает её человеку.
Открыть квитанцию и получить первую строкуСамостоятельный пример
<?php
declare(strict_types=1);

$path = __DIR__ . '/input/receipt.txt';
$file = new SplFileObject($path, 'rb');
$line = $file->fgets();

echo 'Первая строка: ' . rtrim($line, "\r\n") . "\n";
Ожидаемый результат
Первая строка: Заказ 42

$path хранит путь. new SplFileObject(...) открывает файл; rb означает чтение байтов без записи. Стрелка -> вызывает метод fgets() у этого объекта. Метод возвращает одну строку вместе с её переносом; rtrim убирает только CR/LF для аккуратной подписи. Полный текст при этом не загружается в массив.

Если нужно только имя и свойства пути, используйте SplFileInfo::__construct. Если нужно читать или писать содержимое, нужен SplFileObject::__construct. Для временного результата без постоянного имени — SplTempFileObject::__construct.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

File Handling

Table of Contents SplFileInfo SplFileObject SplTempFileObject

SPL provides a number of classes to work with files.

SplFileInfo: карточка пути без автоматического чтения

SplFileInfo хранит путь и даёт операции над его именем и метаданными. Создание объекта не читает квитанцию и не создаёт отсутствующий файл. Это удобно, когда каталог нужно показать, отфильтровать или проверить до отдельной попытки открытия.

Группа действийЧто получает программа
Имя и расположениеSplFileInfo::getFilename, SplFileInfo::getPath, SplFileInfo::getRealPath.
Тип и доступSplFileInfo::isFile, SplFileInfo::isDir, SplFileInfo::isLink, readable/writable/executable.
МетаданныеSplFileInfo::getSize, времена, owner/group, inode и режим прав.
Переход к содержимомуSplFileInfo::openFile возвращает уже открытый SplFileObject.
Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

The SplFileInfo class

(PHP 5 >= 5.1.2, PHP 7, PHP 8)

Introduction

The SplFileInfo class offers a high-level object-oriented interface to information for an individual file.

Class synopsis

class SplFileInfo

implements Stringable {

/* Methods */

public function __construct(string $filename)

public function getATime(): int|false

public function getBasename(string $suffix = ""): string

public function getCTime(): int|false

public function getExtension(): string

public function getFileInfo(?string $class = null): SplFileInfo

public function getFilename(): string

public function getGroup(): int|false

public function getInode(): int|false

public function getLinkTarget(): string|false

public function getMTime(): int|false

public function getOwner(): int|false

public function getPath(): string

public function getPathInfo(?string $class = null): ?SplFileInfo

public function getPathname(): string

public function getPerms(): int|false

public function getRealPath(): string|false

public function getSize(): int|false

public function getType(): string|false

public function isDir(): bool

public function isExecutable(): bool

public function isFile(): bool

public function isLink(): bool

public function isReadable(): bool

public function isWritable(): bool

public function openFile(string $mode = "r", bool $useIncludePath = false, ?resource $context = null): SplFileObject

public function setFileClass(string $class = SplFileObject::class): void

public function setInfoClass(string $class = SplFileInfo::class): void

public function __toString(): string

}

Changelog

Version Description

8.0.0

SplFileInfo implements Stringable now.

Table of Contents SplFileInfo::__construct — Construct a new SplFileInfo object SplFileInfo::getATime — Gets last access time of the file SplFileInfo::getBasename — Gets the base name of the file SplFileInfo::getCTime — Gets the inode change time SplFileInfo::getExtension — Gets the file extension SplFileInfo::getFileInfo — Gets an SplFileInfo object for the file SplFileInfo::getFilename — Gets the filename SplFileInfo::getGroup — Gets the file group SplFileInfo::getInode — Gets the inode for the file SplFileInfo::getLinkTarget — Gets the target of a link SplFileInfo::getMTime — Gets the last modified time SplFileInfo::getOwner — Gets the owner of the file SplFileInfo::getPath — Gets the path without filename SplFileInfo::getPathInfo — Gets an SplFileInfo object for the path SplFileInfo::getPathname — Gets the path to the file SplFileInfo::getPerms — Gets file permissions SplFileInfo::getRealPath — Gets absolute path to file SplFileInfo::getSize — Gets file size SplFileInfo::getType — Gets file type SplFileInfo::isDir — Tells if the file is a directory SplFileInfo::isExecutable — Tells if the file is executable SplFileInfo::isFile — Tells if the object references a regular file SplFileInfo::isLink — Tells if the file is a link SplFileInfo::isReadable — Tells if file is readable SplFileInfo::isWritable — Tells if the entry is writable SplFileInfo::openFile — Gets an SplFileObject object for the file SplFileInfo::setFileClass — Sets the class used with SplFileInfo::openFile SplFileInfo::setInfoClass — Sets the class used with SplFileInfo::getFileInfo and SplFileInfo::getPathInfo SplFileInfo::__toString — Returns the path to the file as a string

SplFileObject: открытый поток, строковый итератор и позиция

SplFileObject наследует сведения пути у SplFileInfo и добавляет открытый файловый поток. Один объект хранит текущую позицию: fgets, fread, next и seek меняют то, что будет прочитано дальше. Поэтому два вызова подряд обычно возвращают разные части файла.

Иерархия и обязанности
  1. SplFileInfo — путь, имя, тип и метаданные.
  2. SplFileObject extends SplFileInfo — тот же путь плюс открытый поток, позиция и чтение/запись.
  3. SplTempFileObject extends SplFileObject — поток без постоянного пользовательского имени, с порогом памяти.
Поле fstatПрактический смысл и граница
dev / inoУстройство и идентификатор файлового объекта. Пара полезна для локального поиска повторов; не вечный глобальный ID.
modeТип записи и биты прав. На Windows не заменяет ACL. Для rwx-маски используют $mode & 0777.
nlinkКоличество жёстких ссылок на объект, если файловая система сообщает поле.
uid / gidЧисловой владелец и группа. На Windows обычно не описывают реальную ACL.
sizeРазмер содержимого в байтах, а не в символах UTF-8.
atime / mtime / ctimeДоступ, изменение содержимого и изменение inode; на Windows значение ctime трактуется иначе.
blksize / blocksПредпочтительный размер ввода-вывода и занятые блоки; на Windows могут быть −1.

Метод SplFileObject::fstat возвращает оба числовых и строковых ключа. В примерах читаются строковые ключи, чтобы код было легче понять. Флаги SplFileObject::setFlags управляют именно итерацией; прямой fgets() не превращается из-за них в CSV-парсер.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

The SplFileObject class

(PHP 5 >= 5.1.0, PHP 7, PHP 8)

Introduction

The SplFileObject class offers an object-oriented interface for a file.

Class synopsis

class SplFileObject

extends SplFileInfo

implements RecursiveIterator,

SeekableIterator {

/* Constants */

public const int DROP_NEW_LINE;

public const int READ_AHEAD;

public const int SKIP_EMPTY;

public const int READ_CSV;

/* Methods */

public function __construct(    string $filename,    string $mode = "r",    bool $useIncludePath = false,    ?resource $context = null)

public function current(): string|array|false

public function eof(): bool

public function fflush(): bool

public function fgetc(): string|false

public function fgetcsv(string $separator = ",", string $enclosure = "\"", string $escape = "\\"): array|false

public function fgets(): string

public function fgetss(string $allowable_tags = ?): string

public function flock(int $operation, int &$wouldBlock = null): bool

public function fpassthru(): int

public function fputcsv(    array $fields,    string $separator = ",",    string $enclosure = "\"",    string $escape = "\\",    string $eol = "\n"): int|false

public function fread(int $length): string|false

public function fscanf(string $format, mixed &...$vars): array|int|null

public function fseek(int $offset, int $whence = SEEK_SET): int

public function fstat(): array

public function ftell(): int|false

public function ftruncate(int $size): bool

public function fwrite(string $data, ?int $length = null): int|false

public function getChildren(): null

public function getCsvControl(): array

public function getFlags(): int

public function getMaxLineLen(): int

public function hasChildren(): false

public function key(): int

public function next(): void

public function rewind(): void

public function seek(int $line): void

public function setCsvControl(string $separator = ",", string $enclosure = "\"", string $escape = "\\"): void

public function setFlags(int $flags): void

public function setMaxLineLen(int $maxLength): void

public function __toString(): string

public function valid(): bool

/* Inherited methods */

public function SplFileInfo::getATime(): int|false

public function SplFileInfo::getBasename(string $suffix = ""): string

public function SplFileInfo::getCTime(): int|false

public function SplFileInfo::getExtension(): string

public function SplFileInfo::getFileInfo(?string $class = null): SplFileInfo

public function SplFileInfo::getFilename(): string

public function SplFileInfo::getGroup(): int|false

public function SplFileInfo::getInode(): int|false

public function SplFileInfo::getLinkTarget(): string|false

public function SplFileInfo::getMTime(): int|false

public function SplFileInfo::getOwner(): int|false

public function SplFileInfo::getPath(): string

public function SplFileInfo::getPathInfo(?string $class = null): ?SplFileInfo

public function SplFileInfo::getPathname(): string

public function SplFileInfo::getPerms(): int|false

public function SplFileInfo::getRealPath(): string|false

public function SplFileInfo::getSize(): int|false

public function SplFileInfo::getType(): string|false

public function SplFileInfo::isDir(): bool

public function SplFileInfo::isExecutable(): bool

public function SplFileInfo::isFile(): bool

public function SplFileInfo::isLink(): bool

public function SplFileInfo::isReadable(): bool

public function SplFileInfo::isWritable(): bool

public function SplFileInfo::openFile(string $mode = "r", bool $useIncludePath = false, ?resource $context = null): SplFileObject

public function SplFileInfo::setFileClass(string $class = SplFileObject::class): void

public function SplFileInfo::setInfoClass(string $class = SplFileInfo::class): void

public function SplFileInfo::__toString(): string

}

Predefined Constants

SplFileObject::DROP_NEW_LINE

Drop newlines at the end of a line.

SplFileObject::READ_AHEAD

Read on rewind/next.

SplFileObject::SKIP_EMPTY

Skips empty lines in the file. This requires the READ_AHEAD flag be enabled, to work as expected.

SplFileObject::READ_CSV

Read lines as CSV rows.

Changelog

Version Description

8.4.0

The class constants are now typed.

Table of Contents SplFileObject::__construct — Construct a new file object SplFileObject::current — Retrieve current line of file SplFileObject::eof — Reached end of file SplFileObject::fflush — Flushes the output to the file SplFileObject::fgetc — Gets character from file SplFileObject::fgetcsv — Gets line from file and parse as CSV fields SplFileObject::fgets — Gets line from file SplFileObject::fgetss — Gets line from file and strip HTML tags SplFileObject::flock — Portable file locking SplFileObject::fpassthru — Output all remaining data on a file pointer SplFileObject::fputcsv — Write a field array as a CSV line SplFileObject::fread — Read from file SplFileObject::fscanf — Parses input from file according to a format SplFileObject::fseek — Seek to a position SplFileObject::fstat — Gets information about the file SplFileObject::ftell — Return current file position SplFileObject::ftruncate — Truncates the file to a given length SplFileObject::fwrite — Write to file SplFileObject::getChildren — No purpose SplFileObject::getCsvControl — Get the delimiter, enclosure and escape character for CSV SplFileObject::getCurrentLine — Alias of SplFileObject::fgets SplFileObject::getFlags — Gets flags for the SplFileObject SplFileObject::getMaxLineLen — Get maximum line length SplFileObject::hasChildren — SplFileObject does not have children SplFileObject::key — Get line number SplFileObject::next — Read next line SplFileObject::rewind — Rewind the file to the first line SplFileObject::seek — Seek to specified line SplFileObject::setCsvControl — Set the delimiter, enclosure and escape character for CSV SplFileObject::setFlags — Sets flags for the SplFileObject SplFileObject::setMaxLineLen — Set maximum line length SplFileObject::__toString — Returns the current line as a string SplFileObject::valid — Not at EOF

SplTempFileObject: промежуточный документ и порог памяти

Временный объект подходит для CSV-экспорта, отчёта, преобразования изображения или тела ответа, которое нужно сначала собрать и проверить. Он исчезает после закрытия, поэтому важный результат копируют в именованный файл, БД или HTTP-ответ.

Сравнить три режима временного файла по полезному результатуСамостоятельный пример
<?php
declare(strict_types=1);

$payload = "Заказ 42\nКисть — 2 шт.\nИтого: 300 руб.\n";
$variants = [
    'сразу временный файл ОС' => new SplTempFileObject(0),
    'только память' => new SplTempFileObject(-1),
    'порог 16 байт' => new SplTempFileObject(16),
];

foreach ($variants as $label => $temp) {
    $written = $temp->fwrite($payload);
    if ($written !== strlen($payload)) {
        throw new RuntimeException('Неполная временная запись');
    }
    $temp->rewind();
    echo $label . ': ' . $temp->fstat()['size'] . ' байт; ' . trim($temp->fgets()) . "\n";
}
Ожидаемый результат
сразу временный файл ОС: 61 байт; Заказ 42
только память: 61 байт; Заказ 42
порог 16 байт: 61 байт; Заказ 42

0 просит использовать временный файл сразу, -1 запрещает перенос из памяти, 16 переносит данные после превышения 16 байт. Публичный API показывает размер и содержимое, но намеренно не обещает внутренний путь или измерение RAM. Во всех трёх случаях полезный контракт один: 61 байт записан и снова прочитан.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

The SplTempFileObject class

(PHP 5 >= 5.1.2, PHP 7, PHP 8)

Introduction

The SplTempFileObject class offers an object-oriented interface for a temporary file.

Class synopsis

class SplTempFileObject

extends SplFileObject {

/* Inherited constants */

public const int SplFileObject::DROP_NEW_LINE;

public const int SplFileObject::READ_AHEAD;

public const int SplFileObject::SKIP_EMPTY;

public const int SplFileObject::READ_CSV;

/* Methods */

public function __construct(int $maxMemory = 2 * 1024 * 1024)

/* Inherited methods */

public function SplFileObject::current(): string|array|false

public function SplFileObject::eof(): bool

public function SplFileObject::fflush(): bool

public function SplFileObject::fgetc(): string|false

public function SplFileObject::fgetcsv(string $separator = ",", string $enclosure = "\"", string $escape = "\\"): array|false

public function SplFileObject::fgets(): string

public function SplFileObject::fgetss(string $allowable_tags = ?): string

public function SplFileObject::flock(int $operation, int &$wouldBlock = null): bool

public function SplFileObject::fpassthru(): int

public function SplFileObject::fputcsv(    array $fields,    string $separator = ",",    string $enclosure = "\"",    string $escape = "\\",    string $eol = "\n"): int|false

public function SplFileObject::fread(int $length): string|false

public function SplFileObject::fscanf(string $format, mixed &...$vars): array|int|null

public function SplFileObject::fseek(int $offset, int $whence = SEEK_SET): int

public function SplFileObject::fstat(): array

public function SplFileObject::ftell(): int|false

public function SplFileObject::ftruncate(int $size): bool

public function SplFileObject::fwrite(string $data, ?int $length = null): int|false

public function SplFileObject::getChildren(): null

public function SplFileObject::getCsvControl(): array

public function SplFileObject::getFlags(): int

public function SplFileObject::getMaxLineLen(): int

public function SplFileObject::hasChildren(): false

public function SplFileObject::key(): int

public function SplFileObject::next(): void

public function SplFileObject::rewind(): void

public function SplFileObject::seek(int $line): void

public function SplFileObject::setCsvControl(string $separator = ",", string $enclosure = "\"", string $escape = "\\"): void

public function SplFileObject::setFlags(int $flags): void

public function SplFileObject::setMaxLineLen(int $maxLength): void

public function SplFileObject::__toString(): string

public function SplFileObject::valid(): bool

public function SplFileInfo::getATime(): int|false

public function SplFileInfo::getBasename(string $suffix = ""): string

public function SplFileInfo::getCTime(): int|false

public function SplFileInfo::getExtension(): string

public function SplFileInfo::getFileInfo(?string $class = null): SplFileInfo

public function SplFileInfo::getFilename(): string

public function SplFileInfo::getGroup(): int|false

public function SplFileInfo::getInode(): int|false

public function SplFileInfo::getLinkTarget(): string|false

public function SplFileInfo::getMTime(): int|false

public function SplFileInfo::getOwner(): int|false

public function SplFileInfo::getPath(): string

public function SplFileInfo::getPathInfo(?string $class = null): ?SplFileInfo

public function SplFileInfo::getPathname(): string

public function SplFileInfo::getPerms(): int|false

public function SplFileInfo::getRealPath(): string|false

public function SplFileInfo::getSize(): int|false

public function SplFileInfo::getType(): string|false

public function SplFileInfo::isDir(): bool

public function SplFileInfo::isExecutable(): bool

public function SplFileInfo::isFile(): bool

public function SplFileInfo::isLink(): bool

public function SplFileInfo::isReadable(): bool

public function SplFileInfo::isWritable(): bool

public function SplFileInfo::openFile(string $mode = "r", bool $useIncludePath = false, ?resource $context = null): SplFileObject

public function SplFileInfo::setFileClass(string $class = SplFileObject::class): void

public function SplFileInfo::setInfoClass(string $class = SplFileInfo::class): void

public function SplFileInfo::__toString(): string

}

Table of Contents SplTempFileObject::__construct — Construct a new temporary file object

Готовые задачи: импорт, журнал, поток и границы текста

Ниже методы объединены в законченные сценарии. Каждый пример создаёт или читает только собственные файлы из учебной папки, показывает итог и отдельно объясняет отказ. Это следующий уровень после карточек отдельных методов.

CSV-каталог: заголовок, проверка строк и частичный результат

Импортировать каталог и показать принятые и отклонённые строкиСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/catalog.csv', 'rb');
$file->setCsvControl(';', '"', '');
$header = $file->fgetcsv();
if ($header !== ['sku', 'name', 'price', 'stock']) {
    throw new RuntimeException('Неожиданные столбцы CSV');
}

$accepted = [];
$rejected = [];
while (($row = $file->fgetcsv()) !== false) {
    if ($row === [null]) { continue; }
    if (count($row) !== 4) {
        $rejected[] = 'строка ' . ($file->key() + 1) . ': нужно 4 поля';
        continue;
    }
    [$sku, $name, $price, $stock] = $row;
    if ($sku === '' || $name === '' || !is_numeric($price) || filter_var($stock, FILTER_VALIDATE_INT) === false || (int) $stock < 0) {
        $rejected[] = 'строка ' . ($file->key() + 1) . ': неверные данные';
        continue;
    }
    $accepted[$sku] = ['name' => $name, 'price' => (float) $price, 'stock' => (int) $stock];
}

foreach ($accepted as $sku => $item) {
    echo $sku . ': ' . $item['name'] . ', ' . number_format($item['price'], 2, '.', '') . ' руб., остаток ' . $item['stock'] . "\n";
}
foreach ($rejected as $message) { echo 'Ошибка: ' . $message . "\n"; }
echo 'Итог: принято ' . count($accepted) . ', отклонено ' . count($rejected) . ".\n";
Ожидаемый результат
BR-1: Кисть широкая, 150.00 руб., остаток 2
PN-9: Пена, 450.50 руб., остаток 0
Ошибка: строка 3: неверные данные
Ошибка: строка 5: нужно 4 поля
Итог: принято 2, отклонено 2.

CSV сначала проверяется по заголовку. Пустая физическая строка даёт [null] и пропускается явно. Затем проверяются число полей, обязательные значения, цена и целый неотрицательный остаток. Хорошие строки не теряются из-за соседней ошибки; плохие получают номер и причину. В реальном импорте после этой стадии начинают транзакцию БД и сохраняют только проверенную модель.

Дописываемый журнал: сохранить позицию и продолжить

Продолжить журнал с сохранённого байтового смещенияСамостоятельный пример
<?php
declare(strict_types=1);

$logPath = __DIR__ . '/orders.log';
$cursorPath = __DIR__ . '/orders.cursor';
file_put_contents($logPath, "order=41 status=paid\norder=42 status=new\n");
file_put_contents($cursorPath, "0");

$readNew = static function () use ($logPath, $cursorPath): void {
    $offset = (int) trim(file_get_contents($cursorPath));
    $log = new SplFileObject($logPath, 'rb');
    if ($log->fseek($offset, SEEK_SET) !== 0) {
        throw new RuntimeException('Смещение больше недоступно');
    }
    while (!$log->eof()) {
        $line = $log->fgets();
        if ($line === '') { break; }
        echo 'Новая запись: ' . rtrim($line, "\r\n") . "\n";
    }
    $next = $log->ftell();
    if ($next === false) { throw new RuntimeException('Не получена позиция'); }
    file_put_contents($cursorPath, (string) $next);
    echo 'Следующее смещение: ' . $next . "\n";
};

$readNew();
file_put_contents($logPath, "order=43 status=shipped\n", FILE_APPEND);
$readNew();
Ожидаемый результат
Новая запись: order=41 status=paid
Новая запись: order=42 status=new
Следующее смещение: 41
Новая запись: order=43 status=shipped
Следующее смещение: 65

ftell() возвращает байтовую позицию после полностью прочитанных строк. Она сохраняется отдельно; следующий запуск перед чтением вызывает fseek(). Это полезно для дописываемого журнала. В производстве также сохраняют identity файла и обрабатывают ротацию/усечение: если размер стал меньше курсора или inode изменился, чтение начинают по согласованной политике, а не с произвольного старого байта.

Большой файл: обработать поток без массива всех строк

Посчитать большой собственный файл по одной строкеСамостоятельный пример
<?php
declare(strict_types=1);

$path = __DIR__ . '/measurements.txt';
$writer = new SplFileObject($path, 'wb');
for ($i = 1; $i <= 10000; $i++) {
    $line = $i . ';' . ($i % 10) . "\n";
    if ($writer->fwrite($line) !== strlen($line)) {
        throw new RuntimeException('Неполная запись строки ' . $i);
    }
}
$writer->fflush();
unset($writer);

$reader = new SplFileObject($path, 'rb');
$count = 0;
$sum = 0;
while (($line = $reader->fgets()) !== '') {
    [$id, $value] = explode(';', rtrim($line, "\r\n"), 2);
    $count++;
    $sum += (int) $value;
}
echo 'Строк: ' . $count . "\n";
echo 'Сумма значений: ' . $sum . "\n";
echo 'Размер файла: ' . filesize($path) . " байт\n";
Ожидаемый результат
Строк: 10000
Сумма значений: 45000
Размер файла: 68894 байт

Пример сам создаёт 10 000 строк, закрывает писателя и затем читает файл по одной строке. В памяти остаются текущая строка и два счётчика, а не массив из 10 000 записей. Это не обещание конкретного объёма RAM: интерпретатор и файловая система используют свои буферы. Видимый результат подтверждает число обработанных строк, сумму и точный размер созданного ASCII-файла.

UTF-8 BOM и CRLF: байты требуют явной политики

Убрать BOM и переносы, не скрывая кодировкуСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/windows-utf8.txt', 'rb');
$number = 0;
while (!$file->eof()) {
    $line = $file->fgets();
    if ($line === '') { break; }
    $number++;
    if ($number === 1 && str_starts_with($line, "\xEF\xBB\xBF")) {
        $line = substr($line, 3);
    }
    echo $number . ': ' . rtrim($line, "\r\n") . "\n";
}
Ожидаемый результат
1: Заказ 42
2: Готов

Файл содержит UTF-8 BOM и переносы CRLF. SplFileObject возвращает байты как есть и не определяет кодировку. Только в первой строке проверяются три байта BOM; rtrim($line, "\r\n") удаляет оба варианта переноса, не стирая обычные пробелы текста. Для неизвестного внешнего ввода кодировку сначала проверяют, а преобразование выполняют явным инструментом вроде mb_convert_encoding/iconv с собственной политикой ошибок.

Связанные карточки: SplFileObject::fgetcsv, SplFileObject::setCsvControl, SplFileObject::fseek, SplFileObject::ftell, SplFileObject::fgets и SplFileObject::fwrite. Для блокировки одновременных писателей перейдите к SplFileObject::flock.

Как выбрать операцию и не потерять ошибку

ПотребностьИнструментЧто обязательно проверить
Показать имя/размер, не читать содержимоеSplFileInfoОтсутствие пути, false/RuntimeException, кэш stat, symlink-политику.
Прочитать строку или порциюSplFileObject::fgets/freadEOF отдельно от ошибки/пустой строки; кодировку и переносы.
Перебрать CSVfgetcsv или READ_CSVЯвные delimiter/enclosure/escape, [null], число и типы полей.
Продолжить по позицииftell + fseekПозиция в байтах; ротация, усечение и identity файла.
Записать совместноc+b + flock + fflushНе очищать до lock; проверять частичную запись; все писатели соблюдают протокол.
Собрать промежуточный результатSplTempFileObjectПорог хранения не лимит RAM процесса; нет обещанного обычного пути.

Режимы открытия — часть контракта данных. rb не пишет; wb очищает сразу; xb создаёт только новый файл; c+b не очищает; a+b пишет в конец. Буква b особенно важна для переносимых байтовых смещений на Windows.

SPL целиком: какой инструмент выбрать для реальной задачи

SPL — это не один алгоритм, а набор стандартных договоров и готовых объектов. Сначала определите форму задачи: последовательность, очередь, множество объектов, дерево каталогов, CSV-файл, автозагрузка или диагностика. Затем откройте соответствующий маршрут и только после этого выбирайте конкретный метод.

ЗадачаКуда перейтиГлавный вопрос перед выбором
Подключать классы проектафункции автозагрузкиСовпадают ли namespace, префикс и путь; не пытаетесь ли так загружать функции?
Хранить очередь, стек, приоритеты или фиксированный наборструктуры данныхКакие операции часты и важны ли порядок, уникальность и расход памяти?
Фильтровать поток, объединять источники или обходить деревокарту итераторовНужен массив целиком или достаточно читать элементы по одному?
Разобрать путь, прочитать строки, CSV или временный файлфайловые классыЧто является строкой, байтовым смещением и текущей позицией курсора?
Связать метаданные с живыми объектамиSplObjectStorageНужна идентичность объекта текущего процесса или устойчивый бизнес-ID?
Выбрать договор обхода или тип ошибкиинтерфейсы SPL и иерархия исключенийЭто обязательство реализации, ошибка программиста или отказ во время работы?

Функции и методы этой темы

Откройте карточку, чтобы увидеть договор функции, примеры, ограничения и связанные инструменты.

spl_object_idВозвращает целочисленный handle живого объекта в текущем процессе.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

function spl_object_id(object $object): int

Одинаковый объект всегда даёт одинаковое число, разные одновременно живые объекты — разные. После уничтожения handle может быть переиспользован.

ПараметрЧто означает в задаче
$objectЛюбой объект.
Часть контрактаЧто важно
Сигнатураfunction spl_object_id(object $object): int
Результатint — временный идентификатор объекта.
Ошибки и особые значенияНе-объект даёт TypeError.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице
Отличить псевдоним объекта от другого экземпляраСамостоятельный пример
<?php
declare(strict_types=1);

$first = new stdClass();
$alias = $first;
$second = new stdClass();
echo spl_object_id($first) === spl_object_id($alias) ? "same\n" : "different\n";
echo spl_object_id($first) === spl_object_id($second) ? "same\n" : "different\n";
Ожидаемый результат
same
different

Присваивание объекта не создаёт копию, поэтому first и alias имеют один handle. Новый stdClass — другой живой объект.

Связать временные данные с двумя живыми объектамиСамостоятельный пример
<?php
declare(strict_types=1);

$lamp = (object) ['sku' => 'L-1'];
$cable = (object) ['sku' => 'C-1'];
$labels = [
    spl_object_id($lamp) => 'витрина',
    spl_object_id($cable) => 'склад',
];
echo count($labels), "\n";
echo $lamp->sku, ':', $labels[spl_object_id($lamp)], "\n";
Ожидаемый результат
2
L-1:витрина

Пока оба объекта живы, числовой handle различает их в текущем процессе. Для такой связи безопаснее SplObjectStorage или WeakMap: контейнер явно принимает объект и не маскирует временный ID под постоянный.

Строковая форма: spl_object_hash. Для карты объект→данные: SplObjectStorage или WeakMap.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

class_implementsВозвращает интерфейсы, реализованные классом или объектом.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

function class_implements($object_or_class, bool $autoload = true): array|false

Функция исследует объявленную и унаследованную структуру типа. Ключи и значения результата — имена интерфейсов; при неизвестном классе возвращается false.

ПараметрЧто означает в задаче
$object_or_classОбъект или строка с полным именем класса/интерфейса.
$autoloadЗапускать ли зарегистрированные загрузчики для неизвестного имени; по умолчанию true.
Часть контрактаЧто важно
Сигнатураfunction class_implements($object_or_class, bool $autoload = true): array|false
Результатarray имён интерфейсов или false, если класс не существует/не загружен.
Ошибки и особые значенияautoload callback может выбросить своё исключение. Недействительный тип аргумента приводит к TypeError.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице
Проверить два договора объекта отчётаСамостоятельный пример
<?php
declare(strict_types=1);

final class Report implements Countable, JsonSerializable
{
    public function count(): int { return 3; }
    public function jsonSerialize(): mixed { return ['rows' => 3]; }
}
$interfaces = class_implements(new Report());
echo 'Countable=', isset($interfaces[Countable::class]) ? 'yes' : 'no', "\n";
echo 'JsonSerializable=', isset($interfaces[JsonSerializable::class]) ? 'yes' : 'no', "\n";
Ожидаемый результат
Countable=yes
JsonSerializable=yes

Функция возвращает ассоциативный массив имён. Для одной проверки обычно яснее $report instanceof Countable; список полезен диагностике и инструментам.

Не запускать автозагрузку при безопасном исследовании имениСамостоятельный пример
<?php
declare(strict_types=1);

$calls = 0;
$loader = static function (string $class) use (&$calls): void { $calls++; };
spl_autoload_register($loader);
$name = 'Vendor\\MissingWidget';
$result = class_exists($name, false) ? class_implements($name, false) : false;
spl_autoload_unregister($loader);
echo $result === false ? 'Класс не найден' : 'Класс найден', "\n";
echo 'Вызовов loader: ', $calls, "\n";
Ожидаемый результат
Класс не найден
Вызовов loader: 0

Сначала class_exists с false проверяет таблицу уже загруженных типов без warning и без запуска loader. Только существующее имя передаётся class_implements. Сам class_implements для отсутствующей строки возвращает false, но также выдаёт warning, поэтому безопасный диагностический шаблон проверяет существование заранее.

Родители: class_parents. Трейты: class_uses.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

iterator_to_arrayКопирует элементы Traversable или array в новый массив.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

function iterator_to_array(Traversable|array $iterator, bool $preserve_keys = true): array

Функция полностью обходит источник и материализует результат. Параметр preserve_keys определяет, использовать ли исходные ключи.

ПараметрЧто означает в задаче
$iteratorTraversable или array.
$preserve_keystrue сохраняет ключи; false перенумеровывает значения от нуля.
Часть контрактаЧто важно
Сигнатураfunction iterator_to_array(Traversable|array $iterator, bool $preserve_keys = true): array
Результатarray со всеми пройденными значениями.
Ошибки и особые значенияИсключения итератора выходят наружу; для недопустимых типов ключа возможны преобразования/предупреждения по правилам массива.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице
Увидеть потерю повторяющихся ключей и сохранить все значенияСамостоятельный пример
<?php
declare(strict_types=1);

$source = (function (): Generator {
    yield 'SKU' => 'старая цена';
    yield 'SKU' => 'новая цена';
})();
$preserved = iterator_to_array($source, true);
echo json_encode($preserved, JSON_UNESCAPED_UNICODE), "\n";

$source = (function (): Generator {
    yield 'SKU' => 'старая цена';
    yield 'SKU' => 'новая цена';
})();
echo json_encode(iterator_to_array($source, false), JSON_UNESCAPED_UNICODE), "\n";
Ожидаемый результат
{"SKU":"новая цена"}
["старая цена","новая цена"]

При preserve_keys=true позднее значение перезаписывает раннее с тем же ключом. false назначает новые числовые ключи и сохраняет обе записи.

Сделать снимок конечного потока для повторного чтенияСамостоятельный пример
<?php
declare(strict_types=1);

function prices(): Generator {
    yield 'lamp' => 1200;
    yield 'cable' => 300;
}
$snapshot = iterator_to_array(prices());
echo 'Позиций: ', count($snapshot), "\n";
echo 'Лампа: ', $snapshot['lamp'], "\n";
Ожидаемый результат
Позиций: 2
Лампа: 1200

Массив можно читать повторно и обращаться по ключу. Цена — память на все элементы; для миллионов строк обработка потоком безопаснее.

Только число элементов: iterator_count.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

iterator_countПодсчитывает элементы Traversable или массива полным обходом.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

function iterator_count(Traversable|array $iterator): int

Для Iterator функция проходит последовательность. Позиция после вызова не гарантируется; одноразовый Generator будет исчерпан.

ПараметрЧто означает в задаче
$iteratorTraversable или, начиная с PHP 8.2, array.
Часть контрактаЧто важно
Сигнатураfunction iterator_count(Traversable|array $iterator): int
Результатint — число пройденных элементов.
Ошибки и особые значенияИсключения из Iterator выходят наружу. Бесконечная последовательность не завершится.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице
Посчитать массив и Iterator одной функциейСамостоятельный пример
<?php
declare(strict_types=1);

echo iterator_count(['A', 'B', 'C']), "\n";
echo iterator_count(new ArrayIterator(['draft', 'paid'])), "\n";
Ожидаемый результат
3
2

Начиная с PHP 8.2 функция принимает и array. Для обычного массива count яснее; общий API удобен, если вход действительно объявлен как iterable.

Увидеть, что подсчёт исчерпывает GeneratorСамостоятельный пример
<?php
declare(strict_types=1);

function rows(): Generator {
    yield 'first';
    yield 'second';
}
$rows = rows();
echo 'Количество: ', iterator_count($rows), "\n";
echo 'После подсчёта valid: ', $rows->valid() ? 'yes' : 'no', "\n";
Ожидаемый результат
Количество: 2
После подсчёта valid: no

Чтобы узнать размер Generator, PHP проходит его до конца. Повторного результата уже нет; если нужны и элементы, и число, материализуйте конечный поток один раз или считайте по мере обработки.

Сохранить значения: iterator_to_array.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplQueue::enqueueПоставить работу в конец FIFO-очереди

PHP 5.3+; примеры рассчитаны на PHP 8.2+ · SPL

public function SplQueue::enqueue(mixed $value): void

Вызов $jobs->enqueue("Импорт") добавляет строку в конец именно $jobs. Ранее ожидающие задания сохраняют место; значение может быть массивом, объектом или null. Метод — псевдоним SplDoublyLinkedList::push().

ПараметрЧто означает в задаче
valueЗадание любого типа. Аргумент передаётся как значение PHP; объект остаётся тем же объектом, глубокого копирования нет.
Часть контрактаЧто важно
Сигнатураpublic function SplQueue::enqueue(mixed $value): void
Результатvoid: очередь изменена, полезного возвращаемого значения нет. Работу получают отдельным dequeue().
Ошибки и особые значенияПамять процесса конечна; успешная постановка не означает выполнение или сохранение на диск.
ВерсииPHP 5.3+; примеры рассчитаны на PHP 8.2+
Получить первое заданиеСамостоятельный пример
<?php
declare(strict_types=1);

$jobs = new SplQueue();
$jobs->enqueue('Импорт');
$jobs->enqueue('Отчёт');
$job = $jobs->dequeue();
echo 'Выполняем: ', $job, "\n";
echo 'Следующее: ', $jobs->bottom(), "\n";
Ожидаемый результат
Выполняем: Импорт
Следующее: Отчёт

После двух enqueue очередь содержит Импорт → Отчёт. dequeue удаляет Импорт и возвращает эту строку в присваивание $job. bottom читает оставшийся Отчёт без удаления. Ни один метод здесь сам не выполняет задание: полезное действие обозначено выводом.

Скачать самостоятельный пример с результатом и README

Обойти связанные разделы без бесконечных повторовСамостоятельный пример
<?php
declare(strict_types=1);

$links = ['Главная' => ['Каталог', 'Контакты'], 'Каталог' => ['Главная', 'Чай'], 'Контакты' => [], 'Чай' => []];
$pending = new SplQueue();
$pending->enqueue('Главная');
$scheduled = ['Главная' => true];
while (!$pending->isEmpty()) {
    $page = $pending->dequeue();
    echo 'Раздел: ', $page, "\n";
    foreach ($links[$page] as $next) {
        if (!isset($scheduled[$next])) {
            $scheduled[$next] = true;
            $pending->enqueue($next);
        }
    }
}
Ожидаемый результат
Раздел: Главная
Раздел: Каталог
Раздел: Контакты
Раздел: Чай

Это конечный граф разделов, уже известный в памяти. foreach получает соседей текущей страницы. isset проверяет отметку; её ставят при постановке в очередь, поэтому две страницы не поставят один раздел дважды. Обратная ссылка Каталог → Главная не зацикливает обработку. Для загружаемого извне графа отдельно нужны пределы страниц, глубины и времени.

Скачать самостоятельный пример с результатом и README

Продолжение: SplQueue::dequeue, SplDoublyLinkedList::push.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplQueue::dequeueПолучить и удалить первое задание

PHP 5.3+; примеры рассчитаны на PHP 8.2+ · SPL

public function SplQueue::dequeue(): mixed

В выражении $job = $jobs->dequeue() значение первого узла возвращается на место вызова, затем присваивается $job. Остальные задания сдвигаются в порядке обхода. Это псевдоним SplDoublyLinkedList::shift().

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplQueue::dequeue(): mixed
Результатmixed: само извлечённое значение, а не изменённая очередь и не признак успеха.
Ошибки и особые значенияЧтение top/bottom и удаление pop/shift из пустого списка вызывают RuntimeException. Перед обычной обработкой проверяйте isEmpty(); null, 0 и пустая строка могут быть настоящими значениями.
ВерсииPHP 5.3+; примеры рассчитаны на PHP 8.2+
Обработать очередь до концаСамостоятельный пример
<?php
declare(strict_types=1);

$jobs = new SplQueue();
$jobs->enqueue(['file' => 'orders.csv', 'rows' => 3]);
$jobs->enqueue(['file' => 'returns.csv', 'rows' => 1]);
while (!$jobs->isEmpty()) {
    $job = $jobs->dequeue();
    echo $job['file'], ': подготовлено строк ', $job['rows'], "\n";
}
echo 'Осталось заданий: ', $jobs->count(), "\n";
Ожидаемый результат
orders.csv: подготовлено строк 3
returns.csv: подготовлено строк 1
Осталось заданий: 0

Каждое задание теперь массив с именем и числом строк. ! превращает «пуста» в «не пуста»; while повторяет тело, пока это условие истинно. dequeue передаёт ровно один массив в $job и уменьшает очередь. После двух проходов условие ложно, выполняется последний echo. Файлы здесь описаны данными, их чтение не заявляется.

Скачать самостоятельный пример с результатом и README

Пустая очередь и настоящее значение nullСамостоятельный пример
<?php
declare(strict_types=1);

$jobs = new SplQueue();
$jobs->enqueue(null);
while (!$jobs->isEmpty()) {
    $job = $jobs->dequeue();
    echo $job === null ? "Получено задание без данных\n" : $job . "\n";
}
try {
    $jobs->dequeue();
} catch (RuntimeException $error) {
    echo "Новой работы нет\n";
}
Ожидаемый результат
Получено задание без данных
Новой работы нет

Очередь с одним null не пуста. Проверка по isEmpty позволяет обработать значение, после чего отдельная попытка чтения пустой очереди попадает в catch. try обозначает проверяемое действие, catch получает исключение указанного класса и выбирает понятную реакцию; это не возврат null из dequeue.

Скачать самостоятельный пример с результатом и README

Продолжение: SplQueue::enqueue, SplDoublyLinkedList::bottom.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

OuterIterator::getInnerIteratorВозвращает Iterator, который обёрнут текущим OuterIterator.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

abstract public function OuterIterator::getInnerIterator(): ?Iterator

Метод отвечает на вопрос «какой источник находится непосредственно под этой обёрткой?». Он полезен для диагностики цепочки фильтров и для API, которому нужен исходный Iterator. У вложенных обёрток один вызов снимает только один слой.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураabstract public function OuterIterator::getInnerIterator(): ?Iterator
РезультатIterator|null по официальной сигнатуре интерфейса. Конкретные стандартные обёртки обычно возвращают переданный Iterator.
Ошибки и особые значенияСам интерфейс не объявляет специального исключения. Ошибки возникают из реализации или из опасных изменений общего внутреннего объекта.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице
Увидеть источник за фильтром доступных товаровСамостоятельный пример
<?php
declare(strict_types=1);

final class AvailableProducts extends FilterIterator
{
    public function accept(): bool
    {
        return $this->current()['stock'] > 0;
    }
}

$source = new ArrayIterator([
    'SKU-1' => ['name' => 'Лампа', 'stock' => 3],
    'SKU-2' => ['name' => 'Кабель', 'stock' => 0],
]);
$available = new AvailableProducts($source);

foreach ($available as $sku => $product) {
    echo $sku, ':', $product['name'], "\n";
}
echo 'Источник: ', get_class($available->getInnerIterator()), "\n";
Ожидаемый результат
SKU-1:Лампа
Источник: ArrayIterator

Фильтр выдаёт только товар с остатком. getInnerIterator не снимает фильтр с foreach: он отдельно возвращает тот ArrayIterator, который был передан конструктору.

Понять, что обёртка и вызывающий код видят один источникСамостоятельный пример
<?php
declare(strict_types=1);

$source = new ArrayIterator(['new', 'paid']);
$wrapper = new IteratorIterator($source);

echo iterator_count($wrapper->getInnerIterator()), "\n";
$source->append('sent');
echo iterator_count($wrapper->getInnerIterator()), "\n";
Ожидаемый результат
2
3

Внутренний итератор не копируется. После append обе стороны видят третий статус. Такая общая изменяемость полезна не всегда; для стабильного снимка сначала создайте отдельный массив.

Соседние инструменты: iterator_to_array создаёт снимок, iterator_count считает элементы.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveIterator::getChildrenВозвращает RecursiveIterator для детей текущего элемента.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

abstract public function RecursiveIterator::getChildren(): ?RecursiveIterator

Сначала вызывающий код проверяет hasChildren, затем получает отдельный итератор ветки. Это разделяет решение «ветка или лист» и способ обхода детей.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураabstract public function RecursiveIterator::getChildren(): ?RecursiveIterator
РезультатRecursiveIterator|null. Конкретная реализация описывает, когда возможен null.
Ошибки и особые значенияВызов на листе без предварительной проверки зависит от реализации и может дать исключение или бессмысленный результат.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице
Открыть одну ветку каталогаСамостоятельный пример
<?php
declare(strict_types=1);

$catalog = new RecursiveArrayIterator([
    'lighting' => ['L-1' => 'Лампа', 'L-2' => 'Бра'],
    'delivery' => 'Самовывоз',
]);

$catalog->rewind();
echo $catalog->key(), "\n";
$children = $catalog->getChildren();
foreach ($children as $sku => $name) {
    echo $sku, ':', $name, "\n";
}
Ожидаемый результат
lighting
L-1:Лампа
L-2:Бра

rewind ставит курсор на lighting. getChildren создаёт RecursiveIterator для вложенного массива; исходный корневой итератор остаётся на своём элементе.

Перейти от отдела к полке и товаруСамостоятельный пример
<?php
declare(strict_types=1);

$tree = new RecursiveArrayIterator([
    'warehouse' => ['A' => ['A-01' => 'Кабель']],
]);
$tree->rewind();
$warehouse = $tree->getChildren();
$warehouse->rewind();
$shelf = $warehouse->getChildren();

foreach ($shelf as $cell => $product) {
    echo $cell, '=', $product, "\n";
}
Ожидаемый результат
A-01=Кабель

Каждый getChildren спускается ровно на один уровень. Для неизвестной заранее глубины не пишут цепочку вручную, а передают корневой RecursiveIterator в RecursiveIteratorIterator.

Сначала прочитайте RecursiveIterator::hasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveIterator::hasChildrenСообщает, есть ли у текущего элемента дочерний итератор.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

abstract public function RecursiveIterator::hasChildren(): bool

Метод вызывается относительно текущей позиции. Он не спрашивает, есть ли элементы вообще во всём дереве, и не перемещает курсор.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураabstract public function RecursiveIterator::hasChildren(): bool
Результатtrue, если текущий элемент следует обходить как ветку, иначе false.
Ошибки и особые значенияЕсли итератор не находится на допустимой позиции, поведение задаёт реализация. Сначала корректно rewind/valid или используйте foreach.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице
Отличить раздел от конечного значенияСамостоятельный пример
<?php
declare(strict_types=1);

$tree = new RecursiveArrayIterator([
    'database' => ['host' => 'db.local'],
    'debug' => false,
    'empty_group' => [],
]);
foreach ($tree as $name => $value) {
    echo $name, ':', $tree->hasChildren() ? 'ветка' : 'лист', "\n";
}
Ожидаемый результат
database:ветка
debug:лист
empty_group:ветка

Даже пустой вложенный массив является веткой: он может не дать ни одного ребёнка, но его тип всё равно описывает контейнер. Булево false остаётся листом.

Показать ветки перед автоматическим глубоким обходомСамостоятельный пример
<?php
declare(strict_types=1);

$source = new RecursiveArrayIterator([
    'site' => ['title' => 'Магазин', 'theme' => ['color' => 'green']],
]);
$walker = new RecursiveIteratorIterator($source, RecursiveIteratorIterator::SELF_FIRST);

foreach ($walker as $key => $value) {
    $inner = $walker->getInnerIterator();
    echo str_repeat('  ', $walker->getDepth()), $key,
         $inner->hasChildren() ? '/' : '=' . (string) $value, "\n";
}
Ожидаемый результат
site/
  title=Магазин
  theme/
    color=green

SELF_FIRST выдаёт ветку до её содержимого. getInnerIterator на каждом шаге указывает на RecursiveIterator текущего уровня; hasChildren определяет, печатать ли разделитель ветки.

После true используйте RecursiveIterator::getChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SeekableIterator::seekУстанавливает текущую позицию SeekableIterator по числовому смещению.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

abstract public function SeekableIterator::seek(int $offset): void

Метод нужен для прямого перехода внутри уже имеющейся последовательности. После успешного вызова current/key относятся к выбранной позиции.

ПараметрЧто означает в задаче
$offsetЦелое смещение позиции. Ноль означает первый элемент у стандартных реализаций.
Часть контрактаЧто важно
Сигнатураabstract public function SeekableIterator::seek(int $offset): void
РезультатНичего не возвращает (void); наблюдаемый результат — изменённая текущая позиция.
Ошибки и особые значенияOutOfBoundsException — рекомендуемый договор для недопустимой позиции; конкретная реализация обязана его документировать.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице
Перейти к строке выбранной страницыСамостоятельный пример
<?php
declare(strict_types=1);

$orders = new ArrayIterator(['A-100', 'A-101', 'A-102', 'A-103']);
$page = 2;
$perPage = 2;
$offset = ($page - 1) * $perPage;

$orders->seek($offset);
echo 'Первая строка страницы: ', $orders->current(), "\n";
Ожидаемый результат
Первая строка страницы: A-102

seek получает числовую позицию 2, а не ключ или номер страницы. Формула страницы находится снаружи и может быть проверена отдельно.

Обработать запрос несуществующей позицииСамостоятельный пример
<?php
declare(strict_types=1);

$rows = new ArrayIterator(['first', 'second']);
try {
    $rows->seek(5);
    echo $rows->current(), "\n";
} catch (OutOfBoundsException $error) {
    echo "Позиции 5 нет\n";
}
Ожидаемый результат
Позиции 5 нет

ArrayIterator сообщает о выходе за диапазон через OutOfBoundsException. В HTTP-приложении это условие можно преобразовать в пустую страницу или 404 согласно договору интерфейса.

Для диапазона поверх итератора смотрите LimitIterator.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplObserver::updateПолучает уведомление от SplSubject и выполняет реакцию наблюдателя.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

abstract public function SplObserver::update(SplSubject $subject): void

Subject вызывает update сам. Параметр позволяет observer прочитать нужное состояние; SPL не передаёт отдельный payload и не определяет имя события.

ПараметрЧто означает в задаче
$subjectОбъект, который инициировал уведомление; тип гарантирует лишь методы SplSubject.
Часть контрактаЧто важно
Сигнатураabstract public function SplObserver::update(SplSubject $subject): void
РезультатНичего не возвращает (void). Побочный эффект определяет observer: запись в память, журнал, постановка задания.
Ошибки и особые значенияЛюбое исключение реализации выходит в notify, если Subject его явно не изолирует.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице
Передать подписчику новое состояние ценыСамостоятельный пример
<?php
declare(strict_types=1);

final class PriceSubject implements SplSubject
{
    public int $price = 0;
    private SplObjectStorage $observers;
    public function __construct() { $this->observers = new SplObjectStorage(); }
    public function attach(SplObserver $o): void { $this->observers[$o] = null; }
    public function detach(SplObserver $o): void { unset($this->observers[$o]); }
    public function notify(): void { foreach ($this->observers as $o) { $o->update($this); } }
}
final class PriceLog implements SplObserver
{
    public function update(SplSubject $subject): void
    {
        echo 'Новая цена: ', $subject->price, "\n";
    }
}
$subject = new PriceSubject();
$subject->attach(new PriceLog());
$subject->price = 159900;
$subject->notify();
Ожидаемый результат
Новая цена: 159900

update получает объект subject, а цена заранее записана в его состояние. В реальном дизайне лучше дать типизированный метод чтения или отдельный объект события, чтобы observer не зависел от публичного изменяемого свойства.

Различить типы событий внутри одного SubjectСамостоятельный пример
<?php
declare(strict_types=1);

final class OrderSubject implements SplSubject
{
    public string $event = '';
    private SplObjectStorage $observers;
    public function __construct() { $this->observers = new SplObjectStorage(); }
    public function attach(SplObserver $o): void { $this->observers[$o] = null; }
    public function detach(SplObserver $o): void { unset($this->observers[$o]); }
    public function notify(): void { foreach ($this->observers as $o) { $o->update($this); } }
    public function record(string $event): void { $this->event = $event; $this->notify(); }
}
final class AuditObserver implements SplObserver
{
    public function update(SplSubject $subject): void { echo 'audit:', $subject->event, "\n"; }
}
$orders = new OrderSubject();
$orders->attach(new AuditObserver());
$orders->record('order-paid');
$orders->record('order-sent');
Ожидаемый результат
audit:order-paid
audit:order-sent

Интерфейс передаёт только Subject. Здесь последнее событие хранится в event. Для конкурентных или отложенных уведомлений безопаснее неизменяемый объект события и очередь, а не одно перезаписываемое поле.

Регистрация выполняется через SplSubject::attach.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplSubject::attachРегистрирует объект SplObserver для будущих уведомлений.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

abstract public function SplSubject::attach(SplObserver $observer): void

Интерфейс не хранит список за вас: реализация Subject выбирает SplObjectStorage или собственную коллекцию и определяет политику повторной регистрации.

ПараметрЧто означает в задаче
$observerКонкретный объект, реализующий SplObserver.
Часть контрактаЧто важно
Сигнатураabstract public function SplSubject::attach(SplObserver $observer): void
РезультатНичего не возвращает (void).
Ошибки и особые значенияSubject может отклонить подписчика своим исключением; сам интерфейс специального типа отказа не задаёт.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице
Не добавить один объект-подписчик дваждыСамостоятельный пример
<?php
declare(strict_types=1);

final class Subject implements SplSubject {
    private SplObjectStorage $list;
    public function __construct() { $this->list = new SplObjectStorage(); }
    public function attach(SplObserver $o): void { $this->list[$o] = null; }
    public function detach(SplObserver $o): void { unset($this->list[$o]); }
    public function notify(): void { foreach ($this->list as $o) { $o->update($this); } }
}
final class Counter implements SplObserver {
    public int $calls = 0;
    public function update(SplSubject $subject): void { $this->calls++; }
}
$subject = new Subject();
$observer = new Counter();
$subject->attach($observer);
$subject->attach($observer);
$subject->notify();
echo $observer->calls, "\n";
Ожидаемый результат
1

SplObjectStorage использует идентичность объекта: повторная запись по тому же объекту не создаёт второй элемент. В PHP 8.5 его методы attach/detach устарели; offset-синтаксис сохраняет поведение контейнера. Два разных Counter остаются двумя подписчиками.

Подключить две независимые реакцииСамостоятельный пример
<?php
declare(strict_types=1);

final class Subject implements SplSubject {
    private array $list = [];
    public function attach(SplObserver $o): void { $this->list[spl_object_id($o)] = $o; }
    public function detach(SplObserver $o): void { unset($this->list[spl_object_id($o)]); }
    public function notify(): void { foreach ($this->list as $o) { $o->update($this); } }
}
final class NamedObserver implements SplObserver {
    public function __construct(private string $name) {}
    public function update(SplSubject $subject): void { echo $this->name, "\n"; }
}
$subject = new Subject();
$subject->attach(new NamedObserver('audit'));
$subject->attach(new NamedObserver('search-index'));
$subject->notify();
Ожидаемый результат
audit
search-index

Один Subject не знает деталей аудита и индекса. Массив здесь индексируется временным object id; его нельзя сохранять как постоянный идентификатор между процессами.

Снять регистрацию: SplSubject::detach.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplSubject::detachУдаляет SplObserver из списка будущих уведомлений.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

abstract public function SplSubject::detach(SplObserver $observer): void

Методу нужен тот же экземпляр observer, если коллекция использует идентичность объекта. После успешного удаления следующие notify не должны его вызывать.

ПараметрЧто означает в задаче
$observerОбъект-подписчик, который нужно убрать.
Часть контрактаЧто важно
Сигнатураabstract public function SplSubject::detach(SplObserver $observer): void
РезультатНичего не возвращает (void).
Ошибки и особые значенияПоведение для отсутствующего observer определяет реализация Subject; SplObjectStorage делает удаление идемпотентным.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице
Отключить один канал и оставить другойСамостоятельный пример
<?php
declare(strict_types=1);

final class Subject implements SplSubject {
    private SplObjectStorage $list;
    public function __construct() { $this->list = new SplObjectStorage(); }
    public function attach(SplObserver $o): void { $this->list[$o] = null; }
    public function detach(SplObserver $o): void { unset($this->list[$o]); }
    public function notify(): void { foreach ($this->list as $o) { $o->update($this); } }
}
final class Channel implements SplObserver {
    public function __construct(private string $name) {}
    public function update(SplSubject $subject): void { echo $this->name, "\n"; }
}
$subject = new Subject();
$email = new Channel('email');
$audit = new Channel('audit');
$subject->attach($email);
$subject->attach($audit);
$subject->detach($email);
$subject->notify();
Ожидаемый результат
audit

detach получает тот же объект email, который был добавлен. Новый Channel("email") был бы другим экземпляром и не снял бы эту подписку.

Безопасно снять уже отсутствующую подписку в SplObjectStorageСамостоятельный пример
<?php
declare(strict_types=1);

$storage = new SplObjectStorage();
$observer = new class implements SplObserver {
    public function update(SplSubject $subject): void {}
};
$storage[$observer] = null;
unset($storage[$observer]);
unset($storage[$observer]);
echo $storage->count(), "\n";
Ожидаемый результат
0

Повторный offsetUnset у SplObjectStorage не бросает исключение. В PHP 8.5 это современная замена устаревшему методу detach контейнера. Это свойство контейнера, а не требование интерфейса SplSubject: собственная реализация может выбрать другой договор.

Добавление: SplSubject::attach.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplSubject::notifyВызывает обновление зарегистрированных observers.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

abstract public function SplSubject::notify(): void

Реализация Subject сама перебирает коллекцию и вызывает update. Интерфейс не диктует порядок, изоляцию исключений и момент относительно фиксации транзакции.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураabstract public function SplSubject::notify(): void
РезультатНичего не возвращает (void); результаты реакций нужно проектировать отдельно.
Ошибки и особые значенияПервое необработанное исключение update обычно выходит из notify и прерывает цикл.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице
Увидеть синхронный порядок вызововСамостоятельный пример
<?php
declare(strict_types=1);

final class Subject implements SplSubject {
    public array $list = [];
    public function attach(SplObserver $o): void { $this->list[] = $o; }
    public function detach(SplObserver $o): void {}
    public function notify(): void {
        echo "before\n";
        foreach ($this->list as $o) { $o->update($this); }
        echo "after\n";
    }
}
final class Step implements SplObserver {
    public function __construct(private string $name) {}
    public function update(SplSubject $subject): void { echo $this->name, "\n"; }
}
$subject = new Subject();
$subject->attach(new Step('audit'));
$subject->attach(new Step('index'));
$subject->notify();
Ожидаемый результат
before
audit
index
after

notify — обычный метод. Каждый update завершается до следующего, затем управление возвращается к строке after. SPL сам не создаёт очередь и не запускает параллельные задачи.

Увидеть, как исключение прерывает следующий observerСамостоятельный пример
<?php
declare(strict_types=1);

final class Subject implements SplSubject {
    public array $list = [];
    public function attach(SplObserver $o): void { $this->list[] = $o; }
    public function detach(SplObserver $o): void {}
    public function notify(): void { foreach ($this->list as $o) { $o->update($this); } }
}
final class Step implements SplObserver {
    public function __construct(private string $name, private bool $fails = false) {}
    public function update(SplSubject $subject): void {
        echo $this->name, "\n";
        if ($this->fails) { throw new RuntimeException('observer failed'); }
    }
}
$subject = new Subject();
$subject->attach(new Step('first'));
$subject->attach(new Step('second', true));
$subject->attach(new Step('third'));
try { $subject->notify(); }
catch (RuntimeException $error) { echo $error->getMessage(), "\n"; }
Ожидаемый результат
first
second
observer failed

third не вызван: исключение вышло из цикла. Для независимых обработчиков Subject может ловить ошибки по одному, но тогда обязан сохранить их и сообщить об итоговом частичном отказе; пустой catch потеряет событие.

Получатель реализует SplObserver::update.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

class_parentsВозвращает родительские классы объекта или имени класса.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

function class_parents($object_or_class, bool $autoload = true): array|false

Список описывает наследование класса до корня. Интерфейсы и трейты в него не входят.

ПараметрЧто означает в задаче
$object_or_classОбъект или полное имя класса.
$autoloadРазрешить автозагрузку неизвестного имени; по умолчанию true.
Часть контрактаЧто важно
Сигнатураfunction class_parents($object_or_class, bool $autoload = true): array|false
Результатarray имён родителей или false для неизвестного класса.
Ошибки и особые значенияИсключение из autoload не скрывается; неправильный тип даёт TypeError.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице
Показать цепочку модели заказаСамостоятельный пример
<?php
declare(strict_types=1);

class Entity {}
class Document extends Entity {}
final class OrderDocument extends Document {}

$parents = array_values(class_parents(OrderDocument::class));
echo implode(' <- ', $parents), "\n";
Ожидаемый результат
Document <- Entity

Возвращаются родитель и его предки; сам OrderDocument в массив не входит. Код не создаёт объект.

Исследовать реальный объект и обработать неизвестное имяСамостоятельный пример
<?php
declare(strict_types=1);

class BaseJob {}
final class ImportJob extends BaseJob {}
echo implode(',', class_parents(new ImportJob())), "\n";
$name = 'MissingJob';
var_dump(class_exists($name, false) ? class_parents($name, false) : false);
Ожидаемый результат
BaseJob
bool(false)

Объект и строка поддерживаются одним параметром. false позволяет явно отличить неизвестный класс от класса без родителей, для которого результатом был бы пустой массив.

Интерфейсы: class_implements.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

class_usesВозвращает трейты, непосредственно используемые классом или трейтом.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

function class_uses($object_or_class, bool $autoload = true): array|false

Функция исследует одну декларацию. Она не добавляет автоматически трейты предков и вложенные трейты.

ПараметрЧто означает в задаче
$object_or_classОбъект или полное имя класса/трейта.
$autoloadРазрешить автозагрузку имени; по умолчанию true.
Часть контрактаЧто важно
Сигнатураfunction class_uses($object_or_class, bool $autoload = true): array|false
Результатarray имён трейтов или false для неизвестного типа.
Ошибки и особые значенияAutoloader может выбросить исключение; неправильный тип аргумента даёт TypeError.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице
Отличить трейты потомка и родителяСамостоятельный пример
<?php
declare(strict_types=1);

trait HasTimestamps {}
trait SoftDeletes {}
class StoredRecord { use HasTimestamps; }
final class ProductRecord extends StoredRecord { use SoftDeletes; }

echo 'Product: ', implode(',', class_uses(ProductRecord::class)), "\n";
echo 'Parent: ', implode(',', class_uses(get_parent_class(ProductRecord::class))), "\n";
Ожидаемый результат
Product: SoftDeletes
Parent: HasTimestamps

class_uses показывает только трейты, использованные непосредственно указанным классом. Чтобы получить всю цепочку, код отдельно проходит родителей.

Увидеть внешний трейт без автоматического раскрытия вложенногоСамостоятельный пример
<?php
declare(strict_types=1);

trait FormatsDate {}
trait Audited { use FormatsDate; }
final class Invoice { use Audited; }

echo implode(',', class_uses(Invoice::class)), "\n";
echo implode(',', class_uses(Audited::class)), "\n";
Ожидаемый результат
Audited
FormatsDate

Первый вызов не раскрывает trait-inside-trait. Второй исследует сам Audited и показывает его прямую зависимость.

Договоры класса: class_implements.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

spl_classesВозвращает список доступных классов и интерфейсов SPL.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

function spl_classes(): array

Функция описывает возможности текущей сборки PHP. Она не перечисляет пользовательские классы и не заменяет class_exists/interface_exists.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураfunction spl_classes(): array
Результатarray строк с именами доступных типов SPL.
Ошибки и особые значенияСпециальных рабочих отказов нет; состав зависит от версии PHP.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице
Проверить наличие нужных стандартных типовСамостоятельный пример
<?php
declare(strict_types=1);

$classes = spl_classes();
foreach (['ArrayIterator', 'RecursiveIteratorIterator', 'SplObjectStorage'] as $name) {
    echo $name, '=', in_array($name, $classes, true) ? 'yes' : 'no', "\n";
}
Ожидаемый результат
ArrayIterator=yes
RecursiveIteratorIterator=yes
SplObjectStorage=yes

Код не полагается на общий размер списка, который может меняться с версией PHP. Он проверяет именно три возможности, необходимые приложению.

Увидеть, что список содержит и интерфейсы, и исключенияСамостоятельный пример
<?php
declare(strict_types=1);

$classes = array_flip(spl_classes());
echo 'SplObserver=', isset($classes['SplObserver']) ? 'yes' : 'no', "\n";
echo 'LogicException=', isset($classes['LogicException']) ? 'yes' : 'no', "\n";
Ожидаемый результат
SplObserver=yes
LogicException=yes

Историческое имя функции говорит classes, но результат охватывает доступные SPL classes/interfaces. array_flip превращает список в быстрый набор имён для нескольких проверок.

Для конкретного класса используйте class_exists или interface_exists.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

iterator_applyВызывает callback для элементов Iterator, пока callback возвращает true.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

function iterator_apply(Traversable $iterator, callable $callback, ?array $args = null): int

Функция управляет перемещением итератора. Текущий элемент не передаётся callback автоматически: передайте сам Iterator через args или захватите его в closure.

ПараметрЧто означает в задаче
$iteratorTraversable, который будет последовательно обходиться.
$callbackВызываемая функция; true продолжает, false останавливает.
$argsНеобязательный массив аргументов callback; null означает без аргументов.
Часть контрактаЧто важно
Сигнатураfunction iterator_apply(Traversable $iterator, callable $callback, ?array $args = null): int
Результатint — число итераций, после которых callback вернул true.
Ошибки и особые значенияИсключение callback выходит наружу; бесконечный Iterator без условия остановки никогда не завершится.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице
Суммировать остатки, передав итератор и аккумулятор callbackСамостоятельный пример
<?php
declare(strict_types=1);

$stocks = new ArrayIterator([3, 0, 7]);
$total = 0;
$calls = iterator_apply(
    $stocks,
    static function (Iterator $iterator, int &$sum): bool {
        $sum += $iterator->current();
        return true;
    },
    [$stocks, &$total]
);
echo 'Сумма: ', $total, "\n";
echo 'Вызовов: ', $calls, "\n";
Ожидаемый результат
Сумма: 10
Вызовов: 3

Callback получает только значения из третьего аргумента; текущий элемент он читает через переданный Iterator. true разрешает перейти к следующему элементу.

Остановить обход после найденного заказаСамостоятельный пример
<?php
declare(strict_types=1);

$orders = new ArrayIterator(['new', 'paid', 'sent']);
$seen = [];
$calls = iterator_apply($orders, static function () use ($orders, &$seen): bool {
    $seen[] = $orders->current();
    return $orders->current() !== 'paid';
});
echo implode(',', $seen), "\n";
echo 'Продолжений: ', $calls, "\n";
Ожидаемый результат
new,paid
Продолжений: 2

Callback был вызван и для paid, затем false остановил применение. Возвращаемое число считает все выполненные вызовы callback, включая последний, вернувший false.

Материализация: iterator_to_array. Подсчёт: iterator_count.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

spl_autoload_registerДобавляет callable в очередь автозагрузчиков классов.

PHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.0.0) · SPL

function spl_autoload_register(?callable $callback = null, bool $throw = true, bool $prepend = false): bool

PHP вызывает загрузчики по очереди, когда встречает ещё не объявленный class/interface/trait/enum. Callback получает полное имя без начального обратного слеша.

ПараметрЧто означает в задаче
$callbackCallable загрузчика; null регистрирует стандартный spl_autoload.
$throwИсторический параметр; начиная с PHP 8 false игнорируется и сообщает notice.
$prependtrue добавляет callback в начало, false — в конец.
Часть контрактаЧто важно
Сигнатураfunction spl_autoload_register(?callable $callback = null, bool $throw = true, bool $prepend = false): bool
Результатtrue при успешной регистрации.
Ошибки и особые значенияНекорректный callback даёт TypeError. Исключение callback при загрузке выходит вызывающему коду.
ВерсииPHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.0.0)
Загрузить App\Product из безопасного каталога srcСамостоятельный пример
<?php
declare(strict_types=1);

$prefix = 'App\\';
$baseDir = __DIR__ . '/src/';
$loader = static function (string $class) use ($prefix, $baseDir): void {
    if (!str_starts_with($class, $prefix)) { return; }
    $relative = substr($class, strlen($prefix));
    $file = $baseDir . str_replace('\\', '/', $relative) . '.php';
    if (is_file($file)) { require $file; }
};
spl_autoload_register($loader);
echo (new App\Product('Лампа'))->name(), "\n";
spl_autoload_unregister($loader);
Ожидаемый результат
Лампа

Префикс проверяется до построения пути, а имя namespace превращается в относительный путь. В обычном проекте этот проверенный шаблон генерирует Composer по PSR-4.

Поставить приоритетный загрузчик в начало очередиСамостоятельный пример
<?php
declare(strict_types=1);

$fallback = static function (string $class): void { echo "fallback\n"; };
$primary = static function (string $class): void {
    echo "primary\n";
    if ($class === 'App\\Ready') { require __DIR__ . '/src/Ready.php'; }
};
spl_autoload_register($fallback);
spl_autoload_register($primary, true, true);
echo App\Ready::status(), "\n";
spl_autoload_unregister($primary);
spl_autoload_unregister($fallback);
Ожидаемый результат
primary
ready

prepend=true ставит primary раньше fallback. Как только класс объявлен, PHP прекращает очередь. Частое изменение приоритетов усложняет диагностику; у Composer порядок обычно централизован.

Список очереди: spl_autoload_functions. Удаление: spl_autoload_unregister.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

spl_autoload_unregisterУдаляет ранее зарегистрированный callback автозагрузки.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

function spl_autoload_unregister(callable $callback): bool

Функция меняет глобальную для процесса очередь загрузчиков. Она не выгружает уже объявленные классы.

ПараметрЧто означает в задаче
$callbackТот же callable, который ранее передали register.
Часть контрактаЧто важно
Сигнатураfunction spl_autoload_unregister(callable $callback): bool
Результатtrue при успешном удалении, false, если callable не зарегистрирован.
Ошибки и особые значенияНекорректный callable даёт TypeError.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице
Убрать конкретный closure из очередиСамостоятельный пример
<?php
declare(strict_types=1);

$loader = static function (string $class): void {};
spl_autoload_register($loader);
echo in_array($loader, spl_autoload_functions(), true) ? "before=yes\n" : "before=no\n";
spl_autoload_unregister($loader);
echo in_array($loader, spl_autoload_functions(), true) ? "after=yes\n" : "after=no\n";
Ожидаемый результат
before=yes
after=no

Для удаления нужен тот же closure-объект, поэтому он сохранён в переменной. Новая анонимная функция с тем же телом не равна зарегистрированной.

Очистить учебную очередь без устаревшего трюкаСамостоятельный пример
<?php
declare(strict_types=1);

$one = static function (string $class): void {};
$two = static function (string $class): void {};
spl_autoload_register($one);
spl_autoload_register($two);
foreach (spl_autoload_functions() as $loader) {
    spl_autoload_unregister($loader);
}
echo count(spl_autoload_functions()), "\n";
Ожидаемый результат
0

С PHP 8.5 передача spl_autoload_call как способ очистить всё устарела. Явный снимок списка и удаление каждого callback показывают реальное намерение.

Регистрация: spl_autoload_register.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

spl_autoload_functionsВозвращает текущую очередь зарегистрированных автозагрузчиков.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

function spl_autoload_functions(): array

Порядок массива совпадает с порядком вызова загрузчиков. Элементы имеют форму исходных callable.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураfunction spl_autoload_functions(): array
Результатarray; начиная с PHP 8 пустая очередь — пустой массив.
Ошибки и особые значенияСпециальных исключений нет.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице
Посмотреть форму двух зарегистрированных callbackСамостоятельный пример
<?php
declare(strict_types=1);

final class Loader { public static function load(string $class): void {} }
$closure = static function (string $class): void {};
spl_autoload_register([Loader::class, 'load']);
spl_autoload_register($closure);
$list = spl_autoload_functions();
echo count($list), "\n";
echo is_array($list[0]) ? 'static-method' : get_debug_type($list[0]), "\n";
echo get_debug_type($list[1]), "\n";
spl_autoload_unregister([Loader::class, 'load']);
spl_autoload_unregister($closure);
Ожидаемый результат
2
static-method
Closure

Элемент списка сохраняет форму callable: массив класса/метода или объект Closure. Это помогает диагностировать порядок очереди.

Получить пустой массив без зарегистрированных загрузчиковСамостоятельный пример
<?php
declare(strict_types=1);

var_dump(spl_autoload_functions());
Ожидаемый результат
array(0) {
}

В PHP 8 и новее функция всегда возвращает array; отсутствие загрузчиков представлено пустым массивом, а не false.

Изменяют очередь spl_autoload_register и spl_autoload_unregister.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

spl_autoload_callПринудительно вызывает зарегистрированную очередь автозагрузки для имени класса.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

function spl_autoload_call(string $class): void

Функция передаёт имя каждому загрузчику по обычным правилам autoload. Обычно вызов инициирует сам движок при обращении к неизвестному типу.

ПараметрЧто означает в задаче
$classПолное имя класса/interface/trait/enum без начального обратного слеша.
Часть контрактаЧто важно
Сигнатураfunction spl_autoload_call(string $class): void
РезультатНичего не возвращает (void); проверяйте class_exists/interface_exists после вызова.
Ошибки и особые значенияИсключение callback выходит наружу. Отсутствие найденного класса само по себе не даёт полезного return.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице
Явно прогнать очередь для известного имени классаСамостоятельный пример
<?php
declare(strict_types=1);

$loader = static function (string $class): void {
    echo 'load:', $class, "\n";
    if ($class === 'Demo\\Tool') { require __DIR__ . '/src/Tool.php'; }
};
spl_autoload_register($loader);
spl_autoload_call('Demo\\Tool');
echo Demo\Tool::status(), "\n";
spl_autoload_unregister($loader);
Ожидаемый результат
load:Demo\Tool
ready

Обычно PHP сам вызывает очередь при первом обращении к Demo\Tool. Прямой вызов полезен загрузчику-координатору или диагностике, но не заменяет проверку class_exists после попытки.

Увидеть исключение одного загрузчикаСамостоятельный пример
<?php
declare(strict_types=1);

$loader = static function (string $class): void {
    throw new RuntimeException('Каталог классов недоступен');
};
spl_autoload_register($loader);
try { spl_autoload_call('Demo\\Missing'); }
catch (RuntimeException $error) { echo $error->getMessage(), "\n"; }
finally { spl_autoload_unregister($loader); }
Ожидаемый результат
Каталог классов недоступен

Исключение не превращается в false и не заставляет очередь безопасно продолжиться. finally убирает учебный callback даже после отказа.

Очередь создаёт spl_autoload_register.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

spl_autoload_extensionsУстанавливает или возвращает расширения файлов для стандартного spl_autoload.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

function spl_autoload_extensions(?string $file_extensions = null): string

Значение — одна строка с разделёнными запятыми суффиксами. Настройка относится к встроенному загрузчику, а не ко всем пользовательским callbacks.

ПараметрЧто означает в задаче
$file_extensionsНовая строка расширений или null, чтобы только прочитать текущую.
Часть контрактаЧто важно
Сигнатураfunction spl_autoload_extensions(?string $file_extensions = null): string
Результатstring текущего списка.
Ошибки и особые значенияНеверный тип даёт TypeError.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице
Изменить и восстановить список расширений стандартного загрузчикаСамостоятельный пример
<?php
declare(strict_types=1);

$before = spl_autoload_extensions();
echo spl_autoload_extensions('.class.php,.php'), "\n";
spl_autoload_extensions($before);
echo spl_autoload_extensions() === $before ? "restored\n" : "changed\n";
Ожидаемый результат
.class.php,.php
restored

Вызов с аргументом одновременно устанавливает и возвращает строку. Восстановление важно в общей среде теста, потому что настройка глобальна для процесса.

Показать, что это строка суффиксов, а не карта namespaceСамостоятельный пример
<?php
declare(strict_types=1);

$before = spl_autoload_extensions();
$configured = spl_autoload_extensions('.inc,.php');
echo implode('|', explode(',', $configured)), "\n";
spl_autoload_extensions($before);
Ожидаемый результат
.inc|.php

Функция не знает префиксов App\ и путей src/. Она настраивает лишь суффиксы для стандартного spl_autoload.

Встроенная реализация: spl_autoload.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

spl_autoloadСтандартная реализация автозагрузки по имени класса и расширениям.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

function spl_autoload(string $class, ?string $file_extensions = null): void

Функция приводит имя класса к нижнему регистру и ищет файл с разрешённым суффиксом через include_path. Она историческая и не является полноценным PSR-4 loader.

ПараметрЧто означает в задаче
$classИмя загружаемого класса.
$file_extensionsНеобязательная строка расширений; null использует spl_autoload_extensions.
Часть контрактаЧто важно
Сигнатураfunction spl_autoload(string $class, ?string $file_extensions = null): void
РезультатНичего не возвращает (void); успех виден по объявленному классу.
Ошибки и особые значенияОфициальная страница документирует LogicException при ненайденном классе без других autoloaders. Прямой вызов в PHP 8.5.11 вернул void без исключения; после попытки проверяйте class_exists($name, false). Обычное обращение к так и не загруженному классу завершается Error.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице
Загрузить DemoTool из файла с явным расширениемСамостоятельный пример
<?php
declare(strict_types=1);

$oldPath = get_include_path();
set_include_path(__DIR__);
spl_autoload('DemoTool', '.inc');
echo DemoTool::status(), "\n";
set_include_path($oldPath);
Ожидаемый результат
loaded

Стандартный загрузчик приводит имя класса к нижнему регистру и ищет файл в include_path. Поэтому fixture называется demotool.inc. Для namespace и структуры src удобнее Composer.

Обработать отсутствие файла стандартного загрузчикаСамостоятельный пример
<?php
declare(strict_types=1);

spl_autoload('MissingWidget', '.php');
echo class_exists('MissingWidget', false) ? "loaded\n" : "not loaded\n";
Ожидаемый результат
not loaded

Прямой вызов в проверенном PHP 8.5.11 возвращается без исключения и без класса. Официальная страница документирует LogicException, когда класс не найден и нет других autoloaders; php-src 8.5.11 для прямого вызова такой throw не содержит. Поэтому надёжный код проверяет class_exists, а обычное разрешение неизвестного класса в конце даёт Error.

Настройка расширений: spl_autoload_extensions. Регистрация: spl_autoload_register.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

spl_object_hashВозвращает строковый handle живого объекта в текущем процессе.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

function spl_object_hash(object $object): string

Назначение совпадает со spl_object_id, но форма строковая. Значение уникально только среди одновременно живых объектов; после уничтожения может быть использовано снова.

ПараметрЧто означает в задаче
$objectЛюбой объект.
Часть контрактаЧто важно
Сигнатураfunction spl_object_hash(object $object): string
Результатstring временной идентичности объекта.
Ошибки и особые значенияНе-объект даёт TypeError.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице
Сравнить строковые handles без вывода случайного значенияСамостоятельный пример
<?php
declare(strict_types=1);

$product = new stdClass();
$alias = $product;
$other = new stdClass();
echo hash_equals(spl_object_hash($product), spl_object_hash($alias)) ? "same\n" : "different\n";
echo hash_equals(spl_object_hash($product), spl_object_hash($other)) ? "same\n" : "different\n";
Ожидаемый результат
same
different

Сам hash зависит от процесса, поэтому пример проверяет отношение, а не фиксированную строку. hash_equals здесь не добавляет защиту секрета: object hash не секрет и не криптографическая подпись.

Сделать временную диагностическую карту объектовСамостоятельный пример
<?php
declare(strict_types=1);

$first = (object) ['name' => 'import-1'];
$second = (object) ['name' => 'import-2'];
$states = [
    spl_object_hash($first) => 'started',
    spl_object_hash($second) => 'queued',
];
echo count($states), "\n";
echo $first->name, ':', $states[spl_object_hash($first)], "\n";
Ожидаемый результат
2
import-1:started

Карта работает, пока объекты удерживаются переменными. Для жизненного цикла worker лучше SplObjectStorage/WeakMap; для задания между процессами нужен собственный устойчивый job ID.

Числовая форма: spl_object_id.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplDoublyLinkedList::pushДобавить остановку в конец

PHP 5.3+; примеры рассчитаны на PHP 8.2+ · SPL

public function SplDoublyLinkedList::push(mixed $value): void

push("Магазин") создаёт новый последний узел; существующий маршрут сохраняет порядок.

ПараметрЧто означает в задаче
valueСохраняемое значение любого типа. Для объекта сохраняется идентичность; глубокое копирование не происходит.
Часть контрактаЧто важно
Сигнатураpublic function SplDoublyLinkedList::push(mixed $value): void
Результатvoid; следующее чтение top() получает добавленное значение.
Ошибки и особые значенияАргумент обязателен; выделение памяти ограничено ресурсами процесса.
ВерсииPHP 5.3+; примеры рассчитаны на PHP 8.2+
Составить порядок остановокСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Склад');
$route->push('Магазин');
$route->unshift('Гараж');
foreach ($route as $index => $stop) {
    echo $index, ': ', $stop, "\n";
}
Ожидаемый результат
0: Гараж
1: Склад
2: Магазин

push добавил Склад и Магазин в конец, unshift — Гараж в начало. foreach передаёт текущий номер в $index, строку в $stop; => связывает две переменные обхода. Это позиции в текущем списке, не постоянные ID адресов.

Скачать самостоятельный пример с результатом и README

Отменить последнее изменение ценыСамостоятельный пример
<?php
declare(strict_types=1);

$history = new SplStack();
$price = 500;
$history->push($price);
$price = 450;
$history->push($price);
$price = 400;
$price = $history->pop();
echo 'После отмены: ', $price, "\n";
$price = $history->pop();
echo 'После второй отмены: ', $price, "\n";
Ожидаемый результат
После отмены: 450
После второй отмены: 500

Перед изменением сохраняется старая цена. В стек последовательно попали 500 и 450; pop возвращает последнюю — 450 — в присваивание $price. Второй pop возвращает 500. Стек содержит числа, а не команды и не резервную копию базы; отмену связанных изменений нужно проектировать отдельно.

Скачать самостоятельный пример с результатом и README

Продолжение: SplDoublyLinkedList::count, SplDoublyLinkedList::isEmpty.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplDoublyLinkedList::unshiftДобавить остановку перед началом

PHP 5.3+; примеры рассчитаны на PHP 8.2+ · SPL

public function SplDoublyLinkedList::unshift(mixed $value): void

unshift("Гараж") делает новый первый узел. Числовые позиции прежних узлов меняются.

ПараметрЧто означает в задаче
valueСохраняемое значение любого типа. Для объекта сохраняется идентичность; глубокое копирование не происходит.
Часть контрактаЧто важно
Сигнатураpublic function SplDoublyLinkedList::unshift(mixed $value): void
Результатvoid; bottom() теперь читает новое начало.
Ошибки и особые значенияАргумент обязателен; выделение памяти ограничено ресурсами процесса.
ВерсииPHP 5.3+; примеры рассчитаны на PHP 8.2+
Составить порядок остановокСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Склад');
$route->push('Магазин');
$route->unshift('Гараж');
foreach ($route as $index => $stop) {
    echo $index, ': ', $stop, "\n";
}
Ожидаемый результат
0: Гараж
1: Склад
2: Магазин

push добавил Склад и Магазин в конец, unshift — Гараж в начало. foreach передаёт текущий номер в $index, строку в $stop; => связывает две переменные обхода. Это позиции в текущем списке, не постоянные ID адресов.

Скачать самостоятельный пример с результатом и README

Вставка, замена и удаление — три разных действияСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Склад');
$route->push('Магазин');
$route->add(1, 'Почта');
$route->offsetSet(0, 'Новый склад');
$route->offsetSet(null, 'Гараж');
$route->offsetUnset(2);
foreach ($route as $index => $stop) {
    echo $index, ': ', $stop, "\n";
}
Ожидаемый результат
0: Новый склад
1: Почта
2: Гараж

add(1) вставляет Почту перед Магазином. offsetSet(0) заменяет Склад; null добавляет в физический конец. offsetUnset(2) удаляет уже сдвинувшийся Магазин. Значения не печатаются этими void-методами: окончательное состояние показывает foreach.

Скачать самостоятельный пример с результатом и README

Продолжение: SplDoublyLinkedList::count, SplDoublyLinkedList::isEmpty.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplDoublyLinkedList::popВернуть и удалить последний узел

PHP 5.3+; примеры рассчитаны на PHP 8.2+ · SPL

public function SplDoublyLinkedList::pop(): mixed

В $stop = $route->pop() возвращённая строка переходит в $stop, а физический конец удаляется. Направление foreach это действие не меняет.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplDoublyLinkedList::pop(): mixed
Результатmixed: значение удалённого конца.
Ошибки и особые значенияЧтение top/bottom и удаление pop/shift из пустого списка вызывают RuntimeException. Перед обычной обработкой проверяйте isEmpty(); null, 0 и пустая строка могут быть настоящими значениями.
ВерсииPHP 5.3+; примеры рассчитаны на PHP 8.2+
Прочитать и убрать пройденные остановкиСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Гараж');
$route->push('Склад');
$route->push('Магазин');
echo 'Первый: ', $route->bottom(), "; последний: ", $route->top(), "\n";
echo 'Пройден: ', $route->shift(), "\n";
echo 'Отменён: ', $route->pop(), "\n";
echo 'Следующий: ', $route->bottom(), "\n";
Ожидаемый результат
Первый: Гараж; последний: Магазин
Пройден: Гараж
Отменён: Магазин
Следующий: Склад

bottom и top читают края без удаления. shift возвращает Гараж и удаляет начало; pop возвращает Магазин и удаляет конец. В списке остаётся Склад. Возвращённые строки сразу занимают аргументы echo.

Скачать самостоятельный пример с результатом и README

Отменить последнее изменение ценыСамостоятельный пример
<?php
declare(strict_types=1);

$history = new SplStack();
$price = 500;
$history->push($price);
$price = 450;
$history->push($price);
$price = 400;
$price = $history->pop();
echo 'После отмены: ', $price, "\n";
$price = $history->pop();
echo 'После второй отмены: ', $price, "\n";
Ожидаемый результат
После отмены: 450
После второй отмены: 500

Перед изменением сохраняется старая цена. В стек последовательно попали 500 и 450; pop возвращает последнюю — 450 — в присваивание $price. Второй pop возвращает 500. Стек содержит числа, а не команды и не резервную копию базы; отмену связанных изменений нужно проектировать отдельно.

Скачать самостоятельный пример с результатом и README

Продолжение: SplDoublyLinkedList::count, SplDoublyLinkedList::isEmpty.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplDoublyLinkedList::shiftВернуть и удалить первый узел

PHP 5.3+; примеры рассчитаны на PHP 8.2+ · SPL

public function SplDoublyLinkedList::shift(): mixed

shift() потребляет физическое начало и возвращает его значение. Следующий узел становится началом.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplDoublyLinkedList::shift(): mixed
Результатmixed: значение удалённого начала.
Ошибки и особые значенияЧтение top/bottom и удаление pop/shift из пустого списка вызывают RuntimeException. Перед обычной обработкой проверяйте isEmpty(); null, 0 и пустая строка могут быть настоящими значениями.
ВерсииPHP 5.3+; примеры рассчитаны на PHP 8.2+
Прочитать и убрать пройденные остановкиСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Гараж');
$route->push('Склад');
$route->push('Магазин');
echo 'Первый: ', $route->bottom(), "; последний: ", $route->top(), "\n";
echo 'Пройден: ', $route->shift(), "\n";
echo 'Отменён: ', $route->pop(), "\n";
echo 'Следующий: ', $route->bottom(), "\n";
Ожидаемый результат
Первый: Гараж; последний: Магазин
Пройден: Гараж
Отменён: Магазин
Следующий: Склад

bottom и top читают края без удаления. shift возвращает Гараж и удаляет начало; pop возвращает Магазин и удаляет конец. В списке остаётся Склад. Возвращённые строки сразу занимают аргументы echo.

Скачать самостоятельный пример с результатом и README

Ограничить число остановокСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Склад');
$limit = 2;
if ($route->count() < $limit) {
    $route->push('Магазин');
}
echo 'Остановок: ', count($route), " из ", $limit, "\n";
while (!$route->isEmpty()) {
    echo 'Едем: ', $route->shift(), "\n";
}
Ожидаемый результат
Остановок: 2 из 2
Едем: Склад
Едем: Магазин

count возвращает целое количество узлов, которое используется в сравнении с лимитом. count($route) вызывает договор Countable. isEmpty управляет обработкой, а не служит заменой результатам поездок.

Скачать самостоятельный пример с результатом и README

Продолжение: SplDoublyLinkedList::count, SplDoublyLinkedList::isEmpty.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplDoublyLinkedList::topПрочитать конец без удаления

PHP 5.3+; примеры рассчитаны на PHP 8.2+ · SPL

public function SplDoublyLinkedList::top(): mixed

top() возвращает физически последний узел; повторное чтение оставляет список на месте.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplDoublyLinkedList::top(): mixed
Результатmixed: значение конца.
Ошибки и особые значенияЧтение top/bottom и удаление pop/shift из пустого списка вызывают RuntimeException. Перед обычной обработкой проверяйте isEmpty(); null, 0 и пустая строка могут быть настоящими значениями.
ВерсииPHP 5.3+; примеры рассчитаны на PHP 8.2+
Прочитать и убрать пройденные остановкиСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Гараж');
$route->push('Склад');
$route->push('Магазин');
echo 'Первый: ', $route->bottom(), "; последний: ", $route->top(), "\n";
echo 'Пройден: ', $route->shift(), "\n";
echo 'Отменён: ', $route->pop(), "\n";
echo 'Следующий: ', $route->bottom(), "\n";
Ожидаемый результат
Первый: Гараж; последний: Магазин
Пройден: Гараж
Отменён: Магазин
Следующий: Склад

bottom и top читают края без удаления. shift возвращает Гараж и удаляет начало; pop возвращает Магазин и удаляет конец. В списке остаётся Склад. Возвращённые строки сразу занимают аргументы echo.

Скачать самостоятельный пример с результатом и README

Посмотреть историю, затем отменить шагСамостоятельный пример
<?php
declare(strict_types=1);

$history = new SplStack();
$history->push('Создан черновик');
$history->push('Изменён заголовок');
foreach ($history as $step) {
    echo 'История: ', $step, "\n";
}
echo 'Отменяем: ', $history->pop(), "\n";
echo 'Остаётся: ', $history->top(), "\n";
Ожидаемый результат
История: Изменён заголовок
История: Создан черновик
Отменяем: Изменён заголовок
Остаётся: Создан черновик

SplStack фиксирует LIFO — «последний пришёл, первый вышел». foreach в режиме KEEP не уничтожает историю; затем pop действительно удаляет последнюю запись. top только читает оставшуюся. Надпись «Отменяем» показывает выбранную запись, а не автоматическое изменение документа.

Скачать самостоятельный пример с результатом и README

Продолжение: SplDoublyLinkedList::count, SplDoublyLinkedList::isEmpty.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplDoublyLinkedList::bottomПрочитать начало без удаления

PHP 5.3+; примеры рассчитаны на PHP 8.2+ · SPL

public function SplDoublyLinkedList::bottom(): mixed

bottom() возвращает физически первый узел. Даже при LIFO top/bottom продолжают обозначать физические концы.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplDoublyLinkedList::bottom(): mixed
Результатmixed: значение начала.
Ошибки и особые значенияЧтение top/bottom и удаление pop/shift из пустого списка вызывают RuntimeException. Перед обычной обработкой проверяйте isEmpty(); null, 0 и пустая строка могут быть настоящими значениями.
ВерсииPHP 5.3+; примеры рассчитаны на PHP 8.2+
Прочитать и убрать пройденные остановкиСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Гараж');
$route->push('Склад');
$route->push('Магазин');
echo 'Первый: ', $route->bottom(), "; последний: ", $route->top(), "\n";
echo 'Пройден: ', $route->shift(), "\n";
echo 'Отменён: ', $route->pop(), "\n";
echo 'Следующий: ', $route->bottom(), "\n";
Ожидаемый результат
Первый: Гараж; последний: Магазин
Пройден: Гараж
Отменён: Магазин
Следующий: Склад

bottom и top читают края без удаления. shift возвращает Гараж и удаляет начало; pop возвращает Магазин и удаляет конец. В списке остаётся Склад. Возвращённые строки сразу занимают аргументы echo.

Скачать самостоятельный пример с результатом и README

Получить первое заданиеСамостоятельный пример
<?php
declare(strict_types=1);

$jobs = new SplQueue();
$jobs->enqueue('Импорт');
$jobs->enqueue('Отчёт');
$job = $jobs->dequeue();
echo 'Выполняем: ', $job, "\n";
echo 'Следующее: ', $jobs->bottom(), "\n";
Ожидаемый результат
Выполняем: Импорт
Следующее: Отчёт

После двух enqueue очередь содержит Импорт → Отчёт. dequeue удаляет Импорт и возвращает эту строку в присваивание $job. bottom читает оставшийся Отчёт без удаления. Ни один метод здесь сам не выполняет задание: полезное действие обозначено выводом.

Скачать самостоятельный пример с результатом и README

Продолжение: SplDoublyLinkedList::count, SplDoublyLinkedList::isEmpty.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplDoublyLinkedList::addВставить новый узел перед позицией

PHP 5.3+; примеры рассчитаны на PHP 8.2+ · SPL

public function SplDoublyLinkedList::add(int $index, mixed $value): void

В add(1, "Почта") число 1 попадает в $index, строка — в $value. Прежний узел 1 и следующие сохраняются, сдвигаются на одну позицию. Индекс count() добавляет в конец.

ПараметрЧто означает в задаче
indexПозиция вставки: от 0 до count() включительно.
valueНовое значение любого типа.
Часть контрактаЧто важно
Сигнатураpublic function SplDoublyLinkedList::add(int $index, mixed $value): void
Результатvoid: новый узел добавлен; сам список не возвращается.
Ошибки и особые значенияНесуществующая позиция — OutOfRangeException. Неподходящий тип аргумента в современном PHP — TypeError; старые страницы могут объединять эти случаи как ошибку индекса.
ВерсииPHP 5.3+; примеры рассчитаны на PHP 8.2+
Вставка, замена и удаление — три разных действияСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Склад');
$route->push('Магазин');
$route->add(1, 'Почта');
$route->offsetSet(0, 'Новый склад');
$route->offsetSet(null, 'Гараж');
$route->offsetUnset(2);
foreach ($route as $index => $stop) {
    echo $index, ': ', $stop, "\n";
}
Ожидаемый результат
0: Новый склад
1: Почта
2: Гараж

add(1) вставляет Почту перед Магазином. offsetSet(0) заменяет Склад; null добавляет в физический конец. offsetUnset(2) удаляет уже сдвинувшийся Магазин. Значения не печатаются этими void-методами: окончательное состояние показывает foreach.

Скачать самостоятельный пример с результатом и README

Проверить позицию перед исправлением маршрутаСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Склад');
$index = 2;
if ($route->offsetExists($index)) {
    echo $route->offsetGet($index), "\n";
} else {
    echo 'Остановки ', $index, " нет\n";
}
try {
    $route->offsetSet(1, 'Гараж');
} catch (OutOfRangeException $error) {
    echo "Заменить нельзя; вставляем в конец\n";
    $route->add(1, 'Гараж');
}
echo $route->offsetGet(1), "\n";
Ожидаемый результат
Остановки 2 нет
Заменить нельзя; вставляем в конец
Гараж

У единственного узла индекс 0. offsetSet(1) не расширяет список, потому что позиции ещё нет; add(1) разрешает вставку на границе count. catch обрабатывает намеренно показанную ошибку, затем новый узел доступен по позиции 1.

Скачать самостоятельный пример с результатом и README

Продолжение: SplDoublyLinkedList::offsetSet, SplDoublyLinkedList::count.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplDoublyLinkedList::offsetExistsВыбрать действие по наличию позиции

PHP 5.3+; примеры рассчитаны на PHP 8.2+ · SPL

public function SplDoublyLinkedList::offsetExists($index): bool

Проверка позиции не извлекает узел и не перемещает текущий указатель. Для списка существование узла не зависит от того, содержит ли он null.

ПараметрЧто означает в задаче
indexЦелочисленная текущая позиция от 0 до count()-1; при LIFO отсчёт доступа идёт от конца. Это не постоянный ID узла.
Часть контрактаЧто важно
Сигнатураpublic function SplDoublyLinkedList::offsetExists($index): bool
Результатbool: true для допустимого индекса, false для отсутствующего.
Ошибки и особые значенияИндекс за границей возвращает false; неверный тип может вызвать TypeError.
ВерсииPHP 5.3+; примеры рассчитаны на PHP 8.2+
Проверить позицию перед исправлением маршрутаСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Склад');
$index = 2;
if ($route->offsetExists($index)) {
    echo $route->offsetGet($index), "\n";
} else {
    echo 'Остановки ', $index, " нет\n";
}
try {
    $route->offsetSet(1, 'Гараж');
} catch (OutOfRangeException $error) {
    echo "Заменить нельзя; вставляем в конец\n";
    $route->add(1, 'Гараж');
}
echo $route->offsetGet(1), "\n";
Ожидаемый результат
Остановки 2 нет
Заменить нельзя; вставляем в конец
Гараж

У единственного узла индекс 0. offsetSet(1) не расширяет список, потому что позиции ещё нет; add(1) разрешает вставку на границе count. catch обрабатывает намеренно показанную ошибку, затем новый узел доступен по позиции 1.

Скачать самостоятельный пример с результатом и README

Развернуть просмотр и отдельно включить потреблениеСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Склад');
$route->push('Магазин');
$route->setIteratorMode(SplDoublyLinkedList::IT_MODE_LIFO | SplDoublyLinkedList::IT_MODE_KEEP);
echo 'Позиция 0 в LIFO: ', $route[0], "\n";
foreach ($route as $stop) { echo 'Обратно: ', $stop, "\n"; }
echo 'Сохранено: ', $route->count(), "\n";
$mode = $route->getIteratorMode();
$route->setIteratorMode($mode | SplDoublyLinkedList::IT_MODE_DELETE);
foreach ($route as $stop) { echo 'Пройден: ', $stop, "\n"; }
echo 'Осталось: ', $route->count(), "\n";
Ожидаемый результат
Позиция 0 в LIFO: Магазин
Обратно: Магазин
Обратно: Склад
Сохранено: 2
Пройден: Магазин
Пройден: Склад
Осталось: 0

:: выбирает именованную константу класса; побитовое | объединяет независимые настройки. LIFO меняет направление просмотра и доступ по индексам, но не физические top/bottom. KEEP сохраняет список. Во втором обходе DELETE удаляет пройденный узел при переходе итератора дальше; break до перехода может оставить текущий узел.

Скачать самостоятельный пример с результатом и README

Продолжение: SplDoublyLinkedList::add, SplDoublyLinkedList::offsetGet.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplDoublyLinkedList::offsetGetПолучить значение по позиции

PHP 5.3+; примеры рассчитаны на PHP 8.2+ · SPL

public function SplDoublyLinkedList::offsetGet($index): mixed

$route->offsetGet(1) и $route[1] читают один узел. Полученное значение можно присвоить переменной или передать в echo.

ПараметрЧто означает в задаче
indexЦелочисленная текущая позиция от 0 до count()-1; при LIFO отсчёт доступа идёт от конца. Это не постоянный ID узла.
Часть контрактаЧто важно
Сигнатураpublic function SplDoublyLinkedList::offsetGet($index): mixed
Результатmixed: хранимое значение, включая null; список не изменяется.
Ошибки и особые значенияНесуществующая позиция — OutOfRangeException. Неподходящий тип аргумента в современном PHP — TypeError; старые страницы могут объединять эти случаи как ошибку индекса.
ВерсииPHP 5.3+; примеры рассчитаны на PHP 8.2+
Проверить позицию перед исправлением маршрутаСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Склад');
$index = 2;
if ($route->offsetExists($index)) {
    echo $route->offsetGet($index), "\n";
} else {
    echo 'Остановки ', $index, " нет\n";
}
try {
    $route->offsetSet(1, 'Гараж');
} catch (OutOfRangeException $error) {
    echo "Заменить нельзя; вставляем в конец\n";
    $route->add(1, 'Гараж');
}
echo $route->offsetGet(1), "\n";
Ожидаемый результат
Остановки 2 нет
Заменить нельзя; вставляем в конец
Гараж

У единственного узла индекс 0. offsetSet(1) не расширяет список, потому что позиции ещё нет; add(1) разрешает вставку на границе count. catch обрабатывает намеренно показанную ошибку, затем новый узел доступен по позиции 1.

Скачать самостоятельный пример с результатом и README

Развернуть просмотр и отдельно включить потреблениеСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Склад');
$route->push('Магазин');
$route->setIteratorMode(SplDoublyLinkedList::IT_MODE_LIFO | SplDoublyLinkedList::IT_MODE_KEEP);
echo 'Позиция 0 в LIFO: ', $route[0], "\n";
foreach ($route as $stop) { echo 'Обратно: ', $stop, "\n"; }
echo 'Сохранено: ', $route->count(), "\n";
$mode = $route->getIteratorMode();
$route->setIteratorMode($mode | SplDoublyLinkedList::IT_MODE_DELETE);
foreach ($route as $stop) { echo 'Пройден: ', $stop, "\n"; }
echo 'Осталось: ', $route->count(), "\n";
Ожидаемый результат
Позиция 0 в LIFO: Магазин
Обратно: Магазин
Обратно: Склад
Сохранено: 2
Пройден: Магазин
Пройден: Склад
Осталось: 0

:: выбирает именованную константу класса; побитовое | объединяет независимые настройки. LIFO меняет направление просмотра и доступ по индексам, но не физические top/bottom. KEEP сохраняет список. Во втором обходе DELETE удаляет пройденный узел при переходе итератора дальше; break до перехода может оставить текущий узел.

Скачать самостоятельный пример с результатом и README

Продолжение: SplDoublyLinkedList::offsetSet, SplDoublyLinkedList::count.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplDoublyLinkedList::offsetSetЗаменить узел или явно добавить через null

PHP 5.3+; примеры рассчитаны на PHP 8.2+ · SPL

public function SplDoublyLinkedList::offsetSet($index, mixed $value): void

offsetSet(0, "Новый склад") заменяет существующий узел; offsetSet(null, "Гараж") добавляет в физический конец, как $route[] = "Гараж". Числовой индекс count() сам список не расширяет.

ПараметрЧто означает в задаче
indexСуществующая int-позиция либо null для добавления.
valueНовое значение.
Часть контрактаЧто важно
Сигнатураpublic function SplDoublyLinkedList::offsetSet($index, mixed $value): void
Результатvoid: изменяется список, не возвращается копия.
Ошибки и особые значенияНесуществующая позиция — OutOfRangeException. Неподходящий тип аргумента в современном PHP — TypeError; старые страницы могут объединять эти случаи как ошибку индекса.
ВерсииPHP 5.3+; примеры рассчитаны на PHP 8.2+
Вставка, замена и удаление — три разных действияСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Склад');
$route->push('Магазин');
$route->add(1, 'Почта');
$route->offsetSet(0, 'Новый склад');
$route->offsetSet(null, 'Гараж');
$route->offsetUnset(2);
foreach ($route as $index => $stop) {
    echo $index, ': ', $stop, "\n";
}
Ожидаемый результат
0: Новый склад
1: Почта
2: Гараж

add(1) вставляет Почту перед Магазином. offsetSet(0) заменяет Склад; null добавляет в физический конец. offsetUnset(2) удаляет уже сдвинувшийся Магазин. Значения не печатаются этими void-методами: окончательное состояние показывает foreach.

Скачать самостоятельный пример с результатом и README

Проверить позицию перед исправлением маршрутаСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Склад');
$index = 2;
if ($route->offsetExists($index)) {
    echo $route->offsetGet($index), "\n";
} else {
    echo 'Остановки ', $index, " нет\n";
}
try {
    $route->offsetSet(1, 'Гараж');
} catch (OutOfRangeException $error) {
    echo "Заменить нельзя; вставляем в конец\n";
    $route->add(1, 'Гараж');
}
echo $route->offsetGet(1), "\n";
Ожидаемый результат
Остановки 2 нет
Заменить нельзя; вставляем в конец
Гараж

У единственного узла индекс 0. offsetSet(1) не расширяет список, потому что позиции ещё нет; add(1) разрешает вставку на границе count. catch обрабатывает намеренно показанную ошибку, затем новый узел доступен по позиции 1.

Скачать самостоятельный пример с результатом и README

Продолжение: SplDoublyLinkedList::add, SplDoublyLinkedList::offsetGet.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplDoublyLinkedList::offsetUnsetУдалить одну позицию маршрута

PHP 5.3+; примеры рассчитаны на PHP 8.2+ · SPL

public function SplDoublyLinkedList::offsetUnset($index): void

offsetUnset(2), как unset($route[2]), убирает узел целиком; последующие позиции изменятся. Это отличается от записи null в существующий узел.

ПараметрЧто означает в задаче
indexЦелочисленная текущая позиция от 0 до count()-1; при LIFO отсчёт доступа идёт от конца. Это не постоянный ID узла.
Часть контрактаЧто важно
Сигнатураpublic function SplDoublyLinkedList::offsetUnset($index): void
Результатvoid; прежнее значение не возвращается.
Ошибки и особые значенияНесуществующая позиция — OutOfRangeException. Неподходящий тип аргумента в современном PHP — TypeError; старые страницы могут объединять эти случаи как ошибку индекса.
ВерсииPHP 5.3+; примеры рассчитаны на PHP 8.2+
Вставка, замена и удаление — три разных действияСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Склад');
$route->push('Магазин');
$route->add(1, 'Почта');
$route->offsetSet(0, 'Новый склад');
$route->offsetSet(null, 'Гараж');
$route->offsetUnset(2);
foreach ($route as $index => $stop) {
    echo $index, ': ', $stop, "\n";
}
Ожидаемый результат
0: Новый склад
1: Почта
2: Гараж

add(1) вставляет Почту перед Магазином. offsetSet(0) заменяет Склад; null добавляет в физический конец. offsetUnset(2) удаляет уже сдвинувшийся Магазин. Значения не печатаются этими void-методами: окончательное состояние показывает foreach.

Скачать самостоятельный пример с результатом и README

Прочитать и убрать пройденные остановкиСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Гараж');
$route->push('Склад');
$route->push('Магазин');
echo 'Первый: ', $route->bottom(), "; последний: ", $route->top(), "\n";
echo 'Пройден: ', $route->shift(), "\n";
echo 'Отменён: ', $route->pop(), "\n";
echo 'Следующий: ', $route->bottom(), "\n";
Ожидаемый результат
Первый: Гараж; последний: Магазин
Пройден: Гараж
Отменён: Магазин
Следующий: Склад

bottom и top читают края без удаления. shift возвращает Гараж и удаляет начало; pop возвращает Магазин и удаляет конец. В списке остаётся Склад. Возвращённые строки сразу занимают аргументы echo.

Скачать самостоятельный пример с результатом и README

Продолжение: SplDoublyLinkedList::add, SplDoublyLinkedList::offsetGet.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplDoublyLinkedList::countИспользовать количество узлов как ограничение

PHP 5.3+; примеры рассчитаны на PHP 8.2+ · SPL

public function SplDoublyLinkedList::count(): int

count() возвращает число хранимых узлов, независимо от текущей позиции указателя. count($route) использует тот же договор Countable.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplDoublyLinkedList::count(): int
Результатint от 0: количество узлов, включая узлы со значением null.
Ошибки и особые значенияПараметров нет; подсчёт не извлекает значения.
ВерсииPHP 5.3+; примеры рассчитаны на PHP 8.2+
Ограничить число остановокСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Склад');
$limit = 2;
if ($route->count() < $limit) {
    $route->push('Магазин');
}
echo 'Остановок: ', count($route), " из ", $limit, "\n";
while (!$route->isEmpty()) {
    echo 'Едем: ', $route->shift(), "\n";
}
Ожидаемый результат
Остановок: 2 из 2
Едем: Склад
Едем: Магазин

count возвращает целое количество узлов, которое используется в сравнении с лимитом. count($route) вызывает договор Countable. isEmpty управляет обработкой, а не служит заменой результатам поездок.

Скачать самостоятельный пример с результатом и README

Развернуть просмотр и отдельно включить потреблениеСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Склад');
$route->push('Магазин');
$route->setIteratorMode(SplDoublyLinkedList::IT_MODE_LIFO | SplDoublyLinkedList::IT_MODE_KEEP);
echo 'Позиция 0 в LIFO: ', $route[0], "\n";
foreach ($route as $stop) { echo 'Обратно: ', $stop, "\n"; }
echo 'Сохранено: ', $route->count(), "\n";
$mode = $route->getIteratorMode();
$route->setIteratorMode($mode | SplDoublyLinkedList::IT_MODE_DELETE);
foreach ($route as $stop) { echo 'Пройден: ', $stop, "\n"; }
echo 'Осталось: ', $route->count(), "\n";
Ожидаемый результат
Позиция 0 в LIFO: Магазин
Обратно: Магазин
Обратно: Склад
Сохранено: 2
Пройден: Магазин
Пройден: Склад
Осталось: 0

:: выбирает именованную константу класса; побитовое | объединяет независимые настройки. LIFO меняет направление просмотра и доступ по индексам, но не физические top/bottom. KEEP сохраняет список. Во втором обходе DELETE удаляет пройденный узел при переходе итератора дальше; break до перехода может оставить текущий узел.

Скачать самостоятельный пример с результатом и README

Продолжение: SplDoublyLinkedList::add, SplDoublyLinkedList::offsetGet.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplDoublyLinkedList::isEmptyНе извлекать работу из пустого списка

PHP 5.3+; примеры рассчитаны на PHP 8.2+ · SPL

public function SplDoublyLinkedList::isEmpty(): bool

isEmpty() отвечает о всём контейнере. Это отличается от valid(), которое проверяет только текущую позицию обхода.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplDoublyLinkedList::isEmpty(): bool
Результатbool: true, когда узлов нет; !isEmpty() разрешает следующий шаг обработки.
Ошибки и особые значенияПустое значение внутри узла не означает пустой список.
ВерсииPHP 5.3+; примеры рассчитаны на PHP 8.2+
Ограничить число остановокСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Склад');
$limit = 2;
if ($route->count() < $limit) {
    $route->push('Магазин');
}
echo 'Остановок: ', count($route), " из ", $limit, "\n";
while (!$route->isEmpty()) {
    echo 'Едем: ', $route->shift(), "\n";
}
Ожидаемый результат
Остановок: 2 из 2
Едем: Склад
Едем: Магазин

count возвращает целое количество узлов, которое используется в сравнении с лимитом. count($route) вызывает договор Countable. isEmpty управляет обработкой, а не служит заменой результатам поездок.

Скачать самостоятельный пример с результатом и README

Пустая очередь и настоящее значение nullСамостоятельный пример
<?php
declare(strict_types=1);

$jobs = new SplQueue();
$jobs->enqueue(null);
while (!$jobs->isEmpty()) {
    $job = $jobs->dequeue();
    echo $job === null ? "Получено задание без данных\n" : $job . "\n";
}
try {
    $jobs->dequeue();
} catch (RuntimeException $error) {
    echo "Новой работы нет\n";
}
Ожидаемый результат
Получено задание без данных
Новой работы нет

Очередь с одним null не пуста. Проверка по isEmpty позволяет обработать значение, после чего отдельная попытка чтения пустой очереди попадает в catch. try обозначает проверяемое действие, catch получает исключение указанного класса и выбирает понятную реакцию; это не возврат null из dequeue.

Скачать самостоятельный пример с результатом и README

Продолжение: SplDoublyLinkedList::add, SplDoublyLinkedList::offsetGet.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplDoublyLinkedList::currentПолучить значение текущей остановки

PHP 5.3+; примеры рассчитаны на PHP 8.2+ · SPL

public function SplDoublyLinkedList::current(): mixed

После rewind()/next()/prev() current() читает узел, на котором остановился ручной указатель. Это не обязательно начало и не удаление.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplDoublyLinkedList::current(): mixed
Результатmixed: текущее значение; в текущем PHP без действительного узла возвращается null, поэтому сначала valid().
Ошибки и особые значенияnull двусмысленен: может быть значением узла или признаком отсутствующей позиции.
ВерсииPHP 5.3+; примеры рассчитаны на PHP 8.2+
Пройти маршрут вручную и вернуться на шагСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Склад');
$route->push('Магазин');
$route->rewind();
echo $route->key(), ': ', $route->current(), "\n";
$route->next();
echo $route->key(), ': ', $route->current(), "\n";
$route->prev();
echo 'Назад: ', $route->current(), "\n";
$route->rewind();
while ($route->valid()) {
    echo 'План: ', $route->current(), "\n";
    $route->next();
}
Ожидаемый результат
0: Склад
1: Магазин
Назад: Склад
План: Склад
План: Магазин

rewind устанавливает начало, current возвращает значение, key — позицию. next/prev меняют позицию и возвращают void. valid сообщает, есть ли узел именно у текущего указателя: после конца список всё ещё содержит два элемента, но читать текущий уже нельзя. Перед повторным проходом вызывается rewind.

Скачать самостоятельный пример с результатом и README

Развернуть просмотр и отдельно включить потреблениеСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Склад');
$route->push('Магазин');
$route->setIteratorMode(SplDoublyLinkedList::IT_MODE_LIFO | SplDoublyLinkedList::IT_MODE_KEEP);
echo 'Позиция 0 в LIFO: ', $route[0], "\n";
foreach ($route as $stop) { echo 'Обратно: ', $stop, "\n"; }
echo 'Сохранено: ', $route->count(), "\n";
$mode = $route->getIteratorMode();
$route->setIteratorMode($mode | SplDoublyLinkedList::IT_MODE_DELETE);
foreach ($route as $stop) { echo 'Пройден: ', $stop, "\n"; }
echo 'Осталось: ', $route->count(), "\n";
Ожидаемый результат
Позиция 0 в LIFO: Магазин
Обратно: Магазин
Обратно: Склад
Сохранено: 2
Пройден: Магазин
Пройден: Склад
Осталось: 0

:: выбирает именованную константу класса; побитовое | объединяет независимые настройки. LIFO меняет направление просмотра и доступ по индексам, но не физические top/bottom. KEEP сохраняет список. Во втором обходе DELETE удаляет пройденный узел при переходе итератора дальше; break до перехода может оставить текущий узел.

Скачать самостоятельный пример с результатом и README

Продолжение: SplDoublyLinkedList::add, SplDoublyLinkedList::offsetGet.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplDoublyLinkedList::keyПолучить номер текущей позиции

PHP 5.3+; примеры рассчитаны на PHP 8.2+ · SPL

public function SplDoublyLinkedList::key(): int

key() возвращает позицию ручного итератора. Номер не является идентификатором остановки; при удалении или другом направлении его смысл определяется текущим обходом.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplDoublyLinkedList::key(): int
Результатint: индекс текущего узла; используйте только при valid().
Ошибки и особые значенияПосле завершения обхода номер не доказывает существование узла.
ВерсииPHP 5.3+; примеры рассчитаны на PHP 8.2+
Пройти маршрут вручную и вернуться на шагСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Склад');
$route->push('Магазин');
$route->rewind();
echo $route->key(), ': ', $route->current(), "\n";
$route->next();
echo $route->key(), ': ', $route->current(), "\n";
$route->prev();
echo 'Назад: ', $route->current(), "\n";
$route->rewind();
while ($route->valid()) {
    echo 'План: ', $route->current(), "\n";
    $route->next();
}
Ожидаемый результат
0: Склад
1: Магазин
Назад: Склад
План: Склад
План: Магазин

rewind устанавливает начало, current возвращает значение, key — позицию. next/prev меняют позицию и возвращают void. valid сообщает, есть ли узел именно у текущего указателя: после конца список всё ещё содержит два элемента, но читать текущий уже нельзя. Перед повторным проходом вызывается rewind.

Скачать самостоятельный пример с результатом и README

Составить порядок остановокСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Склад');
$route->push('Магазин');
$route->unshift('Гараж');
foreach ($route as $index => $stop) {
    echo $index, ': ', $stop, "\n";
}
Ожидаемый результат
0: Гараж
1: Склад
2: Магазин

push добавил Склад и Магазин в конец, unshift — Гараж в начало. foreach передаёт текущий номер в $index, строку в $stop; => связывает две переменные обхода. Это позиции в текущем списке, не постоянные ID адресов.

Скачать самостоятельный пример с результатом и README

Продолжение: SplDoublyLinkedList::add, SplDoublyLinkedList::offsetGet.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplDoublyLinkedList::nextПерейти к следующему узлу

PHP 5.3+; примеры рассчитаны на PHP 8.2+ · SPL

public function SplDoublyLinkedList::next(): void

next() перемещает ручной указатель в направлении режима. В LIFO это движение от конца к началу; в DELETE пройденный узел удаляется.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplDoublyLinkedList::next(): void
Результатvoid; новое значение читается следующим current().
Ошибки и особые значенияПройдя конец, указатель становится недействительным; проверьте valid().
ВерсииPHP 5.3+; примеры рассчитаны на PHP 8.2+
Пройти маршрут вручную и вернуться на шагСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Склад');
$route->push('Магазин');
$route->rewind();
echo $route->key(), ': ', $route->current(), "\n";
$route->next();
echo $route->key(), ': ', $route->current(), "\n";
$route->prev();
echo 'Назад: ', $route->current(), "\n";
$route->rewind();
while ($route->valid()) {
    echo 'План: ', $route->current(), "\n";
    $route->next();
}
Ожидаемый результат
0: Склад
1: Магазин
Назад: Склад
План: Склад
План: Магазин

rewind устанавливает начало, current возвращает значение, key — позицию. next/prev меняют позицию и возвращают void. valid сообщает, есть ли узел именно у текущего указателя: после конца список всё ещё содержит два элемента, но читать текущий уже нельзя. Перед повторным проходом вызывается rewind.

Скачать самостоятельный пример с результатом и README

Развернуть просмотр и отдельно включить потреблениеСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Склад');
$route->push('Магазин');
$route->setIteratorMode(SplDoublyLinkedList::IT_MODE_LIFO | SplDoublyLinkedList::IT_MODE_KEEP);
echo 'Позиция 0 в LIFO: ', $route[0], "\n";
foreach ($route as $stop) { echo 'Обратно: ', $stop, "\n"; }
echo 'Сохранено: ', $route->count(), "\n";
$mode = $route->getIteratorMode();
$route->setIteratorMode($mode | SplDoublyLinkedList::IT_MODE_DELETE);
foreach ($route as $stop) { echo 'Пройден: ', $stop, "\n"; }
echo 'Осталось: ', $route->count(), "\n";
Ожидаемый результат
Позиция 0 в LIFO: Магазин
Обратно: Магазин
Обратно: Склад
Сохранено: 2
Пройден: Магазин
Пройден: Склад
Осталось: 0

:: выбирает именованную константу класса; побитовое | объединяет независимые настройки. LIFO меняет направление просмотра и доступ по индексам, но не физические top/bottom. KEEP сохраняет список. Во втором обходе DELETE удаляет пройденный узел при переходе итератора дальше; break до перехода может оставить текущий узел.

Скачать самостоятельный пример с результатом и README

Продолжение: SplDoublyLinkedList::add, SplDoublyLinkedList::offsetGet.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplDoublyLinkedList::prevВернуться на один узел

PHP 5.3+; примеры рассчитаны на PHP 8.2+ · SPL

public function SplDoublyLinkedList::prev(): void

prev() перемещает указатель против направления режима. В обычном FIFO из Магазина можно вернуться к Складу.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplDoublyLinkedList::prev(): void
Результатvoid; результат перемещения наблюдается в current()/key().
Ошибки и особые значенияДо начала указатель становится недействительным. В DELETE обратные переходы также потребляют узлы; для истории используйте KEEP.
ВерсииPHP 5.3+; примеры рассчитаны на PHP 8.2+
Пройти маршрут вручную и вернуться на шагСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Склад');
$route->push('Магазин');
$route->rewind();
echo $route->key(), ': ', $route->current(), "\n";
$route->next();
echo $route->key(), ': ', $route->current(), "\n";
$route->prev();
echo 'Назад: ', $route->current(), "\n";
$route->rewind();
while ($route->valid()) {
    echo 'План: ', $route->current(), "\n";
    $route->next();
}
Ожидаемый результат
0: Склад
1: Магазин
Назад: Склад
План: Склад
План: Магазин

rewind устанавливает начало, current возвращает значение, key — позицию. next/prev меняют позицию и возвращают void. valid сообщает, есть ли узел именно у текущего указателя: после конца список всё ещё содержит два элемента, но читать текущий уже нельзя. Перед повторным проходом вызывается rewind.

Скачать самостоятельный пример с результатом и README

Посмотреть историю, затем отменить шагСамостоятельный пример
<?php
declare(strict_types=1);

$history = new SplStack();
$history->push('Создан черновик');
$history->push('Изменён заголовок');
foreach ($history as $step) {
    echo 'История: ', $step, "\n";
}
echo 'Отменяем: ', $history->pop(), "\n";
echo 'Остаётся: ', $history->top(), "\n";
Ожидаемый результат
История: Изменён заголовок
История: Создан черновик
Отменяем: Изменён заголовок
Остаётся: Создан черновик

SplStack фиксирует LIFO — «последний пришёл, первый вышел». foreach в режиме KEEP не уничтожает историю; затем pop действительно удаляет последнюю запись. top только читает оставшуюся. Надпись «Отменяем» показывает выбранную запись, а не автоматическое изменение документа.

Скачать самостоятельный пример с результатом и README

Продолжение: SplDoublyLinkedList::add, SplDoublyLinkedList::offsetGet.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplDoublyLinkedList::rewindНачать проход с выбранного конца

PHP 5.3+; примеры рассчитаны на PHP 8.2+ · SPL

public function SplDoublyLinkedList::rewind(): void

rewind() ставит указатель на начало выбранного обхода: физическое начало при FIFO, конец при LIFO. Удалённые элементы он не восстанавливает.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplDoublyLinkedList::rewind(): void
Результатvoid; current() после него читает первый узел прохода, если valid().
Ошибки и особые значенияПустой список остаётся пустым, valid() вернёт false.
ВерсииPHP 5.3+; примеры рассчитаны на PHP 8.2+
Пройти маршрут вручную и вернуться на шагСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Склад');
$route->push('Магазин');
$route->rewind();
echo $route->key(), ': ', $route->current(), "\n";
$route->next();
echo $route->key(), ': ', $route->current(), "\n";
$route->prev();
echo 'Назад: ', $route->current(), "\n";
$route->rewind();
while ($route->valid()) {
    echo 'План: ', $route->current(), "\n";
    $route->next();
}
Ожидаемый результат
0: Склад
1: Магазин
Назад: Склад
План: Склад
План: Магазин

rewind устанавливает начало, current возвращает значение, key — позицию. next/prev меняют позицию и возвращают void. valid сообщает, есть ли узел именно у текущего указателя: после конца список всё ещё содержит два элемента, но читать текущий уже нельзя. Перед повторным проходом вызывается rewind.

Скачать самостоятельный пример с результатом и README

Развернуть просмотр и отдельно включить потреблениеСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Склад');
$route->push('Магазин');
$route->setIteratorMode(SplDoublyLinkedList::IT_MODE_LIFO | SplDoublyLinkedList::IT_MODE_KEEP);
echo 'Позиция 0 в LIFO: ', $route[0], "\n";
foreach ($route as $stop) { echo 'Обратно: ', $stop, "\n"; }
echo 'Сохранено: ', $route->count(), "\n";
$mode = $route->getIteratorMode();
$route->setIteratorMode($mode | SplDoublyLinkedList::IT_MODE_DELETE);
foreach ($route as $stop) { echo 'Пройден: ', $stop, "\n"; }
echo 'Осталось: ', $route->count(), "\n";
Ожидаемый результат
Позиция 0 в LIFO: Магазин
Обратно: Магазин
Обратно: Склад
Сохранено: 2
Пройден: Магазин
Пройден: Склад
Осталось: 0

:: выбирает именованную константу класса; побитовое | объединяет независимые настройки. LIFO меняет направление просмотра и доступ по индексам, но не физические top/bottom. KEEP сохраняет список. Во втором обходе DELETE удаляет пройденный узел при переходе итератора дальше; break до перехода может оставить текущий узел.

Скачать самостоятельный пример с результатом и README

Продолжение: SplDoublyLinkedList::add, SplDoublyLinkedList::offsetGet.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplDoublyLinkedList::validПродолжать ручной обход только на существующем узле

PHP 5.3+; примеры рассчитаны на PHP 8.2+ · SPL

public function SplDoublyLinkedList::valid(): bool

valid() проверяет текущий ручной указатель. Непустой список может иметь недействительный указатель, если он уже прошёл конец.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplDoublyLinkedList::valid(): bool
Результатbool: true позволяет читать current/key; false останавливает цикл.
Ошибки и особые значенияЭто не замена isEmpty() при потреблении очереди через dequeue().
ВерсииPHP 5.3+; примеры рассчитаны на PHP 8.2+
Пройти маршрут вручную и вернуться на шагСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Склад');
$route->push('Магазин');
$route->rewind();
echo $route->key(), ': ', $route->current(), "\n";
$route->next();
echo $route->key(), ': ', $route->current(), "\n";
$route->prev();
echo 'Назад: ', $route->current(), "\n";
$route->rewind();
while ($route->valid()) {
    echo 'План: ', $route->current(), "\n";
    $route->next();
}
Ожидаемый результат
0: Склад
1: Магазин
Назад: Склад
План: Склад
План: Магазин

rewind устанавливает начало, current возвращает значение, key — позицию. next/prev меняют позицию и возвращают void. valid сообщает, есть ли узел именно у текущего указателя: после конца список всё ещё содержит два элемента, но читать текущий уже нельзя. Перед повторным проходом вызывается rewind.

Скачать самостоятельный пример с результатом и README

Обойти связанные разделы без бесконечных повторовСамостоятельный пример
<?php
declare(strict_types=1);

$links = ['Главная' => ['Каталог', 'Контакты'], 'Каталог' => ['Главная', 'Чай'], 'Контакты' => [], 'Чай' => []];
$pending = new SplQueue();
$pending->enqueue('Главная');
$scheduled = ['Главная' => true];
while (!$pending->isEmpty()) {
    $page = $pending->dequeue();
    echo 'Раздел: ', $page, "\n";
    foreach ($links[$page] as $next) {
        if (!isset($scheduled[$next])) {
            $scheduled[$next] = true;
            $pending->enqueue($next);
        }
    }
}
Ожидаемый результат
Раздел: Главная
Раздел: Каталог
Раздел: Контакты
Раздел: Чай

Это конечный граф разделов, уже известный в памяти. foreach получает соседей текущей страницы. isset проверяет отметку; её ставят при постановке в очередь, поэтому две страницы не поставят один раздел дважды. Обратная ссылка Каталог → Главная не зацикливает обработку. Для загружаемого извне графа отдельно нужны пределы страниц, глубины и времени.

Скачать самостоятельный пример с результатом и README

Продолжение: SplDoublyLinkedList::add, SplDoublyLinkedList::offsetGet.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplDoublyLinkedList::getIteratorModeПрочитать режим обхода

PHP 5.3+; константы имеют тип int с PHP 8.4 · SPL

public function SplDoublyLinkedList::getIteratorMode(): int

Режим — целочисленная битовая маска. FIFO=0 и LIFO=2 задают направление, KEEP=0 и DELETE=1 — сохранение или удаление. По умолчанию у списка FIFO | KEEP. Именованные константы соединяют |. У Stack/Queue направление закреплено; методы могут возвращать также внутренний бит фиксации, поэтому проверяют нужный бит, а не равенство числу 2.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplDoublyLinkedList::getIteratorMode(): int
Результатint: действующий набор флагов (set возвращает установленный режим, get — текущий). Он пригоден для сохранения направления при добавлении DELETE.
Ошибки и особые значенияПопытка изменить направление SplStack/SplQueue — RuntimeException. Неверный тип mode — TypeError.
ВерсииPHP 5.3+; константы имеют тип int с PHP 8.4
Развернуть просмотр и отдельно включить потреблениеСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Склад');
$route->push('Магазин');
$route->setIteratorMode(SplDoublyLinkedList::IT_MODE_LIFO | SplDoublyLinkedList::IT_MODE_KEEP);
echo 'Позиция 0 в LIFO: ', $route[0], "\n";
foreach ($route as $stop) { echo 'Обратно: ', $stop, "\n"; }
echo 'Сохранено: ', $route->count(), "\n";
$mode = $route->getIteratorMode();
$route->setIteratorMode($mode | SplDoublyLinkedList::IT_MODE_DELETE);
foreach ($route as $stop) { echo 'Пройден: ', $stop, "\n"; }
echo 'Осталось: ', $route->count(), "\n";
Ожидаемый результат
Позиция 0 в LIFO: Магазин
Обратно: Магазин
Обратно: Склад
Сохранено: 2
Пройден: Магазин
Пройден: Склад
Осталось: 0

:: выбирает именованную константу класса; побитовое | объединяет независимые настройки. LIFO меняет направление просмотра и доступ по индексам, но не физические top/bottom. KEEP сохраняет список. Во втором обходе DELETE удаляет пройденный узел при переходе итератора дальше; break до перехода может оставить текущий узел.

Скачать самостоятельный пример с результатом и README

Сохранить направление стека при удаляющем обходеСамостоятельный пример
<?php
declare(strict_types=1);

$stack = new SplStack();
$stack->push('Черновик');
$stack->push('Заголовок');
try {
    $stack->setIteratorMode(SplDoublyLinkedList::IT_MODE_FIFO);
} catch (RuntimeException $error) {
    echo "Стек остаётся LIFO\n";
}
$stack->setIteratorMode(SplDoublyLinkedList::IT_MODE_LIFO | SplDoublyLinkedList::IT_MODE_DELETE);
foreach ($stack as $step) { echo 'Снято: ', $step, "\n"; }
echo 'В стеке: ', $stack->count(), "\n";
Ожидаемый результат
Стек остаётся LIFO
Снято: Заголовок
Снято: Черновик
В стеке: 0

У SplStack закреплён LIFO, у SplQueue — FIFO. Попытка поменять этот бит вызывает RuntimeException; PHP-src подтверждает оба различных направления. Встречающееся на странице setIteratorMode утверждение «всегда FIFO» для обоих классов ошибочно. DELETE меняет поведение удаления, сохраняя выбранное направление.

Скачать самостоятельный пример с результатом и README

Продолжение: SplDoublyLinkedList::rewind, SplDoublyLinkedList::next.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplDoublyLinkedList::setIteratorModeНастроить направление и удаление

PHP 5.3+; константы имеют тип int с PHP 8.4 · SPL

public function SplDoublyLinkedList::setIteratorMode(int $mode): int

Режим — целочисленная битовая маска. FIFO=0 и LIFO=2 задают направление, KEEP=0 и DELETE=1 — сохранение или удаление. По умолчанию у списка FIFO | KEEP. Именованные константы соединяют |. У Stack/Queue направление закреплено; методы могут возвращать также внутренний бит фиксации, поэтому проверяют нужный бит, а не равенство числу 2.

ПараметрЧто означает в задаче
modeСочетание направления и поведения. Для Stack сохраняйте LIFO, для Queue — FIFO; обычный список допускает оба.
Часть контрактаЧто важно
Сигнатураpublic function SplDoublyLinkedList::setIteratorMode(int $mode): int
Результатint: действующий набор флагов (set возвращает установленный режим, get — текущий). Он пригоден для сохранения направления при добавлении DELETE.
Ошибки и особые значенияПопытка изменить направление SplStack/SplQueue — RuntimeException. Неверный тип mode — TypeError.
ВерсииPHP 5.3+; константы имеют тип int с PHP 8.4
Развернуть просмотр и отдельно включить потреблениеСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Склад');
$route->push('Магазин');
$route->setIteratorMode(SplDoublyLinkedList::IT_MODE_LIFO | SplDoublyLinkedList::IT_MODE_KEEP);
echo 'Позиция 0 в LIFO: ', $route[0], "\n";
foreach ($route as $stop) { echo 'Обратно: ', $stop, "\n"; }
echo 'Сохранено: ', $route->count(), "\n";
$mode = $route->getIteratorMode();
$route->setIteratorMode($mode | SplDoublyLinkedList::IT_MODE_DELETE);
foreach ($route as $stop) { echo 'Пройден: ', $stop, "\n"; }
echo 'Осталось: ', $route->count(), "\n";
Ожидаемый результат
Позиция 0 в LIFO: Магазин
Обратно: Магазин
Обратно: Склад
Сохранено: 2
Пройден: Магазин
Пройден: Склад
Осталось: 0

:: выбирает именованную константу класса; побитовое | объединяет независимые настройки. LIFO меняет направление просмотра и доступ по индексам, но не физические top/bottom. KEEP сохраняет список. Во втором обходе DELETE удаляет пройденный узел при переходе итератора дальше; break до перехода может оставить текущий узел.

Скачать самостоятельный пример с результатом и README

Сохранить направление стека при удаляющем обходеСамостоятельный пример
<?php
declare(strict_types=1);

$stack = new SplStack();
$stack->push('Черновик');
$stack->push('Заголовок');
try {
    $stack->setIteratorMode(SplDoublyLinkedList::IT_MODE_FIFO);
} catch (RuntimeException $error) {
    echo "Стек остаётся LIFO\n";
}
$stack->setIteratorMode(SplDoublyLinkedList::IT_MODE_LIFO | SplDoublyLinkedList::IT_MODE_DELETE);
foreach ($stack as $step) { echo 'Снято: ', $step, "\n"; }
echo 'В стеке: ', $stack->count(), "\n";
Ожидаемый результат
Стек остаётся LIFO
Снято: Заголовок
Снято: Черновик
В стеке: 0

У SplStack закреплён LIFO, у SplQueue — FIFO. Попытка поменять этот бит вызывает RuntimeException; PHP-src подтверждает оба различных направления. Встречающееся на странице setIteratorMode утверждение «всегда FIFO» для обоих классов ошибочно. DELETE меняет поведение удаления, сохраняя выбранное направление.

Скачать самостоятельный пример с результатом и README

Продолжение: SplDoublyLinkedList::rewind, SplDoublyLinkedList::next.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplDoublyLinkedList::serializeПолучить строку списка

PHP 5.4+; официальный раздел помечен как неполностью документированный · SPL

public function SplDoublyLinkedList::serialize(): string

Это парные методы формата Serializable: строка метода serialize() передаётся методу unserialize() списка. Глобальные функции serialize($object)/unserialize($string) работают с обёрткой всего объекта; форматы нельзя произвольно смешивать. Официальная страница краткая; реальный round-trip показан на строках Depot и Shop.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplDoublyLinkedList::serialize(): string
Результатstring: сохранённые режим и значения.
Ошибки и особые значенияПовреждённые данные восстановления могут вызвать UnexpectedValueException; не считайте частично изменённый объект пригодным после отказа. Сериализация произвольных вложенных значений тоже может не поддерживаться.
ВерсииPHP 5.4+; официальный раздел помечен как неполностью документированный
Сохранить свой список и восстановить остановкиСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Depot');
$route->push('Shop');
$data = $route->serialize();
echo 'Строка: ', $data, "\n";
$restored = new SplDoublyLinkedList();
$restored->unserialize($data);
echo 'Маршрут: ', $restored->shift(), ' -> ', $restored->shift(), "\n";
Ожидаемый результат
Строка: i:0;:s:5:"Depot";:s:4:"Shop";
Маршрут: Depot -> Shop

serialize() возвращает строку внутреннего парного формата. Она хранится в $data, затем передаётся в unserialize() нового списка. Строка содержит режим и значения; это не JSON. Здесь строка только что создана в том же процессе. Полученный список снова отдаёт реальные остановки.

Скачать самостоятельный пример с результатом и README

Восстановить локальный план из файлаСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Depot');
$route->push('Post');
file_put_contents('route.cache', $route->serialize());
$route = new SplDoublyLinkedList();
$data = file_get_contents('route.cache');
if ($data === false) { throw new RuntimeException('Не удалось прочитать план'); }
$route->unserialize($data);
foreach ($route as $stop) { echo 'Восстановлено: ', $stop, "\n"; }
Ожидаемый результат
Восстановлено: Depot
Восстановлено: Post

В полной программе файл route.cache создаётся в текущей папке и содержит только что сериализованный собственный список. file_get_contents передаёт строку в $data; восстановление изменяет пустой объект, затем foreach использует его данные. Для чужого ввода этот путь непригоден: unserialize может создавать объекты и выполнять их hooks. Для обмена данными задайте простую схему и используйте JSON.

Скачать самостоятельный пример с результатом и README

Продолжение: SplDoublyLinkedList::unserialize.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplDoublyLinkedList::unserializeВосстановить список из его парной строки

PHP 5.4+; официальный раздел помечен как неполностью документированный · SPL

public function SplDoublyLinkedList::unserialize(string $data): void

Это парные методы формата Serializable: строка метода serialize() передаётся методу unserialize() списка. Глобальные функции serialize($object)/unserialize($string) работают с обёрткой всего объекта; форматы нельзя произвольно смешивать. Официальная страница краткая; реальный round-trip показан на строках Depot и Shop.

ПараметрЧто означает в задаче
dataСобственная доверенная строка, ранее полученная парным методом.
Часть контрактаЧто важно
Сигнатураpublic function SplDoublyLinkedList::unserialize(string $data): void
Результатvoid: существующий объект заполнен восстановленным состоянием.
Ошибки и особые значенияПовреждённые данные восстановления могут вызвать UnexpectedValueException; не считайте частично изменённый объект пригодным после отказа. Сериализация произвольных вложенных значений тоже может не поддерживаться.
ВерсииPHP 5.4+; официальный раздел помечен как неполностью документированный
Сохранить свой список и восстановить остановкиСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Depot');
$route->push('Shop');
$data = $route->serialize();
echo 'Строка: ', $data, "\n";
$restored = new SplDoublyLinkedList();
$restored->unserialize($data);
echo 'Маршрут: ', $restored->shift(), ' -> ', $restored->shift(), "\n";
Ожидаемый результат
Строка: i:0;:s:5:"Depot";:s:4:"Shop";
Маршрут: Depot -> Shop

serialize() возвращает строку внутреннего парного формата. Она хранится в $data, затем передаётся в unserialize() нового списка. Строка содержит режим и значения; это не JSON. Здесь строка только что создана в том же процессе. Полученный список снова отдаёт реальные остановки.

Скачать самостоятельный пример с результатом и README

Восстановить локальный план из файлаСамостоятельный пример
<?php
declare(strict_types=1);

$route = new SplDoublyLinkedList();
$route->push('Depot');
$route->push('Post');
file_put_contents('route.cache', $route->serialize());
$route = new SplDoublyLinkedList();
$data = file_get_contents('route.cache');
if ($data === false) { throw new RuntimeException('Не удалось прочитать план'); }
$route->unserialize($data);
foreach ($route as $stop) { echo 'Восстановлено: ', $stop, "\n"; }
Ожидаемый результат
Восстановлено: Depot
Восстановлено: Post

В полной программе файл route.cache создаётся в текущей папке и содержит только что сериализованный собственный список. file_get_contents передаёт строку в $data; восстановление изменяет пустой объект, затем foreach использует его данные. Для чужого ввода этот путь непригоден: unserialize может создавать объекты и выполнять их hooks. Для обмена данными задайте простую схему и используйте JSON.

Скачать самостоятельный пример с результатом и README

Продолжение: SplDoublyLinkedList::serialize.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplHeap::insertПоместить новое значение в структуру

PHP 5.3+; tentative return true с PHP 8.4 · SPL

public function SplHeap::insert(mixed $value): true

Вставка перестраивает только нужный путь к вершине. value сравнивается с уже имеющимися значениями через compare.

ПараметрЧто означает в задаче
valueСохраняемое значение любого типа.
Часть контрактаЧто важно
Сигнатураpublic function SplHeap::insert(mixed $value): true
Результатtrue при нормальном завершении; это не вставленное значение и не новый контейнер. Полезные данные получают через top/extract.
Ошибки и особые значенияИсключение compare может испортить структуру и оставить вставку частично выполненной. Проверяйте вход заранее.
ВерсииPHP 5.3+; tentative return true с PHP 8.4
Выбрать самый крупный остатокСамостоятельный пример
<?php
declare(strict_types=1);

$stock = new SplMaxHeap();
$stock->insert(12);
$stock->insert(40);
$stock->insert(25);
$amount = $stock->extract();
echo 'Первый объём: ', $amount, "\n";
echo 'Следующий объём: ', $stock->top(), "\n";
Ожидаемый результат
Первый объём: 40
Следующий объём: 25

SplMaxHeap выбирает наибольшее значение. extract возвращает 40, следующий top — 25. Мы храним только количества: если нужен ещё и артикул, используйте запись и собственное сравнение либо SplPriorityQueue с количеством как приоритетом.

Скачать самостоятельный пример с результатом и README

Отсеять неверный срок до изменения кучиСамостоятельный пример
<?php
declare(strict_types=1);

$minutes = new SplMinHeap();
foreach ([20, 'later', 10] as $value) {
    if (!is_int($value) || $value < 0) {
        echo "Пропущен неверный срок\n";
        continue;
    }
    $minutes->insert($value);
}
while (!$minutes->isEmpty()) { echo 'Минута: ', $minutes->extract(), "\n"; }
Ожидаемый результат
Пропущен неверный срок
Минута: 10
Минута: 20

is_int и проверка диапазона происходят до insert. continue пропускает эту запись и начинает следующий проход foreach. Внутри кучи остаются однородные числа, и стандартное сравнение уже не зависит от внешней ошибки.

Скачать самостоятельный пример с результатом и README

Продолжение: SplHeap::top, SplHeap::isEmpty.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplHeap::topПрочитать вершину без удаления

PHP 5.3+ · SPL

public function SplHeap::top(): mixed

top() даёт следующего кандидата, сохраняя количество элементов.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplHeap::top(): mixed
Результатmixed: хранимое значение вершины.
Ошибки и особые значенияПустой или заблокированный контейнер — RuntimeException.
ВерсииPHP 5.3+
Выбрать самый крупный остатокСамостоятельный пример
<?php
declare(strict_types=1);

$stock = new SplMaxHeap();
$stock->insert(12);
$stock->insert(40);
$stock->insert(25);
$amount = $stock->extract();
echo 'Первый объём: ', $amount, "\n";
echo 'Следующий объём: ', $stock->top(), "\n";
Ожидаемый результат
Первый объём: 40
Следующий объём: 25

SplMaxHeap выбирает наибольшее значение. extract возвращает 40, следующий top — 25. Мы храним только количества: если нужен ещё и артикул, используйте запись и собственное сравнение либо SplPriorityQueue с количеством как приоритетом.

Скачать самостоятельный пример с результатом и README

Просмотр без потери исходных значенийСамостоятельный пример
<?php
declare(strict_types=1);

$sizes = new SplMaxHeap();
foreach ([12, 40, 25] as $size) { $sizes->insert($size); }
$preview = clone $sizes;
foreach ($preview as $size) { echo 'Предпросмотр: ', $size, "\n"; }
echo 'Осталось в копии: ', $preview->count(), "\n";
echo 'В исходной куче: ', $sizes->count(), "\n";
echo 'Реально выбран: ', $sizes->extract(), "\n";
Ожидаемый результат
Предпросмотр: 40
Предпросмотр: 25
Предпросмотр: 12
Осталось в копии: 0
В исходной куче: 3
Реально выбран: 40

foreach кучи последовательно удаляет вершины. clone создаёт отдельный контейнер, поэтому обзор опустошает $preview, а не $sizes. Клонирование контейнера поверхностное: вложенные объекты остаются общими, поэтому это не снимок состояния всего графа объектов.

Скачать самостоятельный пример с результатом и README

Продолжение: SplHeap::extract, SplHeap::isEmpty.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplHeap::extractВернуть вершину и удалить её

PHP 5.3+ · SPL

public function SplHeap::extract(): mixed

Возвращённое значение занимает место extract() в присваивании или echo; оставшиеся элементы восстанавливают отношение вершины.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplHeap::extract(): mixed
Результатmixed: хранимое значение вершины.
Ошибки и особые значенияПустой контейнер — RuntimeException; compare может выбросить исключение и блокировать кучу.
ВерсииPHP 5.3+
Выбрать самый крупный остатокСамостоятельный пример
<?php
declare(strict_types=1);

$stock = new SplMaxHeap();
$stock->insert(12);
$stock->insert(40);
$stock->insert(25);
$amount = $stock->extract();
echo 'Первый объём: ', $amount, "\n";
echo 'Следующий объём: ', $stock->top(), "\n";
Ожидаемый результат
Первый объём: 40
Следующий объём: 25

SplMaxHeap выбирает наибольшее значение. extract возвращает 40, следующий top — 25. Мы храним только количества: если нужен ещё и артикул, используйте запись и собственное сравнение либо SplPriorityQueue с количеством как приоритетом.

Скачать самостоятельный пример с результатом и README

Остановиться, когда значения закончилисьСамостоятельный пример
<?php
declare(strict_types=1);

$sizes = new SplMaxHeap();
$sizes->insert(12);
while (!$sizes->isEmpty()) { echo 'Выдано: ', $sizes->extract(), "\n"; }
try { $sizes->top(); }
catch (RuntimeException $error) { echo "Больше остатков нет\n"; }
Ожидаемый результат
Выдано: 12
Больше остатков нет

isEmpty управляет повторением до очередного извлечения. Отдельный top на уже пустой куче вызывает RuntimeException; это не нулевой остаток. Полезное нулевое значение тоже можно хранить и извлекать.

Скачать самостоятельный пример с результатом и README

Продолжение: SplHeap::top, SplHeap::isEmpty.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplHeap::countУзнать объём ожидающей работы

PHP 5.3+ · SPL

public function SplHeap::count(): int

Число элементов используется для лимита и оценки остатка. count($container) вызывает договор Countable.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplHeap::count(): int
Результатint: число узлов, включая равные и нулевые значения.
Ошибки и особые значенияПодсчёт не выполняет работу и не удаляет узлы.
ВерсииPHP 5.3+
Один указатель всегда смотрит на вершинуСамостоятельный пример
<?php
declare(strict_types=1);

$sizes = new SplMaxHeap();
$sizes->insert(12);
$sizes->insert(40);
$sizes->insert(25);
$sizes->rewind();
echo 'Ключ ', $sizes->key(), ': ', $sizes->current(), "\n";
$sizes->next();
$sizes->rewind();
while ($sizes->valid()) {
    echo 'Остаток ', $sizes->key(), ': ', $sizes->current(), "\n";
    $sizes->next();
}
echo 'После прохода: ', $sizes->count(), "\n";
Ожидаемый результат
Ключ 2: 40
Остаток 1: 25
Остаток 0: 12
После прохода: 0

key отражает число оставшихся элементов минус один, а не прежний индекс вставки. next удалил 40. rewind — пустое действие для кучи: 40 не вернулся. current читает вершину, valid позволяет продолжать, пока есть элементы. Обход потребил весь контейнер.

Скачать самостоятельный пример с результатом и README

Просмотр без потери исходных значенийСамостоятельный пример
<?php
declare(strict_types=1);

$sizes = new SplMaxHeap();
foreach ([12, 40, 25] as $size) { $sizes->insert($size); }
$preview = clone $sizes;
foreach ($preview as $size) { echo 'Предпросмотр: ', $size, "\n"; }
echo 'Осталось в копии: ', $preview->count(), "\n";
echo 'В исходной куче: ', $sizes->count(), "\n";
echo 'Реально выбран: ', $sizes->extract(), "\n";
Ожидаемый результат
Предпросмотр: 40
Предпросмотр: 25
Предпросмотр: 12
Осталось в копии: 0
В исходной куче: 3
Реально выбран: 40

foreach кучи последовательно удаляет вершины. clone создаёт отдельный контейнер, поэтому обзор опустошает $preview, а не $sizes. Клонирование контейнера поверхностное: вложенные объекты остаются общими, поэтому это не снимок состояния всего графа объектов.

Скачать самостоятельный пример с результатом и README

Продолжение: SplHeap::top, SplHeap::isEmpty.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplHeap::isEmptyПродолжать выдачу до опустошения

PHP 5.3+ · SPL

public function SplHeap::isEmpty(): bool

Условие !$queue->isEmpty() проверяется до очередного extract, чтобы отсутствие работы не стало исключением.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplHeap::isEmpty(): bool
Результатbool: true только когда узлов нет.
Ошибки и особые значенияНулевая величина или null внутри узла не делают контейнер пустым.
ВерсииPHP 5.3+
Отсеять неверный срок до изменения кучиСамостоятельный пример
<?php
declare(strict_types=1);

$minutes = new SplMinHeap();
foreach ([20, 'later', 10] as $value) {
    if (!is_int($value) || $value < 0) {
        echo "Пропущен неверный срок\n";
        continue;
    }
    $minutes->insert($value);
}
while (!$minutes->isEmpty()) { echo 'Минута: ', $minutes->extract(), "\n"; }
Ожидаемый результат
Пропущен неверный срок
Минута: 10
Минута: 20

is_int и проверка диапазона происходят до insert. continue пропускает эту запись и начинает следующий проход foreach. Внутри кучи остаются однородные числа, и стандартное сравнение уже не зависит от внешней ошибки.

Скачать самостоятельный пример с результатом и README

Остановиться, когда значения закончилисьСамостоятельный пример
<?php
declare(strict_types=1);

$sizes = new SplMaxHeap();
$sizes->insert(12);
while (!$sizes->isEmpty()) { echo 'Выдано: ', $sizes->extract(), "\n"; }
try { $sizes->top(); }
catch (RuntimeException $error) { echo "Больше остатков нет\n"; }
Ожидаемый результат
Выдано: 12
Больше остатков нет

isEmpty управляет повторением до очередного извлечения. Отдельный top на уже пустой куче вызывает RuntimeException; это не нулевой остаток. Полезное нулевое значение тоже можно хранить и извлекать.

Скачать самостоятельный пример с результатом и README

Продолжение: SplHeap::top, SplHeap::count.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplHeap::currentПрочитать текущую вершину итератора

PHP 5.3+ · SPL

public function SplHeap::current(): mixed

Виртуальный итератор остаётся у вершины. current() читает её, не перемещается и не удаляет.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplHeap::current(): mixed
Результатmixed: хранимое значение вершины. Для пустого контейнера в текущем PHP null; перед чтением проверяйте valid().
Ошибки и особые значенияnull может быть полезным значением; corrupted блокирует нормальное чтение.
ВерсииPHP 5.3+
Один указатель всегда смотрит на вершинуСамостоятельный пример
<?php
declare(strict_types=1);

$sizes = new SplMaxHeap();
$sizes->insert(12);
$sizes->insert(40);
$sizes->insert(25);
$sizes->rewind();
echo 'Ключ ', $sizes->key(), ': ', $sizes->current(), "\n";
$sizes->next();
$sizes->rewind();
while ($sizes->valid()) {
    echo 'Остаток ', $sizes->key(), ': ', $sizes->current(), "\n";
    $sizes->next();
}
echo 'После прохода: ', $sizes->count(), "\n";
Ожидаемый результат
Ключ 2: 40
Остаток 1: 25
Остаток 0: 12
После прохода: 0

key отражает число оставшихся элементов минус один, а не прежний индекс вставки. next удалил 40. rewind — пустое действие для кучи: 40 не вернулся. current читает вершину, valid позволяет продолжать, пока есть элементы. Обход потребил весь контейнер.

Скачать самостоятельный пример с результатом и README

Просмотр без потери исходных значенийСамостоятельный пример
<?php
declare(strict_types=1);

$sizes = new SplMaxHeap();
foreach ([12, 40, 25] as $size) { $sizes->insert($size); }
$preview = clone $sizes;
foreach ($preview as $size) { echo 'Предпросмотр: ', $size, "\n"; }
echo 'Осталось в копии: ', $preview->count(), "\n";
echo 'В исходной куче: ', $sizes->count(), "\n";
echo 'Реально выбран: ', $sizes->extract(), "\n";
Ожидаемый результат
Предпросмотр: 40
Предпросмотр: 25
Предпросмотр: 12
Осталось в копии: 0
В исходной куче: 3
Реально выбран: 40

foreach кучи последовательно удаляет вершины. clone создаёт отдельный контейнер, поэтому обзор опустошает $preview, а не $sizes. Клонирование контейнера поверхностное: вложенные объекты остаются общими, поэтому это не снимок состояния всего графа объектов.

Скачать самостоятельный пример с результатом и README

Продолжение: SplHeap::top, SplHeap::isEmpty.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplHeap::keyПрочитать номер оставшейся вершины

PHP 5.3+ · SPL

public function SplHeap::key(): int

key() возвращает число оставшихся узлов минус один. Это технический ключ итератора, а не ID задачи, не её priority и не порядок вставки.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplHeap::key(): int
Результатint при действительном итераторе.
Ошибки и особые значенияПосле конца ключ не обозначает существующий узел; сначала valid().
ВерсииPHP 5.3+
Один указатель всегда смотрит на вершинуСамостоятельный пример
<?php
declare(strict_types=1);

$sizes = new SplMaxHeap();
$sizes->insert(12);
$sizes->insert(40);
$sizes->insert(25);
$sizes->rewind();
echo 'Ключ ', $sizes->key(), ': ', $sizes->current(), "\n";
$sizes->next();
$sizes->rewind();
while ($sizes->valid()) {
    echo 'Остаток ', $sizes->key(), ': ', $sizes->current(), "\n";
    $sizes->next();
}
echo 'После прохода: ', $sizes->count(), "\n";
Ожидаемый результат
Ключ 2: 40
Остаток 1: 25
Остаток 0: 12
После прохода: 0

key отражает число оставшихся элементов минус один, а не прежний индекс вставки. next удалил 40. rewind — пустое действие для кучи: 40 не вернулся. current читает вершину, valid позволяет продолжать, пока есть элементы. Обход потребил весь контейнер.

Скачать самостоятельный пример с результатом и README

Просмотр без потери исходных значенийСамостоятельный пример
<?php
declare(strict_types=1);

$sizes = new SplMaxHeap();
foreach ([12, 40, 25] as $size) { $sizes->insert($size); }
$preview = clone $sizes;
foreach ($preview as $size) { echo 'Предпросмотр: ', $size, "\n"; }
echo 'Осталось в копии: ', $preview->count(), "\n";
echo 'В исходной куче: ', $sizes->count(), "\n";
echo 'Реально выбран: ', $sizes->extract(), "\n";
Ожидаемый результат
Предпросмотр: 40
Предпросмотр: 25
Предпросмотр: 12
Осталось в копии: 0
В исходной куче: 3
Реально выбран: 40

foreach кучи последовательно удаляет вершины. clone создаёт отдельный контейнер, поэтому обзор опустошает $preview, а не $sizes. Клонирование контейнера поверхностное: вложенные объекты остаются общими, поэтому это не снимок состояния всего графа объектов.

Скачать самостоятельный пример с результатом и README

Продолжение: SplHeap::top, SplHeap::isEmpty.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplHeap::nextУдалить вершину при продвижении

PHP 5.3+ · SPL

public function SplHeap::next(): void

next() потребляет верхний элемент без выдачи его значения. Для обработки сначала current(), затем next(); либо проще extract().

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplHeap::next(): void
Результатvoid: следующий current() увидит уже новую вершину.
Ошибки и особые значенияСравнение оставшихся значений может выбросить исключение.
ВерсииPHP 5.3+
Один указатель всегда смотрит на вершинуСамостоятельный пример
<?php
declare(strict_types=1);

$sizes = new SplMaxHeap();
$sizes->insert(12);
$sizes->insert(40);
$sizes->insert(25);
$sizes->rewind();
echo 'Ключ ', $sizes->key(), ': ', $sizes->current(), "\n";
$sizes->next();
$sizes->rewind();
while ($sizes->valid()) {
    echo 'Остаток ', $sizes->key(), ': ', $sizes->current(), "\n";
    $sizes->next();
}
echo 'После прохода: ', $sizes->count(), "\n";
Ожидаемый результат
Ключ 2: 40
Остаток 1: 25
Остаток 0: 12
После прохода: 0

key отражает число оставшихся элементов минус один, а не прежний индекс вставки. next удалил 40. rewind — пустое действие для кучи: 40 не вернулся. current читает вершину, valid позволяет продолжать, пока есть элементы. Обход потребил весь контейнер.

Скачать самостоятельный пример с результатом и README

Выбрать самый крупный остатокСамостоятельный пример
<?php
declare(strict_types=1);

$stock = new SplMaxHeap();
$stock->insert(12);
$stock->insert(40);
$stock->insert(25);
$amount = $stock->extract();
echo 'Первый объём: ', $amount, "\n";
echo 'Следующий объём: ', $stock->top(), "\n";
Ожидаемый результат
Первый объём: 40
Следующий объём: 25

SplMaxHeap выбирает наибольшее значение. extract возвращает 40, следующий top — 25. Мы храним только количества: если нужен ещё и артикул, используйте запись и собственное сравнение либо SplPriorityQueue с количеством как приоритетом.

Скачать самостоятельный пример с результатом и README

Продолжение: SplHeap::top, SplHeap::isEmpty.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplHeap::rewindПонять, почему извлечённые элементы не возвращаются

PHP 5.3+ · SPL

public function SplHeap::rewind(): void

rewind() — no-op: виртуальный указатель всегда у вершины. Это удовлетворяет интерфейсу Iterator, но не восстанавливает потреблённые элементы.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplHeap::rewind(): void
Результатvoid; контейнер не изменяется.
Ошибки и особые значенияПовторный foreach той же опустошённой структуры не выдаст прежние значения.
ВерсииPHP 5.3+
Один указатель всегда смотрит на вершинуСамостоятельный пример
<?php
declare(strict_types=1);

$sizes = new SplMaxHeap();
$sizes->insert(12);
$sizes->insert(40);
$sizes->insert(25);
$sizes->rewind();
echo 'Ключ ', $sizes->key(), ': ', $sizes->current(), "\n";
$sizes->next();
$sizes->rewind();
while ($sizes->valid()) {
    echo 'Остаток ', $sizes->key(), ': ', $sizes->current(), "\n";
    $sizes->next();
}
echo 'После прохода: ', $sizes->count(), "\n";
Ожидаемый результат
Ключ 2: 40
Остаток 1: 25
Остаток 0: 12
После прохода: 0

key отражает число оставшихся элементов минус один, а не прежний индекс вставки. next удалил 40. rewind — пустое действие для кучи: 40 не вернулся. current читает вершину, valid позволяет продолжать, пока есть элементы. Обход потребил весь контейнер.

Скачать самостоятельный пример с результатом и README

Просмотр без потери исходных значенийСамостоятельный пример
<?php
declare(strict_types=1);

$sizes = new SplMaxHeap();
foreach ([12, 40, 25] as $size) { $sizes->insert($size); }
$preview = clone $sizes;
foreach ($preview as $size) { echo 'Предпросмотр: ', $size, "\n"; }
echo 'Осталось в копии: ', $preview->count(), "\n";
echo 'В исходной куче: ', $sizes->count(), "\n";
echo 'Реально выбран: ', $sizes->extract(), "\n";
Ожидаемый результат
Предпросмотр: 40
Предпросмотр: 25
Предпросмотр: 12
Осталось в копии: 0
В исходной куче: 3
Реально выбран: 40

foreach кучи последовательно удаляет вершины. clone создаёт отдельный контейнер, поэтому обзор опустошает $preview, а не $sizes. Клонирование контейнера поверхностное: вложенные объекты остаются общими, поэтому это не снимок состояния всего графа объектов.

Скачать самостоятельный пример с результатом и README

Продолжение: SplHeap::top, SplHeap::isEmpty.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplHeap::validОстановить ручной обход на пустой структуре

PHP 5.3+ · SPL

public function SplHeap::valid(): bool

valid() разрешает чтение текущей вершины, пока узлы существуют. В отличие от связного списка отдельной позиции вне непустой кучи здесь нет.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplHeap::valid(): bool
Результатbool: true, когда есть хотя бы один узел.
Ошибки и особые значенияНаличие узлов не подтверждает корректность порядка после исключения compare; учитывайте isCorrupted().
ВерсииPHP 5.3+
Один указатель всегда смотрит на вершинуСамостоятельный пример
<?php
declare(strict_types=1);

$sizes = new SplMaxHeap();
$sizes->insert(12);
$sizes->insert(40);
$sizes->insert(25);
$sizes->rewind();
echo 'Ключ ', $sizes->key(), ': ', $sizes->current(), "\n";
$sizes->next();
$sizes->rewind();
while ($sizes->valid()) {
    echo 'Остаток ', $sizes->key(), ': ', $sizes->current(), "\n";
    $sizes->next();
}
echo 'После прохода: ', $sizes->count(), "\n";
Ожидаемый результат
Ключ 2: 40
Остаток 1: 25
Остаток 0: 12
После прохода: 0

key отражает число оставшихся элементов минус один, а не прежний индекс вставки. next удалил 40. rewind — пустое действие для кучи: 40 не вернулся. current читает вершину, valid позволяет продолжать, пока есть элементы. Обход потребил весь контейнер.

Скачать самостоятельный пример с результатом и README

Остановиться, когда значения закончилисьСамостоятельный пример
<?php
declare(strict_types=1);

$sizes = new SplMaxHeap();
$sizes->insert(12);
while (!$sizes->isEmpty()) { echo 'Выдано: ', $sizes->extract(), "\n"; }
try { $sizes->top(); }
catch (RuntimeException $error) { echo "Больше остатков нет\n"; }
Ожидаемый результат
Выдано: 12
Больше остатков нет

isEmpty управляет повторением до очередного извлечения. Отдельный top на уже пустой куче вызывает RuntimeException; это не нулевой остаток. Полезное нулевое значение тоже можно хранить и извлекать.

Скачать самостоятельный пример с результатом и README

Продолжение: SplHeap::top, SplHeap::isEmpty.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplHeap::isCorruptedВыбрать восстановление после исключения

PHP 7+ · SPL

public function SplHeap::isCorrupted(): bool

isCorrupted() сообщает о флаге нарушения после отказа сравнения. Это контроль состояния алгоритма, не проверка бизнес-валидности всех заданий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplHeap::isCorrupted(): bool
Результатbool: true в заблокированном состоянии.
Ошибки и особые значенияfalse не доказывает, что входные данные правильные или приоритеты соответствуют требованиям.
ВерсииPHP 7+
Отказ сравнения: снять блокировку и заново построить рабочую структуруСамостоятельный пример
<?php
declare(strict_types=1);

class GuardedHeap extends SplMaxHeap {
    protected function compare(mixed $first, mixed $second): int {
        if (!is_int($first) || !is_int($second)) {
            throw new InvalidArgumentException('Нужны целые приоритеты');
        }
        return $first <=> $second;
    }
}
$broken = new GuardedHeap();
$broken->insert(20);
try { $broken->insert('bad'); }
catch (InvalidArgumentException $error) { echo "Некорректная запись остановила сравнение\n"; }
if ($broken->isCorrupted()) {
    echo "Очередность больше не доверенная\n";
    $broken->recoverFromCorruption();
    echo "Блокировка снята; перестраиваем из проверенного источника\n";
}
$clean = new SplMaxHeap();
$clean->insert(20);
$clean->insert(10);
while (!$clean->isEmpty()) { echo 'Восстановлено: ', $clean->extract(), "\n"; }
Ожидаемый результат
Некорректная запись остановила сравнение
Очередность больше не доверенная
Блокировка снята; перестраиваем из проверенного источника
Восстановлено: 20
Восстановлено: 10

Первая вставка не требует сравнения, вторая приносит неподходящий тип. Исключение из compare оставляет контейнер в состоянии corrupted. isCorrupted выбирает восстановление; recoverFromCorruption лишь очищает флаг блокировки и возвращает true, не пересортировывает узлы. Поэтому рабочий $clean создан заново из отдельного проверенного источника; повреждённый $broken больше не используется. Проверять вход лучше до insert, а не внутри сравнения.

Скачать самостоятельный пример с результатом и README

Отсеять неверный срок до изменения кучиСамостоятельный пример
<?php
declare(strict_types=1);

$minutes = new SplMinHeap();
foreach ([20, 'later', 10] as $value) {
    if (!is_int($value) || $value < 0) {
        echo "Пропущен неверный срок\n";
        continue;
    }
    $minutes->insert($value);
}
while (!$minutes->isEmpty()) { echo 'Минута: ', $minutes->extract(), "\n"; }
Ожидаемый результат
Пропущен неверный срок
Минута: 10
Минута: 20

is_int и проверка диапазона происходят до insert. continue пропускает эту запись и начинает следующий проход foreach. Внутри кучи остаются однородные числа, и стандартное сравнение уже не зависит от внешней ошибки.

Скачать самостоятельный пример с результатом и README

Продолжение: SplHeap::top, SplHeap::isEmpty.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplHeap::recoverFromCorruptionСнять блокировку, не приписывая ей пересортировку

PHP 5.3+; tentative return true с PHP 8.4 · SPL

public function SplHeap::recoverFromCorruption(): true

Метод очищает флаг corrupted. Он не восстанавливает heap-property и не обещает, что вставка, на которой было исключение, откатилась.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplHeap::recoverFromCorruption(): true
Результатtrue при нормальном завершении; после вызова isCorrupted() становится false.
Ошибки и особые значенияЕсли compare продолжает ошибаться, следующая операция снова может блокировать структуру. Без проверенного источника нельзя обещать сохранность очередности.
ВерсииPHP 5.3+; tentative return true с PHP 8.4
Отказ сравнения: снять блокировку и заново построить рабочую структуруСамостоятельный пример
<?php
declare(strict_types=1);

class GuardedHeap extends SplMaxHeap {
    protected function compare(mixed $first, mixed $second): int {
        if (!is_int($first) || !is_int($second)) {
            throw new InvalidArgumentException('Нужны целые приоритеты');
        }
        return $first <=> $second;
    }
}
$broken = new GuardedHeap();
$broken->insert(20);
try { $broken->insert('bad'); }
catch (InvalidArgumentException $error) { echo "Некорректная запись остановила сравнение\n"; }
if ($broken->isCorrupted()) {
    echo "Очередность больше не доверенная\n";
    $broken->recoverFromCorruption();
    echo "Блокировка снята; перестраиваем из проверенного источника\n";
}
$clean = new SplMaxHeap();
$clean->insert(20);
$clean->insert(10);
while (!$clean->isEmpty()) { echo 'Восстановлено: ', $clean->extract(), "\n"; }
Ожидаемый результат
Некорректная запись остановила сравнение
Очередность больше не доверенная
Блокировка снята; перестраиваем из проверенного источника
Восстановлено: 20
Восстановлено: 10

Первая вставка не требует сравнения, вторая приносит неподходящий тип. Исключение из compare оставляет контейнер в состоянии corrupted. isCorrupted выбирает восстановление; recoverFromCorruption лишь очищает флаг блокировки и возвращает true, не пересортировывает узлы. Поэтому рабочий $clean создан заново из отдельного проверенного источника; повреждённый $broken больше не используется. Проверять вход лучше до insert, а не внутри сравнения.

Скачать самостоятельный пример с результатом и README

Отсеять неверный срок до изменения кучиСамостоятельный пример
<?php
declare(strict_types=1);

$minutes = new SplMinHeap();
foreach ([20, 'later', 10] as $value) {
    if (!is_int($value) || $value < 0) {
        echo "Пропущен неверный срок\n";
        continue;
    }
    $minutes->insert($value);
}
while (!$minutes->isEmpty()) { echo 'Минута: ', $minutes->extract(), "\n"; }
Ожидаемый результат
Пропущен неверный срок
Минута: 10
Минута: 20

is_int и проверка диапазона происходят до insert. continue пропускает эту запись и начинает следующий проход foreach. Внутри кучи остаются однородные числа, и стандартное сравнение уже не зависит от внешней ошибки.

Скачать самостоятельный пример с результатом и README

Продолжение: SplHeap::top, SplHeap::isEmpty.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplPriorityQueue::insertПоместить новое значение в структуру

PHP 5.3+; tentative return true с PHP 8.4 · SPL

public function SplPriorityQueue::insert(mixed $value, mixed $priority): true

Вставка перестраивает только нужный путь к вершине. Аргумент value — работа, priority — правило её порядка; они хранятся отдельно.

ПараметрЧто означает в задаче
valueСохраняемое значение любого типа.
priorityСопоставимый приоритет: предпочтительно единый тип и явное правило при равенстве.
Часть контрактаЧто важно
Сигнатураpublic function SplPriorityQueue::insert(mixed $value, mixed $priority): true
Результатtrue при нормальном завершении; это не вставленное значение и не новый контейнер. Полезные данные получают через top/extract.
Ошибки и особые значенияИсключение compare может испортить структуру и оставить вставку частично выполненной. Проверяйте вход заранее.
ВерсииPHP 5.3+; tentative return true с PHP 8.4
Срочное письмо получить раньше отчётаСамостоятельный пример
<?php
declare(strict_types=1);

$jobs = new SplPriorityQueue();
$jobs->insert('Отчёт', 10);
$jobs->insert('Сброс пароля', 50);
echo 'Следующее: ', $jobs->top(), "\n";
$job = $jobs->extract();
echo 'Обработать: ', $job, "\n";
echo 'После него: ', $jobs->extract(), "\n";
Ожидаемый результат
Следующее: Сброс пароля
Обработать: Сброс пароля
После него: Отчёт

Первый аргумент insert — полезные данные, второй — приоритет. Большее число 50 важнее 10, поэтому «Сброс пароля» возвращается раньше. top не удаляет, extract удаляет. По умолчанию возвращаются данные; код лишь показывает выбранные задания и не отправляет письма.

Скачать самостоятельный пример с результатом и README

Сохранить FIFO внутри одинаковой срочностиСамостоятельный пример
<?php
declare(strict_types=1);

class StableJobs extends SplPriorityQueue {
    public function compare(mixed $first, mixed $second): int {
        $urgency = $first['level'] <=> $second['level'];
        if ($urgency !== 0) { return $urgency; }
        return $second['sequence'] <=> $first['sequence'];
    }
}
$jobs = new StableJobs();
$jobs->insert('Отчёт A', ['level' => 10, 'sequence' => 1]);
$jobs->insert('Отчёт B', ['level' => 10, 'sequence' => 2]);
$jobs->insert('Пароль', ['level' => 50, 'sequence' => 3]);
while (!$jobs->isEmpty()) { echo $jobs->extract(), "\n"; }
Ожидаемый результат
Пароль
Отчёт A
Отчёт B

Второй аргумент insert теперь массив приоритета из двух полей. Встроенная куча вызывает compare с двумя такими массивами, не со строками задания. Сначала return отдаёт знак сравнения level. При одинаковом level меньший sequence получает больший приоритет через обратное сравнение. Возврат compare используется только алгоритмом; extract позже возвращает строку. Счётчик sequence должен быть уникальным и возрастающим в пределах этого планировщика.

Скачать самостоятельный пример с результатом и README

Продолжение: SplPriorityQueue::top, SplPriorityQueue::isEmpty.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplPriorityQueue::topПрочитать вершину без удаления

PHP 5.3+ · SPL

public function SplPriorityQueue::top(): mixed

top() даёт следующего кандидата, сохраняя количество элементов.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplPriorityQueue::top(): mixed
Результатmixed: данные, приоритет или массив data/priority согласно getExtractFlags().
Ошибки и особые значенияПустой или заблокированный контейнер — RuntimeException.
ВерсииPHP 5.3+
Срочное письмо получить раньше отчётаСамостоятельный пример
<?php
declare(strict_types=1);

$jobs = new SplPriorityQueue();
$jobs->insert('Отчёт', 10);
$jobs->insert('Сброс пароля', 50);
echo 'Следующее: ', $jobs->top(), "\n";
$job = $jobs->extract();
echo 'Обработать: ', $job, "\n";
echo 'После него: ', $jobs->extract(), "\n";
Ожидаемый результат
Следующее: Сброс пароля
Обработать: Сброс пароля
После него: Отчёт

Первый аргумент insert — полезные данные, второй — приоритет. Большее число 50 важнее 10, поэтому «Сброс пароля» возвращается раньше. top не удаляет, extract удаляет. По умолчанию возвращаются данные; код лишь показывает выбранные задания и не отправляет письма.

Скачать самостоятельный пример с результатом и README

Получить вместе задание и его приоритетСамостоятельный пример
<?php
declare(strict_types=1);

$jobs = new SplPriorityQueue();
$jobs->insert('Сброс пароля', 50);
$saved = $jobs->getExtractFlags();
$jobs->setExtractFlags(SplPriorityQueue::EXTR_PRIORITY);
echo 'Приоритет: ', $jobs->top(), "\n";
$jobs->setExtractFlags(SplPriorityQueue::EXTR_BOTH);
$entry = $jobs->current();
echo $entry['data'], ': ', $entry['priority'], "\n";
$jobs->setExtractFlags($saved);
echo 'К исполнению: ', $jobs->extract(), "\n";
Ожидаемый результат
Приоритет: 50
Сброс пароля: 50
К исполнению: Сброс пароля

EXTR_PRIORITY меняет форму чтения на число; EXTR_BOTH возвращает массив с ключами data и priority. Это не меняет очередность. getExtractFlags сохранил прежнюю настройку EXTR_DATA, setExtractFlags восстановил её, поэтому extract снова вернул строку задания.

Скачать самостоятельный пример с результатом и README

Продолжение: SplPriorityQueue::extract, SplPriorityQueue::isEmpty.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplPriorityQueue::extractВернуть вершину и удалить её

PHP 5.3+ · SPL

public function SplPriorityQueue::extract(): mixed

Возвращённое значение занимает место extract() в присваивании или echo; оставшиеся элементы восстанавливают отношение вершины.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplPriorityQueue::extract(): mixed
Результатmixed: данные, приоритет или массив data/priority согласно getExtractFlags().
Ошибки и особые значенияПустой контейнер — RuntimeException; compare может выбросить исключение и блокировать кучу.
ВерсииPHP 5.3+
Срочное письмо получить раньше отчётаСамостоятельный пример
<?php
declare(strict_types=1);

$jobs = new SplPriorityQueue();
$jobs->insert('Отчёт', 10);
$jobs->insert('Сброс пароля', 50);
echo 'Следующее: ', $jobs->top(), "\n";
$job = $jobs->extract();
echo 'Обработать: ', $job, "\n";
echo 'После него: ', $jobs->extract(), "\n";
Ожидаемый результат
Следующее: Сброс пароля
Обработать: Сброс пароля
После него: Отчёт

Первый аргумент insert — полезные данные, второй — приоритет. Большее число 50 важнее 10, поэтому «Сброс пароля» возвращается раньше. top не удаляет, extract удаляет. По умолчанию возвращаются данные; код лишь показывает выбранные задания и не отправляет письма.

Скачать самостоятельный пример с результатом и README

Пустая очередь и неверная форма выдачиСамостоятельный пример
<?php
declare(strict_types=1);

$jobs = new SplPriorityQueue();
try { $jobs->setExtractFlags(0); }
catch (RuntimeException $error) { echo "Нужно выбрать данные, приоритет или оба\n"; }
if ($jobs->isEmpty()) { echo "Задания не поступили\n"; }
try { $jobs->extract(); }
catch (RuntimeException $error) { echo "Извлекать нечего\n"; }
Ожидаемый результат
Нужно выбрать данные, приоритет или оба
Задания не поступили
Извлекать нечего

Нулевой flags не выбирает ни одного компонента и вызывает RuntimeException. Другая независимая ошибка — extract пустой очереди. В обычном цикле её избегают проверкой isEmpty, а исключения оставляют для нарушения ожидаемого состояния.

Скачать самостоятельный пример с результатом и README

Продолжение: SplPriorityQueue::top, SplPriorityQueue::isEmpty.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplPriorityQueue::countУзнать объём ожидающей работы

PHP 5.3+ · SPL

public function SplPriorityQueue::count(): int

Число элементов используется для лимита и оценки остатка. count($container) вызывает договор Countable.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplPriorityQueue::count(): int
Результатint: число узлов, включая равные и нулевые значения.
Ошибки и особые значенияПодсчёт не выполняет работу и не удаляет узлы.
ВерсииPHP 5.3+
Потребить приоритетную очередь вручнуюСамостоятельный пример
<?php
declare(strict_types=1);

$jobs = new SplPriorityQueue();
$jobs->insert('Отчёт', 10);
$jobs->insert('Пароль', 50);
$jobs->insert('Чек', 20);
$jobs->rewind();
while ($jobs->valid()) {
    echo $jobs->key(), ': ', $jobs->current(), "\n";
    $jobs->next();
}
$jobs->rewind();
echo 'После rewind осталось: ', $jobs->count(), "\n";
Ожидаемый результат
2: Пароль
1: Чек
0: Отчёт
После rewind осталось: 0

Виртуальный итератор всегда смотрит на вершину. current получает данные согласно флагу; next удаляет вершину без возврата. key равен текущему count()-1 и не является исходным номером задания. rewind не возвращает уже удалённую работу.

Скачать самостоятельный пример с результатом и README

Получить вместе задание и его приоритетСамостоятельный пример
<?php
declare(strict_types=1);

$jobs = new SplPriorityQueue();
$jobs->insert('Сброс пароля', 50);
$saved = $jobs->getExtractFlags();
$jobs->setExtractFlags(SplPriorityQueue::EXTR_PRIORITY);
echo 'Приоритет: ', $jobs->top(), "\n";
$jobs->setExtractFlags(SplPriorityQueue::EXTR_BOTH);
$entry = $jobs->current();
echo $entry['data'], ': ', $entry['priority'], "\n";
$jobs->setExtractFlags($saved);
echo 'К исполнению: ', $jobs->extract(), "\n";
Ожидаемый результат
Приоритет: 50
Сброс пароля: 50
К исполнению: Сброс пароля

EXTR_PRIORITY меняет форму чтения на число; EXTR_BOTH возвращает массив с ключами data и priority. Это не меняет очередность. getExtractFlags сохранил прежнюю настройку EXTR_DATA, setExtractFlags восстановил её, поэтому extract снова вернул строку задания.

Скачать самостоятельный пример с результатом и README

Продолжение: SplPriorityQueue::top, SplPriorityQueue::isEmpty.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplPriorityQueue::isEmptyПродолжать выдачу до опустошения

PHP 5.3+ · SPL

public function SplPriorityQueue::isEmpty(): bool

Условие !$queue->isEmpty() проверяется до очередного extract, чтобы отсутствие работы не стало исключением.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplPriorityQueue::isEmpty(): bool
Результатbool: true только когда узлов нет.
Ошибки и особые значенияНулевая величина или null внутри узла не делают контейнер пустым.
ВерсииPHP 5.3+
Сохранить FIFO внутри одинаковой срочностиСамостоятельный пример
<?php
declare(strict_types=1);

class StableJobs extends SplPriorityQueue {
    public function compare(mixed $first, mixed $second): int {
        $urgency = $first['level'] <=> $second['level'];
        if ($urgency !== 0) { return $urgency; }
        return $second['sequence'] <=> $first['sequence'];
    }
}
$jobs = new StableJobs();
$jobs->insert('Отчёт A', ['level' => 10, 'sequence' => 1]);
$jobs->insert('Отчёт B', ['level' => 10, 'sequence' => 2]);
$jobs->insert('Пароль', ['level' => 50, 'sequence' => 3]);
while (!$jobs->isEmpty()) { echo $jobs->extract(), "\n"; }
Ожидаемый результат
Пароль
Отчёт A
Отчёт B

Второй аргумент insert теперь массив приоритета из двух полей. Встроенная куча вызывает compare с двумя такими массивами, не со строками задания. Сначала return отдаёт знак сравнения level. При одинаковом level меньший sequence получает больший приоритет через обратное сравнение. Возврат compare используется только алгоритмом; extract позже возвращает строку. Счётчик sequence должен быть уникальным и возрастающим в пределах этого планировщика.

Скачать самостоятельный пример с результатом и README

Пустая очередь и неверная форма выдачиСамостоятельный пример
<?php
declare(strict_types=1);

$jobs = new SplPriorityQueue();
try { $jobs->setExtractFlags(0); }
catch (RuntimeException $error) { echo "Нужно выбрать данные, приоритет или оба\n"; }
if ($jobs->isEmpty()) { echo "Задания не поступили\n"; }
try { $jobs->extract(); }
catch (RuntimeException $error) { echo "Извлекать нечего\n"; }
Ожидаемый результат
Нужно выбрать данные, приоритет или оба
Задания не поступили
Извлекать нечего

Нулевой flags не выбирает ни одного компонента и вызывает RuntimeException. Другая независимая ошибка — extract пустой очереди. В обычном цикле её избегают проверкой isEmpty, а исключения оставляют для нарушения ожидаемого состояния.

Скачать самостоятельный пример с результатом и README

Продолжение: SplPriorityQueue::top, SplPriorityQueue::count.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplPriorityQueue::currentПрочитать текущую вершину итератора

PHP 5.3+ · SPL

public function SplPriorityQueue::current(): mixed

Виртуальный итератор остаётся у вершины. current() читает её, не перемещается и не удаляет.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplPriorityQueue::current(): mixed
Результатmixed: данные, приоритет или массив data/priority согласно getExtractFlags(). Для пустого контейнера в текущем PHP null; перед чтением проверяйте valid().
Ошибки и особые значенияnull может быть полезным значением; corrupted блокирует нормальное чтение.
ВерсииPHP 5.3+
Потребить приоритетную очередь вручнуюСамостоятельный пример
<?php
declare(strict_types=1);

$jobs = new SplPriorityQueue();
$jobs->insert('Отчёт', 10);
$jobs->insert('Пароль', 50);
$jobs->insert('Чек', 20);
$jobs->rewind();
while ($jobs->valid()) {
    echo $jobs->key(), ': ', $jobs->current(), "\n";
    $jobs->next();
}
$jobs->rewind();
echo 'После rewind осталось: ', $jobs->count(), "\n";
Ожидаемый результат
2: Пароль
1: Чек
0: Отчёт
После rewind осталось: 0

Виртуальный итератор всегда смотрит на вершину. current получает данные согласно флагу; next удаляет вершину без возврата. key равен текущему count()-1 и не является исходным номером задания. rewind не возвращает уже удалённую работу.

Скачать самостоятельный пример с результатом и README

Получить вместе задание и его приоритетСамостоятельный пример
<?php
declare(strict_types=1);

$jobs = new SplPriorityQueue();
$jobs->insert('Сброс пароля', 50);
$saved = $jobs->getExtractFlags();
$jobs->setExtractFlags(SplPriorityQueue::EXTR_PRIORITY);
echo 'Приоритет: ', $jobs->top(), "\n";
$jobs->setExtractFlags(SplPriorityQueue::EXTR_BOTH);
$entry = $jobs->current();
echo $entry['data'], ': ', $entry['priority'], "\n";
$jobs->setExtractFlags($saved);
echo 'К исполнению: ', $jobs->extract(), "\n";
Ожидаемый результат
Приоритет: 50
Сброс пароля: 50
К исполнению: Сброс пароля

EXTR_PRIORITY меняет форму чтения на число; EXTR_BOTH возвращает массив с ключами data и priority. Это не меняет очередность. getExtractFlags сохранил прежнюю настройку EXTR_DATA, setExtractFlags восстановил её, поэтому extract снова вернул строку задания.

Скачать самостоятельный пример с результатом и README

Продолжение: SplPriorityQueue::top, SplPriorityQueue::isEmpty.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplPriorityQueue::keyПрочитать номер оставшейся вершины

PHP 5.3+ · SPL

public function SplPriorityQueue::key(): int

key() возвращает число оставшихся узлов минус один. Это технический ключ итератора, а не ID задачи, не её priority и не порядок вставки.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplPriorityQueue::key(): int
Результатint при действительном итераторе.
Ошибки и особые значенияПосле конца ключ не обозначает существующий узел; сначала valid().
ВерсииPHP 5.3+
Потребить приоритетную очередь вручнуюСамостоятельный пример
<?php
declare(strict_types=1);

$jobs = new SplPriorityQueue();
$jobs->insert('Отчёт', 10);
$jobs->insert('Пароль', 50);
$jobs->insert('Чек', 20);
$jobs->rewind();
while ($jobs->valid()) {
    echo $jobs->key(), ': ', $jobs->current(), "\n";
    $jobs->next();
}
$jobs->rewind();
echo 'После rewind осталось: ', $jobs->count(), "\n";
Ожидаемый результат
2: Пароль
1: Чек
0: Отчёт
После rewind осталось: 0

Виртуальный итератор всегда смотрит на вершину. current получает данные согласно флагу; next удаляет вершину без возврата. key равен текущему count()-1 и не является исходным номером задания. rewind не возвращает уже удалённую работу.

Скачать самостоятельный пример с результатом и README

Сохранить FIFO внутри одинаковой срочностиСамостоятельный пример
<?php
declare(strict_types=1);

class StableJobs extends SplPriorityQueue {
    public function compare(mixed $first, mixed $second): int {
        $urgency = $first['level'] <=> $second['level'];
        if ($urgency !== 0) { return $urgency; }
        return $second['sequence'] <=> $first['sequence'];
    }
}
$jobs = new StableJobs();
$jobs->insert('Отчёт A', ['level' => 10, 'sequence' => 1]);
$jobs->insert('Отчёт B', ['level' => 10, 'sequence' => 2]);
$jobs->insert('Пароль', ['level' => 50, 'sequence' => 3]);
while (!$jobs->isEmpty()) { echo $jobs->extract(), "\n"; }
Ожидаемый результат
Пароль
Отчёт A
Отчёт B

Второй аргумент insert теперь массив приоритета из двух полей. Встроенная куча вызывает compare с двумя такими массивами, не со строками задания. Сначала return отдаёт знак сравнения level. При одинаковом level меньший sequence получает больший приоритет через обратное сравнение. Возврат compare используется только алгоритмом; extract позже возвращает строку. Счётчик sequence должен быть уникальным и возрастающим в пределах этого планировщика.

Скачать самостоятельный пример с результатом и README

Продолжение: SplPriorityQueue::top, SplPriorityQueue::isEmpty.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplPriorityQueue::nextУдалить вершину при продвижении

PHP 5.3+ · SPL

public function SplPriorityQueue::next(): void

next() потребляет верхний элемент без выдачи его значения. Для обработки сначала current(), затем next(); либо проще extract().

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplPriorityQueue::next(): void
Результатvoid: следующий current() увидит уже новую вершину.
Ошибки и особые значенияСравнение оставшихся значений может выбросить исключение.
ВерсииPHP 5.3+
Потребить приоритетную очередь вручнуюСамостоятельный пример
<?php
declare(strict_types=1);

$jobs = new SplPriorityQueue();
$jobs->insert('Отчёт', 10);
$jobs->insert('Пароль', 50);
$jobs->insert('Чек', 20);
$jobs->rewind();
while ($jobs->valid()) {
    echo $jobs->key(), ': ', $jobs->current(), "\n";
    $jobs->next();
}
$jobs->rewind();
echo 'После rewind осталось: ', $jobs->count(), "\n";
Ожидаемый результат
2: Пароль
1: Чек
0: Отчёт
После rewind осталось: 0

Виртуальный итератор всегда смотрит на вершину. current получает данные согласно флагу; next удаляет вершину без возврата. key равен текущему count()-1 и не является исходным номером задания. rewind не возвращает уже удалённую работу.

Скачать самостоятельный пример с результатом и README

Срочное письмо получить раньше отчётаСамостоятельный пример
<?php
declare(strict_types=1);

$jobs = new SplPriorityQueue();
$jobs->insert('Отчёт', 10);
$jobs->insert('Сброс пароля', 50);
echo 'Следующее: ', $jobs->top(), "\n";
$job = $jobs->extract();
echo 'Обработать: ', $job, "\n";
echo 'После него: ', $jobs->extract(), "\n";
Ожидаемый результат
Следующее: Сброс пароля
Обработать: Сброс пароля
После него: Отчёт

Первый аргумент insert — полезные данные, второй — приоритет. Большее число 50 важнее 10, поэтому «Сброс пароля» возвращается раньше. top не удаляет, extract удаляет. По умолчанию возвращаются данные; код лишь показывает выбранные задания и не отправляет письма.

Скачать самостоятельный пример с результатом и README

Продолжение: SplPriorityQueue::top, SplPriorityQueue::isEmpty.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplPriorityQueue::rewindПонять, почему извлечённые элементы не возвращаются

PHP 5.3+ · SPL

public function SplPriorityQueue::rewind(): void

rewind() — no-op: виртуальный указатель всегда у вершины. Это удовлетворяет интерфейсу Iterator, но не восстанавливает потреблённые элементы.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplPriorityQueue::rewind(): void
Результатvoid; контейнер не изменяется.
Ошибки и особые значенияПовторный foreach той же опустошённой структуры не выдаст прежние значения.
ВерсииPHP 5.3+
Потребить приоритетную очередь вручнуюСамостоятельный пример
<?php
declare(strict_types=1);

$jobs = new SplPriorityQueue();
$jobs->insert('Отчёт', 10);
$jobs->insert('Пароль', 50);
$jobs->insert('Чек', 20);
$jobs->rewind();
while ($jobs->valid()) {
    echo $jobs->key(), ': ', $jobs->current(), "\n";
    $jobs->next();
}
$jobs->rewind();
echo 'После rewind осталось: ', $jobs->count(), "\n";
Ожидаемый результат
2: Пароль
1: Чек
0: Отчёт
После rewind осталось: 0

Виртуальный итератор всегда смотрит на вершину. current получает данные согласно флагу; next удаляет вершину без возврата. key равен текущему count()-1 и не является исходным номером задания. rewind не возвращает уже удалённую работу.

Скачать самостоятельный пример с результатом и README

Сохранить FIFO внутри одинаковой срочностиСамостоятельный пример
<?php
declare(strict_types=1);

class StableJobs extends SplPriorityQueue {
    public function compare(mixed $first, mixed $second): int {
        $urgency = $first['level'] <=> $second['level'];
        if ($urgency !== 0) { return $urgency; }
        return $second['sequence'] <=> $first['sequence'];
    }
}
$jobs = new StableJobs();
$jobs->insert('Отчёт A', ['level' => 10, 'sequence' => 1]);
$jobs->insert('Отчёт B', ['level' => 10, 'sequence' => 2]);
$jobs->insert('Пароль', ['level' => 50, 'sequence' => 3]);
while (!$jobs->isEmpty()) { echo $jobs->extract(), "\n"; }
Ожидаемый результат
Пароль
Отчёт A
Отчёт B

Второй аргумент insert теперь массив приоритета из двух полей. Встроенная куча вызывает compare с двумя такими массивами, не со строками задания. Сначала return отдаёт знак сравнения level. При одинаковом level меньший sequence получает больший приоритет через обратное сравнение. Возврат compare используется только алгоритмом; extract позже возвращает строку. Счётчик sequence должен быть уникальным и возрастающим в пределах этого планировщика.

Скачать самостоятельный пример с результатом и README

Продолжение: SplPriorityQueue::top, SplPriorityQueue::isEmpty.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplPriorityQueue::validОстановить ручной обход на пустой структуре

PHP 5.3+ · SPL

public function SplPriorityQueue::valid(): bool

valid() разрешает чтение текущей вершины, пока узлы существуют. В отличие от связного списка отдельной позиции вне непустой кучи здесь нет.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplPriorityQueue::valid(): bool
Результатbool: true, когда есть хотя бы один узел.
Ошибки и особые значенияНаличие узлов не подтверждает корректность порядка после исключения compare; учитывайте isCorrupted().
ВерсииPHP 5.3+
Потребить приоритетную очередь вручнуюСамостоятельный пример
<?php
declare(strict_types=1);

$jobs = new SplPriorityQueue();
$jobs->insert('Отчёт', 10);
$jobs->insert('Пароль', 50);
$jobs->insert('Чек', 20);
$jobs->rewind();
while ($jobs->valid()) {
    echo $jobs->key(), ': ', $jobs->current(), "\n";
    $jobs->next();
}
$jobs->rewind();
echo 'После rewind осталось: ', $jobs->count(), "\n";
Ожидаемый результат
2: Пароль
1: Чек
0: Отчёт
После rewind осталось: 0

Виртуальный итератор всегда смотрит на вершину. current получает данные согласно флагу; next удаляет вершину без возврата. key равен текущему count()-1 и не является исходным номером задания. rewind не возвращает уже удалённую работу.

Скачать самостоятельный пример с результатом и README

Пустая очередь и неверная форма выдачиСамостоятельный пример
<?php
declare(strict_types=1);

$jobs = new SplPriorityQueue();
try { $jobs->setExtractFlags(0); }
catch (RuntimeException $error) { echo "Нужно выбрать данные, приоритет или оба\n"; }
if ($jobs->isEmpty()) { echo "Задания не поступили\n"; }
try { $jobs->extract(); }
catch (RuntimeException $error) { echo "Извлекать нечего\n"; }
Ожидаемый результат
Нужно выбрать данные, приоритет или оба
Задания не поступили
Извлекать нечего

Нулевой flags не выбирает ни одного компонента и вызывает RuntimeException. Другая независимая ошибка — extract пустой очереди. В обычном цикле её избегают проверкой isEmpty, а исключения оставляют для нарушения ожидаемого состояния.

Скачать самостоятельный пример с результатом и README

Продолжение: SplPriorityQueue::top, SplPriorityQueue::isEmpty.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplPriorityQueue::isCorruptedВыбрать восстановление после исключения

PHP 7+ · SPL

public function SplPriorityQueue::isCorrupted(): bool

isCorrupted() сообщает о флаге нарушения после отказа сравнения. Это контроль состояния алгоритма, не проверка бизнес-валидности всех заданий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplPriorityQueue::isCorrupted(): bool
Результатbool: true в заблокированном состоянии.
Ошибки и особые значенияfalse не доказывает, что входные данные правильные или приоритеты соответствуют требованиям.
ВерсииPHP 7+
Отказ сравнения: снять блокировку и заново построить рабочую структуруСамостоятельный пример
<?php
declare(strict_types=1);

class GuardedHeap extends SplPriorityQueue {
    public function compare(mixed $first, mixed $second): int {
        if (!is_int($first) || !is_int($second)) {
            throw new InvalidArgumentException('Нужны целые приоритеты');
        }
        return $first <=> $second;
    }
}
$broken = new GuardedHeap();
$broken->insert('Пароль', 20);
try { $broken->insert('Ошибка', 'bad'); }
catch (InvalidArgumentException $error) { echo "Некорректная запись остановила сравнение\n"; }
if ($broken->isCorrupted()) {
    echo "Очередность больше не доверенная\n";
    $broken->recoverFromCorruption();
    echo "Блокировка снята; перестраиваем из проверенного источника\n";
}
$clean = new SplPriorityQueue();
$clean->insert('Пароль', 20);
$clean->insert('Отчёт', 10);
while (!$clean->isEmpty()) { echo 'Восстановлено: ', $clean->extract(), "\n"; }
Ожидаемый результат
Некорректная запись остановила сравнение
Очередность больше не доверенная
Блокировка снята; перестраиваем из проверенного источника
Восстановлено: Пароль
Восстановлено: Отчёт

Первая вставка не требует сравнения, вторая приносит неподходящий тип. Исключение из compare оставляет контейнер в состоянии corrupted. isCorrupted выбирает восстановление; recoverFromCorruption лишь очищает флаг блокировки и возвращает true, не пересортировывает узлы. Поэтому рабочий $clean создан заново из отдельного проверенного источника; повреждённый $broken больше не используется. Проверять вход лучше до insert, а не внутри сравнения.

Скачать самостоятельный пример с результатом и README

Сохранить FIFO внутри одинаковой срочностиСамостоятельный пример
<?php
declare(strict_types=1);

class StableJobs extends SplPriorityQueue {
    public function compare(mixed $first, mixed $second): int {
        $urgency = $first['level'] <=> $second['level'];
        if ($urgency !== 0) { return $urgency; }
        return $second['sequence'] <=> $first['sequence'];
    }
}
$jobs = new StableJobs();
$jobs->insert('Отчёт A', ['level' => 10, 'sequence' => 1]);
$jobs->insert('Отчёт B', ['level' => 10, 'sequence' => 2]);
$jobs->insert('Пароль', ['level' => 50, 'sequence' => 3]);
while (!$jobs->isEmpty()) { echo $jobs->extract(), "\n"; }
Ожидаемый результат
Пароль
Отчёт A
Отчёт B

Второй аргумент insert теперь массив приоритета из двух полей. Встроенная куча вызывает compare с двумя такими массивами, не со строками задания. Сначала return отдаёт знак сравнения level. При одинаковом level меньший sequence получает больший приоритет через обратное сравнение. Возврат compare используется только алгоритмом; extract позже возвращает строку. Счётчик sequence должен быть уникальным и возрастающим в пределах этого планировщика.

Скачать самостоятельный пример с результатом и README

Продолжение: SplPriorityQueue::top, SplPriorityQueue::isEmpty.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplPriorityQueue::recoverFromCorruptionСнять блокировку, не приписывая ей пересортировку

PHP 5.3+; tentative return true с PHP 8.4 · SPL

public function SplPriorityQueue::recoverFromCorruption(): true

Метод очищает флаг corrupted. Он не восстанавливает heap-property и не обещает, что вставка, на которой было исключение, откатилась.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplPriorityQueue::recoverFromCorruption(): true
Результатtrue при нормальном завершении; после вызова isCorrupted() становится false.
Ошибки и особые значенияЕсли compare продолжает ошибаться, следующая операция снова может блокировать структуру. Без проверенного источника нельзя обещать сохранность очередности.
ВерсииPHP 5.3+; tentative return true с PHP 8.4
Отказ сравнения: снять блокировку и заново построить рабочую структуруСамостоятельный пример
<?php
declare(strict_types=1);

class GuardedHeap extends SplPriorityQueue {
    public function compare(mixed $first, mixed $second): int {
        if (!is_int($first) || !is_int($second)) {
            throw new InvalidArgumentException('Нужны целые приоритеты');
        }
        return $first <=> $second;
    }
}
$broken = new GuardedHeap();
$broken->insert('Пароль', 20);
try { $broken->insert('Ошибка', 'bad'); }
catch (InvalidArgumentException $error) { echo "Некорректная запись остановила сравнение\n"; }
if ($broken->isCorrupted()) {
    echo "Очередность больше не доверенная\n";
    $broken->recoverFromCorruption();
    echo "Блокировка снята; перестраиваем из проверенного источника\n";
}
$clean = new SplPriorityQueue();
$clean->insert('Пароль', 20);
$clean->insert('Отчёт', 10);
while (!$clean->isEmpty()) { echo 'Восстановлено: ', $clean->extract(), "\n"; }
Ожидаемый результат
Некорректная запись остановила сравнение
Очередность больше не доверенная
Блокировка снята; перестраиваем из проверенного источника
Восстановлено: Пароль
Восстановлено: Отчёт

Первая вставка не требует сравнения, вторая приносит неподходящий тип. Исключение из compare оставляет контейнер в состоянии corrupted. isCorrupted выбирает восстановление; recoverFromCorruption лишь очищает флаг блокировки и возвращает true, не пересортировывает узлы. Поэтому рабочий $clean создан заново из отдельного проверенного источника; повреждённый $broken больше не используется. Проверять вход лучше до insert, а не внутри сравнения.

Скачать самостоятельный пример с результатом и README

Сохранить FIFO внутри одинаковой срочностиСамостоятельный пример
<?php
declare(strict_types=1);

class StableJobs extends SplPriorityQueue {
    public function compare(mixed $first, mixed $second): int {
        $urgency = $first['level'] <=> $second['level'];
        if ($urgency !== 0) { return $urgency; }
        return $second['sequence'] <=> $first['sequence'];
    }
}
$jobs = new StableJobs();
$jobs->insert('Отчёт A', ['level' => 10, 'sequence' => 1]);
$jobs->insert('Отчёт B', ['level' => 10, 'sequence' => 2]);
$jobs->insert('Пароль', ['level' => 50, 'sequence' => 3]);
while (!$jobs->isEmpty()) { echo $jobs->extract(), "\n"; }
Ожидаемый результат
Пароль
Отчёт A
Отчёт B

Второй аргумент insert теперь массив приоритета из двух полей. Встроенная куча вызывает compare с двумя такими массивами, не со строками задания. Сначала return отдаёт знак сравнения level. При одинаковом level меньший sequence получает больший приоритет через обратное сравнение. Возврат compare используется только алгоритмом; extract позже возвращает строку. Счётчик sequence должен быть уникальным и возрастающим в пределах этого планировщика.

Скачать самостоятельный пример с результатом и README

Продолжение: SplPriorityQueue::top, SplPriorityQueue::isEmpty.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplHeap::compareОпределить, какая запись важнее

PHP 5.3+; примеры рассчитаны на PHP 8.2+ · SPL

abstract protected function SplHeap::compare(mixed $value1, mixed $value2): int

Защищённый метод вызывается самой кучей; напрямую $heap->compare() извне недоступен. Для своей записи определите protected compare в наследнике. Готовые Min/Max уже задают правило для обычных значений PHP. Параметры получают сравниваемые значения, return передаёт только знак обратно алгоритму. Он не является возвращаемым заданием: задание позднее отдаёт extract().

ПараметрЧто означает в задаче
value1Первый сравниваемый приоритет или узел.
value2Второй сравниваемый приоритет или узел.
Часть контрактаЧто важно
Сигнатураabstract protected function SplHeap::compare(mixed $value1, mixed $value2): int
Результатint: Положительное число поднимает первый аргумент выше второго; отрицательное опускает; 0 означает равный приоритет.
Ошибки и особые значенияИсключение пользовательского compare может заблокировать кучу и нарушить порядок. Повторная вставка после отказа не является безопасным автоматическим повтором.
ВерсииPHP 5.3+; примеры рассчитаны на PHP 8.2+
Выбирать запись по срокуСамостоятельный пример
<?php
declare(strict_types=1);

class DeadlineHeap extends SplHeap {
    protected function compare(mixed $first, mixed $second): int {
        return $second['day'] <=> $first['day'];
    }
}
$tasks = new DeadlineHeap();
$tasks->insert(['title' => 'Отчёт', 'day' => 18]);
$tasks->insert(['title' => 'Счёт', 'day' => 15]);
while (!$tasks->isEmpty()) {
    $task = $tasks->extract();
    echo $task['day'], ': ', $task['title'], "\n";
}
Ожидаемый результат
15: Счёт
18: Отчёт

class объявляет новый класс, extends наследует механизм SplHeap. protected compare вызывается самой кучей при insert/extract. При сравнении записи day=15 с day=18 параметры $first/$second получают эти записи; 18 <=> 15 возвращает положительное число, значит первая запись поднимается выше. return передаёт знак встроенному алгоритму, а не печатает запись. Позже extract возвращает всю запись в $task. Для равных сроков порядок здесь не обещан.

Скачать самостоятельный пример с результатом и README

Отказ сравнения: снять блокировку и заново построить рабочую структуруСамостоятельный пример
<?php
declare(strict_types=1);

class GuardedHeap extends SplMaxHeap {
    protected function compare(mixed $first, mixed $second): int {
        if (!is_int($first) || !is_int($second)) {
            throw new InvalidArgumentException('Нужны целые приоритеты');
        }
        return $first <=> $second;
    }
}
$broken = new GuardedHeap();
$broken->insert(20);
try { $broken->insert('bad'); }
catch (InvalidArgumentException $error) { echo "Некорректная запись остановила сравнение\n"; }
if ($broken->isCorrupted()) {
    echo "Очередность больше не доверенная\n";
    $broken->recoverFromCorruption();
    echo "Блокировка снята; перестраиваем из проверенного источника\n";
}
$clean = new SplMaxHeap();
$clean->insert(20);
$clean->insert(10);
while (!$clean->isEmpty()) { echo 'Восстановлено: ', $clean->extract(), "\n"; }
Ожидаемый результат
Некорректная запись остановила сравнение
Очередность больше не доверенная
Блокировка снята; перестраиваем из проверенного источника
Восстановлено: 20
Восстановлено: 10

Первая вставка не требует сравнения, вторая приносит неподходящий тип. Исключение из compare оставляет контейнер в состоянии corrupted. isCorrupted выбирает восстановление; recoverFromCorruption лишь очищает флаг блокировки и возвращает true, не пересортировывает узлы. Поэтому рабочий $clean создан заново из отдельного проверенного источника; повреждённый $broken больше не используется. Проверять вход лучше до insert, а не внутри сравнения.

Скачать самостоятельный пример с результатом и README

Продолжение: SplHeap::insert, SplHeap::recoverFromCorruption.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplMaxHeap::compareОпределить, какая запись важнее

PHP 5.3+; примеры рассчитаны на PHP 8.2+ · SPL

protected function SplMaxHeap::compare(mixed $value1, mixed $value2): int

Защищённый метод вызывается самой кучей; напрямую $heap->compare() извне недоступен. Для своей записи определите protected compare в наследнике. Готовые Min/Max уже задают правило для обычных значений PHP. Параметры получают сравниваемые значения, return передаёт только знак обратно алгоритму. Он не является возвращаемым заданием: задание позднее отдаёт extract().

ПараметрЧто означает в задаче
value1Первый сравниваемый приоритет или узел.
value2Второй сравниваемый приоритет или узел.
Часть контрактаЧто важно
Сигнатураprotected function SplMaxHeap::compare(mixed $value1, mixed $value2): int
Результатint: Положительное число, когда первый аргумент больше второго; 0 при равенстве, отрицательное иначе.
Ошибки и особые значенияИсключение пользовательского compare может заблокировать кучу и нарушить порядок. Повторная вставка после отказа не является безопасным автоматическим повтором.
ВерсииPHP 5.3+; примеры рассчитаны на PHP 8.2+
Выбрать самый крупный остатокСамостоятельный пример
<?php
declare(strict_types=1);

$stock = new SplMaxHeap();
$stock->insert(12);
$stock->insert(40);
$stock->insert(25);
$amount = $stock->extract();
echo 'Первый объём: ', $amount, "\n";
echo 'Следующий объём: ', $stock->top(), "\n";
Ожидаемый результат
Первый объём: 40
Следующий объём: 25

SplMaxHeap выбирает наибольшее значение. extract возвращает 40, следующий top — 25. Мы храним только количества: если нужен ещё и артикул, используйте запись и собственное сравнение либо SplPriorityQueue с количеством как приоритетом.

Скачать самостоятельный пример с результатом и README

Выбирать запись по срокуСамостоятельный пример
<?php
declare(strict_types=1);

class DeadlineHeap extends SplHeap {
    protected function compare(mixed $first, mixed $second): int {
        return $second['day'] <=> $first['day'];
    }
}
$tasks = new DeadlineHeap();
$tasks->insert(['title' => 'Отчёт', 'day' => 18]);
$tasks->insert(['title' => 'Счёт', 'day' => 15]);
while (!$tasks->isEmpty()) {
    $task = $tasks->extract();
    echo $task['day'], ': ', $task['title'], "\n";
}
Ожидаемый результат
15: Счёт
18: Отчёт

class объявляет новый класс, extends наследует механизм SplHeap. protected compare вызывается самой кучей при insert/extract. При сравнении записи day=15 с day=18 параметры $first/$second получают эти записи; 18 <=> 15 возвращает положительное число, значит первая запись поднимается выше. return передаёт знак встроенному алгоритму, а не печатает запись. Позже extract возвращает всю запись в $task. Для равных сроков порядок здесь не обещан.

Скачать самостоятельный пример с результатом и README

Продолжение: SplHeap::insert, SplHeap::recoverFromCorruption.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplMinHeap::compareОпределить, какая запись важнее

PHP 5.3+; примеры рассчитаны на PHP 8.2+ · SPL

protected function SplMinHeap::compare(mixed $value1, mixed $value2): int

Защищённый метод вызывается самой кучей; напрямую $heap->compare() извне недоступен. Для своей записи определите protected compare в наследнике. Готовые Min/Max уже задают правило для обычных значений PHP. Параметры получают сравниваемые значения, return передаёт только знак обратно алгоритму. Он не является возвращаемым заданием: задание позднее отдаёт extract().

ПараметрЧто означает в задаче
value1Первый сравниваемый приоритет или узел.
value2Второй сравниваемый приоритет или узел.
Часть контрактаЧто важно
Сигнатураprotected function SplMinHeap::compare(mixed $value1, mixed $value2): int
Результатint: Положительное число, когда первый аргумент меньше второго; 0 при равенстве, отрицательное иначе.
Ошибки и особые значенияИсключение пользовательского compare может заблокировать кучу и нарушить порядок. Повторная вставка после отказа не является безопасным автоматическим повтором.
ВерсииPHP 5.3+; примеры рассчитаны на PHP 8.2+
Взять ближайшую минуту запускаСамостоятельный пример
<?php
declare(strict_types=1);

$times = new SplMinHeap();
$times->insert(30);
$times->insert(10);
$times->insert(20);
echo 'Ближайшая минута: ', $times->top(), "\n";
$minute = $times->extract();
echo 'Запланировано на минуту: ', $minute, "\n";
echo 'Следующая минута: ', $times->top(), "\n";
Ожидаемый результат
Ближайшая минута: 10
Запланировано на минуту: 10
Следующая минута: 20

insert передал три целых числа в кучу. SplMinHeap держит на вершине наименьшее — 10. top читает его без удаления. extract удаляет вершину и возвращает 10 в $minute; затем наверху 20. Числа — условные минуты от начала расписания, не текущие часы и не автоматический таймер.

Скачать самостоятельный пример с результатом и README

Выбирать запись по срокуСамостоятельный пример
<?php
declare(strict_types=1);

class DeadlineHeap extends SplHeap {
    protected function compare(mixed $first, mixed $second): int {
        return $second['day'] <=> $first['day'];
    }
}
$tasks = new DeadlineHeap();
$tasks->insert(['title' => 'Отчёт', 'day' => 18]);
$tasks->insert(['title' => 'Счёт', 'day' => 15]);
while (!$tasks->isEmpty()) {
    $task = $tasks->extract();
    echo $task['day'], ': ', $task['title'], "\n";
}
Ожидаемый результат
15: Счёт
18: Отчёт

class объявляет новый класс, extends наследует механизм SplHeap. protected compare вызывается самой кучей при insert/extract. При сравнении записи day=15 с day=18 параметры $first/$second получают эти записи; 18 <=> 15 возвращает положительное число, значит первая запись поднимается выше. return передаёт знак встроенному алгоритму, а не печатает запись. Позже extract возвращает всю запись в $task. Для равных сроков порядок здесь не обещан.

Скачать самостоятельный пример с результатом и README

Продолжение: SplHeap::insert, SplHeap::recoverFromCorruption.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplPriorityQueue::compareОпределить, какая запись важнее

PHP 5.3+; примеры рассчитаны на PHP 8.2+ · SPL

public function SplPriorityQueue::compare(mixed $priority1, mixed $priority2): int

Публичный метод сравнивает два приоритета. Его можно вызвать напрямую для объяснения правила; внутри insert/extract его вызывает алгоритм. Параметры получают сравниваемые значения, return передаёт только знак обратно алгоритму. Он не является возвращаемым заданием: задание позднее отдаёт extract().

ПараметрЧто означает в задаче
priority1Первый сравниваемый приоритет или узел.
priority2Второй сравниваемый приоритет или узел.
Часть контрактаЧто важно
Сигнатураpublic function SplPriorityQueue::compare(mixed $priority1, mixed $priority2): int
Результатint: Положительное число, когда первый приоритет выше второго; 0 при равенстве, отрицательное иначе.
Ошибки и особые значенияИсключение пользовательского compare может заблокировать кучу и нарушить порядок. Повторная вставка после отказа не является безопасным автоматическим повтором.
ВерсииPHP 5.3+; примеры рассчитаны на PHP 8.2+
Понять знак сравнения перед постановкойСамостоятельный пример
<?php
declare(strict_types=1);

$jobs = new SplPriorityQueue();
$relation = $jobs->compare(50, 10);
if ($relation > 0) { echo "Приоритет 50 обслуживается раньше 10\n"; }
$jobs->insert('Пароль', 50);
$jobs->insert('Отчёт', 10);
echo 'Выбрано: ', $jobs->extract(), "\n";
Ожидаемый результат
Приоритет 50 обслуживается раньше 10
Выбрано: Пароль

Публичный compare(50,10) возвращает положительный int. Он не вставляет элемент и не меняет очередь. Проверка знака объясняет правило; затем реальная вставка и extract показывают последствие. Сравнение одинаковых приоритетов вернёт 0, но не добавит гарантию FIFO.

Скачать самостоятельный пример с результатом и README

Сохранить FIFO внутри одинаковой срочностиСамостоятельный пример
<?php
declare(strict_types=1);

class StableJobs extends SplPriorityQueue {
    public function compare(mixed $first, mixed $second): int {
        $urgency = $first['level'] <=> $second['level'];
        if ($urgency !== 0) { return $urgency; }
        return $second['sequence'] <=> $first['sequence'];
    }
}
$jobs = new StableJobs();
$jobs->insert('Отчёт A', ['level' => 10, 'sequence' => 1]);
$jobs->insert('Отчёт B', ['level' => 10, 'sequence' => 2]);
$jobs->insert('Пароль', ['level' => 50, 'sequence' => 3]);
while (!$jobs->isEmpty()) { echo $jobs->extract(), "\n"; }
Ожидаемый результат
Пароль
Отчёт A
Отчёт B

Второй аргумент insert теперь массив приоритета из двух полей. Встроенная куча вызывает compare с двумя такими массивами, не со строками задания. Сначала return отдаёт знак сравнения level. При одинаковом level меньший sequence получает больший приоритет через обратное сравнение. Возврат compare используется только алгоритмом; extract позже возвращает строку. Счётчик sequence должен быть уникальным и возрастающим в пределах этого планировщика.

Скачать самостоятельный пример с результатом и README

Продолжение: SplPriorityQueue::insert, SplHeap::recoverFromCorruption.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplPriorityQueue::getExtractFlagsПрочитать формат выдачи

getExtractFlags — PHP 7+; setExtractFlags — PHP 5.3+; типизированные константы с PHP 8.4 · SPL

public function SplPriorityQueue::getExtractFlags(): int

Флаг меняет форму результата current(), top() и extract(), не порядок. EXTR_DATA=1 — данные (по умолчанию); EXTR_PRIORITY=2 — приоритет; EXTR_BOTH=3 — массив с ключами data и priority. Сохраните старый флаг, если временно меняете представление для отчёта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplPriorityQueue::getExtractFlags(): int
Результатint: текущие флаги у get; установленный набор у set.
Ошибки и особые значенияНабор без DATA и PRIORITY, например 0, вызывает RuntimeException у setExtractFlags. Неверный тип — TypeError.
ВерсииgetExtractFlags — PHP 7+; setExtractFlags — PHP 5.3+; типизированные константы с PHP 8.4
Получить вместе задание и его приоритетСамостоятельный пример
<?php
declare(strict_types=1);

$jobs = new SplPriorityQueue();
$jobs->insert('Сброс пароля', 50);
$saved = $jobs->getExtractFlags();
$jobs->setExtractFlags(SplPriorityQueue::EXTR_PRIORITY);
echo 'Приоритет: ', $jobs->top(), "\n";
$jobs->setExtractFlags(SplPriorityQueue::EXTR_BOTH);
$entry = $jobs->current();
echo $entry['data'], ': ', $entry['priority'], "\n";
$jobs->setExtractFlags($saved);
echo 'К исполнению: ', $jobs->extract(), "\n";
Ожидаемый результат
Приоритет: 50
Сброс пароля: 50
К исполнению: Сброс пароля

EXTR_PRIORITY меняет форму чтения на число; EXTR_BOTH возвращает массив с ключами data и priority. Это не меняет очередность. getExtractFlags сохранил прежнюю настройку EXTR_DATA, setExtractFlags восстановил её, поэтому extract снова вернул строку задания.

Скачать самостоятельный пример с результатом и README

Пустая очередь и неверная форма выдачиСамостоятельный пример
<?php
declare(strict_types=1);

$jobs = new SplPriorityQueue();
try { $jobs->setExtractFlags(0); }
catch (RuntimeException $error) { echo "Нужно выбрать данные, приоритет или оба\n"; }
if ($jobs->isEmpty()) { echo "Задания не поступили\n"; }
try { $jobs->extract(); }
catch (RuntimeException $error) { echo "Извлекать нечего\n"; }
Ожидаемый результат
Нужно выбрать данные, приоритет или оба
Задания не поступили
Извлекать нечего

Нулевой flags не выбирает ни одного компонента и вызывает RuntimeException. Другая независимая ошибка — extract пустой очереди. В обычном цикле её избегают проверкой isEmpty, а исключения оставляют для нарушения ожидаемого состояния.

Скачать самостоятельный пример с результатом и README

Продолжение: SplPriorityQueue::current, SplPriorityQueue::extract.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplPriorityQueue::setExtractFlagsВыбрать данные, приоритет или оба

getExtractFlags — PHP 7+; setExtractFlags — PHP 5.3+; типизированные константы с PHP 8.4 · SPL

public function SplPriorityQueue::setExtractFlags(int $flags): int

Флаг меняет форму результата current(), top() и extract(), не порядок. EXTR_DATA=1 — данные (по умолчанию); EXTR_PRIORITY=2 — приоритет; EXTR_BOTH=3 — массив с ключами data и priority. Сохраните старый флаг, если временно меняете представление для отчёта.

ПараметрЧто означает в задаче
flagsОдна из трёх именованных констант; DATA | PRIORITY равно BOTH.
Часть контрактаЧто важно
Сигнатураpublic function SplPriorityQueue::setExtractFlags(int $flags): int
Результатint: текущие флаги у get; установленный набор у set.
Ошибки и особые значенияНабор без DATA и PRIORITY, например 0, вызывает RuntimeException у setExtractFlags. Неверный тип — TypeError.
ВерсииgetExtractFlags — PHP 7+; setExtractFlags — PHP 5.3+; типизированные константы с PHP 8.4
Получить вместе задание и его приоритетСамостоятельный пример
<?php
declare(strict_types=1);

$jobs = new SplPriorityQueue();
$jobs->insert('Сброс пароля', 50);
$saved = $jobs->getExtractFlags();
$jobs->setExtractFlags(SplPriorityQueue::EXTR_PRIORITY);
echo 'Приоритет: ', $jobs->top(), "\n";
$jobs->setExtractFlags(SplPriorityQueue::EXTR_BOTH);
$entry = $jobs->current();
echo $entry['data'], ': ', $entry['priority'], "\n";
$jobs->setExtractFlags($saved);
echo 'К исполнению: ', $jobs->extract(), "\n";
Ожидаемый результат
Приоритет: 50
Сброс пароля: 50
К исполнению: Сброс пароля

EXTR_PRIORITY меняет форму чтения на число; EXTR_BOTH возвращает массив с ключами data и priority. Это не меняет очередность. getExtractFlags сохранил прежнюю настройку EXTR_DATA, setExtractFlags восстановил её, поэтому extract снова вернул строку задания.

Скачать самостоятельный пример с результатом и README

Пустая очередь и неверная форма выдачиСамостоятельный пример
<?php
declare(strict_types=1);

$jobs = new SplPriorityQueue();
try { $jobs->setExtractFlags(0); }
catch (RuntimeException $error) { echo "Нужно выбрать данные, приоритет или оба\n"; }
if ($jobs->isEmpty()) { echo "Задания не поступили\n"; }
try { $jobs->extract(); }
catch (RuntimeException $error) { echo "Извлекать нечего\n"; }
Ожидаемый результат
Нужно выбрать данные, приоритет или оба
Задания не поступили
Извлекать нечего

Нулевой flags не выбирает ни одного компонента и вызывает RuntimeException. Другая независимая ошибка — extract пустой очереди. В обычном цикле её избегают проверкой isEmpty, а исключения оставляют для нарушения ожидаемого состояния.

Скачать самостоятельный пример с результатом и README

Продолжение: SplPriorityQueue::current, SplPriorityQueue::extract.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFixedArray::__constructСоздать заданное число пустых мест

PHP 5.3+; PHP 8: отрицательный размер → ValueError; PHP 8.1: неверный тип индекса → TypeError; PHP 8.4: выход за границу → OutOfBoundsException (ранее RuntimeException) · SPL

public function SplFixedArray::__construct(int $size = 0)

Размер инициализирует каждое место значением null. По умолчанию size=0 — пустой контейнер, а не автоматически растущий массив.

ПараметрЧто означает в задаче
sizeint от 0 до PHP_INT_MAX, по умолчанию 0; практически ограничен доступной памятью.
Часть контрактаЧто важно
Сигнатураpublic function SplFixedArray::__construct(int $size = 0)
РезультатКонструктор не возвращает значение; выражение new возвращает созданный объект.
Ошибки и особые значенияОтрицательный размер вызывает ValueError с PHP 8; раньше InvalidArgumentException. Нельзя считать PHP_INT_MAX реально доступной ёмкостью.
ВерсииPHP 5.3+; PHP 8: отрицательный размер → ValueError; PHP 8.1: неверный тип индекса → TypeError; PHP 8.4: выход за границу → OutOfBoundsException (ранее RuntimeException)
Зарезервировать три места для показанийСамостоятельный пример
<?php
declare(strict_types=1);

$readings = new SplFixedArray(3);
$readings[0] = 18;
$readings[2] = 21;
echo 'Первое показание: ', $readings[0], "\n";
echo 'Мест: ', $readings->getSize(), "\n";
foreach ($readings as $index => $value) {
    echo $index, ': ', $value === null ? 'нет замера' : $value, "\n";
}
Ожидаемый результат
Первое показание: 18
Мест: 3
0: 18
1: нет замера
2: 21

Число 3 в конструкторе задаёт количество мест: индексы 0, 1, 2. Каждое сначала содержит null. Квадратные скобки выбирают место; запись меняет его значение. count/getSize считают места, включая незаполненные. foreach проходит все три; строгая проверка === null выбирает подпись отсутствующего измерения, сохраняя настоящий ноль.

Скачать самостоятельный пример с результатом и README

Отличить неверный номер от неверного типаСамостоятельный пример
<?php
declare(strict_types=1);

$readings = new SplFixedArray(2);
try { $readings[2] = 20; }
catch (RuntimeException $error) { echo "Для третьего места сначала увеличьте размер\n"; }
try { $readings['evening'] = 20; }
catch (TypeError $error) { echo "Индекс должен обозначать целую позицию\n"; }
try { $readings->setSize(-1); }
catch (ValueError $error) { echo "Размер не может быть отрицательным\n"; }
$readings->setSize(3);
$readings[2] = 20;
echo 'Третье показание: ', $readings[2], "\n";
Ожидаемый результат
Для третьего места сначала увеличьте размер
Индекс должен обозначать целую позицию
Размер не может быть отрицательным
Третье показание: 20

При размере 2 допустимы только 0 и 1; запись [2] не расширяет контейнер. С PHP 8.4 ошибка границы — OutOfBoundsException, наследник RuntimeException: такой catch работает и с прежними версиями. Нечисловой строковый индекс с PHP 8.1 даёт TypeError; отрицательный размер с PHP 8 даёт ValueError.

Скачать самостоятельный пример с результатом и README

Продолжение: SplFixedArray::getSize, SplFixedArray::getIterator.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFixedArray::countПолучить число выделенных мест

PHP 5.3+; PHP 8: отрицательный размер → ValueError; PHP 8.1: неверный тип индекса → TypeError; PHP 8.4: выход за границу → OutOfBoundsException (ранее RuntimeException) · SPL

public function SplFixedArray::count(): int

count() равен getSize(), даже если все значения null. Удаление значения offsetUnset не уменьшает размер.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFixedArray::count(): int
Результатint: текущий размер; это не число полученных измерений.
Ошибки и особые значенияПараметров нет; для количества непустых замеров считайте их отдельно по правилу предметной области.
ВерсииPHP 5.3+; PHP 8: отрицательный размер → ValueError; PHP 8.1: неверный тип индекса → TypeError; PHP 8.4: выход за границу → OutOfBoundsException (ранее RuntimeException)
Зарезервировать три места для показанийСамостоятельный пример
<?php
declare(strict_types=1);

$readings = new SplFixedArray(3);
$readings[0] = 18;
$readings[2] = 21;
echo 'Первое показание: ', $readings[0], "\n";
echo 'Мест: ', $readings->getSize(), "\n";
foreach ($readings as $index => $value) {
    echo $index, ': ', $value === null ? 'нет замера' : $value, "\n";
}
Ожидаемый результат
Первое показание: 18
Мест: 3
0: 18
1: нет замера
2: 21

Число 3 в конструкторе задаёт количество мест: индексы 0, 1, 2. Каждое сначала содержит null. Квадратные скобки выбирают место; запись меняет его значение. count/getSize считают места, включая незаполненные. foreach проходит все три; строгая проверка === null выбирает подпись отсутствующего измерения, сохраняя настоящий ноль.

Скачать самостоятельный пример с результатом и README

Записать, очистить и проверить ячейкуСамостоятельный пример
<?php
declare(strict_types=1);

$readings = new SplFixedArray(3);
$readings->offsetSet(1, 0);
if ($readings->offsetExists(1)) {
    echo 'Есть показание: ', $readings->offsetGet(1), "\n";
}
$readings->offsetUnset(1);
if (!$readings->offsetExists(1)) { echo "Показание очищено\n"; }
echo 'Мест после очистки: ', $readings->count(), "\n";
echo 'В ячейке: ', $readings[1] === null ? 'null' : 'другое', "\n";
Ожидаемый результат
Есть показание: 0
Показание очищено
Мест после очистки: 3
В ячейке: null

offsetSet/offsetGet соответствуют записи/чтению квадратными скобками. offsetUnset, как unset($readings[1]), очищает значение до null, но не сжимает контейнер. offsetExists имеет isset-смысл: для null false, для 0 true. Проверку допустимого номера выполняют отдельно: 0 <= индекс < getSize().

Скачать самостоятельный пример с результатом и README

Продолжение: SplFixedArray::getSize, SplFixedArray::getIterator.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFixedArray::getSizeУзнать допустимую границу индекса

PHP 5.3+; PHP 8: отрицательный размер → ValueError; PHP 8.1: неверный тип индекса → TypeError; PHP 8.4: выход за границу → OutOfBoundsException (ранее RuntimeException) · SPL

public function SplFixedArray::getSize(): int

getSize() даёт число мест; условие допустимости: index >= 0 и index < getSize().

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFixedArray::getSize(): int
Результатint: текущий размер, то же, что count().
Ошибки и особые значенияРазмер 0 не допускает ни одной позиции.
ВерсииPHP 5.3+; PHP 8: отрицательный размер → ValueError; PHP 8.1: неверный тип индекса → TypeError; PHP 8.4: выход за границу → OutOfBoundsException (ранее RuntimeException)
Зарезервировать три места для показанийСамостоятельный пример
<?php
declare(strict_types=1);

$readings = new SplFixedArray(3);
$readings[0] = 18;
$readings[2] = 21;
echo 'Первое показание: ', $readings[0], "\n";
echo 'Мест: ', $readings->getSize(), "\n";
foreach ($readings as $index => $value) {
    echo $index, ': ', $value === null ? 'нет замера' : $value, "\n";
}
Ожидаемый результат
Первое показание: 18
Мест: 3
0: 18
1: нет замера
2: 21

Число 3 в конструкторе задаёт количество мест: индексы 0, 1, 2. Каждое сначала содержит null. Квадратные скобки выбирают место; запись меняет его значение. count/getSize считают места, включая незаполненные. foreach проходит все три; строгая проверка === null выбирает подпись отсутствующего измерения, сохраняя настоящий ноль.

Скачать самостоятельный пример с результатом и README

Увеличить сетку, затем явно отбросить хвостСамостоятельный пример
<?php
declare(strict_types=1);

$readings = SplFixedArray::fromArray([18, 19]);
$readings->setSize(4);
$readings[3] = 22;
echo 'До сокращения: ', json_encode($readings), "\n";
$readings->setSize(2);
$readings->setSize(4);
echo 'После расширения: ', json_encode($readings), "\n";
Ожидаемый результат
До сокращения: [18,19,null,22]
После расширения: [18,19,null,null]

fromArray создаёт новый контейнер из обычного массива. setSize(4) добавляет два null. Сокращение до 2 уничтожает значения за новой границей; повторное увеличение не возвращает 22. json_encode здесь только делает всю уже объяснённую структуру видимой: внутри скобок значения идут по индексам.

Скачать самостоятельный пример с результатом и README

Продолжение: SplFixedArray::setSize, SplFixedArray::getIterator.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFixedArray::setSizeЯвно увеличить или сократить контейнер

PHP 5.3+; PHP 8: отрицательный размер → ValueError; PHP 8.1: неверный тип индекса → TypeError; PHP 8.4: выход за границу → OutOfBoundsException (ранее RuntimeException); tentative return true с PHP 8.4 · SPL

public function SplFixedArray::setSize(int $size): true

Увеличение добавляет null, сокращение уничтожает хвост; прежние значения внутри новой границы сохраняются.

ПараметрЧто означает в задаче
sizeНовый неотрицательный размер. 0 освобождает все значения.
Часть контрактаЧто важно
Сигнатураpublic function SplFixedArray::setSize(int $size): true
Результатtrue; это не прежний размер и не копия контейнера.
Ошибки и особые значенияОтрицательный size — ValueError. Расширение может исчерпать память.
ВерсииPHP 5.3+; PHP 8: отрицательный размер → ValueError; PHP 8.1: неверный тип индекса → TypeError; PHP 8.4: выход за границу → OutOfBoundsException (ранее RuntimeException); tentative return true с PHP 8.4
Увеличить сетку, затем явно отбросить хвостСамостоятельный пример
<?php
declare(strict_types=1);

$readings = SplFixedArray::fromArray([18, 19]);
$readings->setSize(4);
$readings[3] = 22;
echo 'До сокращения: ', json_encode($readings), "\n";
$readings->setSize(2);
$readings->setSize(4);
echo 'После расширения: ', json_encode($readings), "\n";
Ожидаемый результат
До сокращения: [18,19,null,22]
После расширения: [18,19,null,null]

fromArray создаёт новый контейнер из обычного массива. setSize(4) добавляет два null. Сокращение до 2 уничтожает значения за новой границей; повторное увеличение не возвращает 22. json_encode здесь только делает всю уже объяснённую структуру видимой: внутри скобок значения идут по индексам.

Скачать самостоятельный пример с результатом и README

Отличить неверный номер от неверного типаСамостоятельный пример
<?php
declare(strict_types=1);

$readings = new SplFixedArray(2);
try { $readings[2] = 20; }
catch (RuntimeException $error) { echo "Для третьего места сначала увеличьте размер\n"; }
try { $readings['evening'] = 20; }
catch (TypeError $error) { echo "Индекс должен обозначать целую позицию\n"; }
try { $readings->setSize(-1); }
catch (ValueError $error) { echo "Размер не может быть отрицательным\n"; }
$readings->setSize(3);
$readings[2] = 20;
echo 'Третье показание: ', $readings[2], "\n";
Ожидаемый результат
Для третьего места сначала увеличьте размер
Индекс должен обозначать целую позицию
Размер не может быть отрицательным
Третье показание: 20

При размере 2 допустимы только 0 и 1; запись [2] не расширяет контейнер. С PHP 8.4 ошибка границы — OutOfBoundsException, наследник RuntimeException: такой catch работает и с прежними версиями. Нечисловой строковый индекс с PHP 8.1 даёт TypeError; отрицательный размер с PHP 8 даёт ValueError.

Скачать самостоятельный пример с результатом и README

Продолжение: SplFixedArray::getSize, SplFixedArray::getIterator.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFixedArray::offsetExistsПроверить наличие ненулевого значения в месте

PHP 5.3+; PHP 8: отрицательный размер → ValueError; PHP 8.1: неверный тип индекса → TypeError; PHP 8.4: выход за границу → OutOfBoundsException (ранее RuntimeException) · SPL

public function SplFixedArray::offsetExists($index): bool

offsetExists(index) имеет поведение isset: false для отсутствующей позиции и для null, true для существующих 0/false/пустой строки. Для самого диапазона сравнивайте индекс с getSize.

ПараметрЧто означает в задаче
indexНомер проверяемой ячейки.
Часть контрактаЧто важно
Сигнатураpublic function SplFixedArray::offsetExists($index): bool
Результатbool, который выбирает ветвь обработки показания.
Ошибки и особые значенияПроверка за границей возвращает false; неподходящий тип индекса может вызвать TypeError.
ВерсииPHP 5.3+; PHP 8: отрицательный размер → ValueError; PHP 8.1: неверный тип индекса → TypeError; PHP 8.4: выход за границу → OutOfBoundsException (ранее RuntimeException)
Записать, очистить и проверить ячейкуСамостоятельный пример
<?php
declare(strict_types=1);

$readings = new SplFixedArray(3);
$readings->offsetSet(1, 0);
if ($readings->offsetExists(1)) {
    echo 'Есть показание: ', $readings->offsetGet(1), "\n";
}
$readings->offsetUnset(1);
if (!$readings->offsetExists(1)) { echo "Показание очищено\n"; }
echo 'Мест после очистки: ', $readings->count(), "\n";
echo 'В ячейке: ', $readings[1] === null ? 'null' : 'другое', "\n";
Ожидаемый результат
Есть показание: 0
Показание очищено
Мест после очистки: 3
В ячейке: null

offsetSet/offsetGet соответствуют записи/чтению квадратными скобками. offsetUnset, как unset($readings[1]), очищает значение до null, но не сжимает контейнер. offsetExists имеет isset-смысл: для null false, для 0 true. Проверку допустимого номера выполняют отдельно: 0 <= индекс < getSize().

Скачать самостоятельный пример с результатом и README

Зарезервировать три места для показанийСамостоятельный пример
<?php
declare(strict_types=1);

$readings = new SplFixedArray(3);
$readings[0] = 18;
$readings[2] = 21;
echo 'Первое показание: ', $readings[0], "\n";
echo 'Мест: ', $readings->getSize(), "\n";
foreach ($readings as $index => $value) {
    echo $index, ': ', $value === null ? 'нет замера' : $value, "\n";
}
Ожидаемый результат
Первое показание: 18
Мест: 3
0: 18
1: нет замера
2: 21

Число 3 в конструкторе задаёт количество мест: индексы 0, 1, 2. Каждое сначала содержит null. Квадратные скобки выбирают место; запись меняет его значение. count/getSize считают места, включая незаполненные. foreach проходит все три; строгая проверка === null выбирает подпись отсутствующего измерения, сохраняя настоящий ноль.

Скачать самостоятельный пример с результатом и README

Продолжение: SplFixedArray::getSize, SplFixedArray::getIterator.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFixedArray::offsetGetПрочитать одно значение

PHP 5.3+; PHP 8: отрицательный размер → ValueError; PHP 8.1: неверный тип индекса → TypeError; PHP 8.4: выход за границу → OutOfBoundsException (ранее RuntimeException) · SPL

public function SplFixedArray::offsetGet($index): mixed

offsetGet(index) соответствует $readings[index]. Ячейка существует с момента выделения размера, даже если хранит null.

ПараметрЧто означает в задаче
indexДопустимый номер ячейки.
Часть контрактаЧто важно
Сигнатураpublic function SplFixedArray::offsetGet($index): mixed
Результатmixed: сохранённое значение, включая null.
Ошибки и особые значенияЗа границей — OutOfBoundsException с PHP 8.4 (до этого RuntimeException); неверный тип индекса — TypeError с PHP 8.1. Числовая строка вроде "2" может обозначать позицию; не путайте это с произвольным именем.
ВерсииPHP 5.3+; PHP 8: отрицательный размер → ValueError; PHP 8.1: неверный тип индекса → TypeError; PHP 8.4: выход за границу → OutOfBoundsException (ранее RuntimeException)
Записать, очистить и проверить ячейкуСамостоятельный пример
<?php
declare(strict_types=1);

$readings = new SplFixedArray(3);
$readings->offsetSet(1, 0);
if ($readings->offsetExists(1)) {
    echo 'Есть показание: ', $readings->offsetGet(1), "\n";
}
$readings->offsetUnset(1);
if (!$readings->offsetExists(1)) { echo "Показание очищено\n"; }
echo 'Мест после очистки: ', $readings->count(), "\n";
echo 'В ячейке: ', $readings[1] === null ? 'null' : 'другое', "\n";
Ожидаемый результат
Есть показание: 0
Показание очищено
Мест после очистки: 3
В ячейке: null

offsetSet/offsetGet соответствуют записи/чтению квадратными скобками. offsetUnset, как unset($readings[1]), очищает значение до null, но не сжимает контейнер. offsetExists имеет isset-смысл: для null false, для 0 true. Проверку допустимого номера выполняют отдельно: 0 <= индекс < getSize().

Скачать самостоятельный пример с результатом и README

Отличить неверный номер от неверного типаСамостоятельный пример
<?php
declare(strict_types=1);

$readings = new SplFixedArray(2);
try { $readings[2] = 20; }
catch (RuntimeException $error) { echo "Для третьего места сначала увеличьте размер\n"; }
try { $readings['evening'] = 20; }
catch (TypeError $error) { echo "Индекс должен обозначать целую позицию\n"; }
try { $readings->setSize(-1); }
catch (ValueError $error) { echo "Размер не может быть отрицательным\n"; }
$readings->setSize(3);
$readings[2] = 20;
echo 'Третье показание: ', $readings[2], "\n";
Ожидаемый результат
Для третьего места сначала увеличьте размер
Индекс должен обозначать целую позицию
Размер не может быть отрицательным
Третье показание: 20

При размере 2 допустимы только 0 и 1; запись [2] не расширяет контейнер. С PHP 8.4 ошибка границы — OutOfBoundsException, наследник RuntimeException: такой catch работает и с прежними версиями. Нечисловой строковый индекс с PHP 8.1 даёт TypeError; отрицательный размер с PHP 8 даёт ValueError.

Скачать самостоятельный пример с результатом и README

Продолжение: SplFixedArray::getSize, SplFixedArray::getIterator.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFixedArray::offsetSetЗаписать значение в существующее место

PHP 5.3+; PHP 8: отрицательный размер → ValueError; PHP 8.1: неверный тип индекса → TypeError; PHP 8.4: выход за границу → OutOfBoundsException (ранее RuntimeException) · SPL

public function SplFixedArray::offsetSet($index, mixed $value): void

offsetSet(index,value) заменяет содержимое одной ячейки. Он не увеличивает размер; запись $readings[index] = value использует тот же смысл.

ПараметрЧто означает в задаче
indexДопустимый номер ячейки; null не означает append.
valueНовое значение любого типа.
Часть контрактаЧто важно
Сигнатураpublic function SplFixedArray::offsetSet($index, mixed $value): void
Результатvoid; используйте последующее чтение для результата изменения.
Ошибки и особые значенияЗа границей — OutOfBoundsException с PHP 8.4 (до этого RuntimeException); неверный тип индекса — TypeError с PHP 8.1. Числовая строка вроде "2" может обозначать позицию; не путайте это с произвольным именем.
ВерсииPHP 5.3+; PHP 8: отрицательный размер → ValueError; PHP 8.1: неверный тип индекса → TypeError; PHP 8.4: выход за границу → OutOfBoundsException (ранее RuntimeException)
Записать, очистить и проверить ячейкуСамостоятельный пример
<?php
declare(strict_types=1);

$readings = new SplFixedArray(3);
$readings->offsetSet(1, 0);
if ($readings->offsetExists(1)) {
    echo 'Есть показание: ', $readings->offsetGet(1), "\n";
}
$readings->offsetUnset(1);
if (!$readings->offsetExists(1)) { echo "Показание очищено\n"; }
echo 'Мест после очистки: ', $readings->count(), "\n";
echo 'В ячейке: ', $readings[1] === null ? 'null' : 'другое', "\n";
Ожидаемый результат
Есть показание: 0
Показание очищено
Мест после очистки: 3
В ячейке: null

offsetSet/offsetGet соответствуют записи/чтению квадратными скобками. offsetUnset, как unset($readings[1]), очищает значение до null, но не сжимает контейнер. offsetExists имеет isset-смысл: для null false, для 0 true. Проверку допустимого номера выполняют отдельно: 0 <= индекс < getSize().

Скачать самостоятельный пример с результатом и README

Отличить неверный номер от неверного типаСамостоятельный пример
<?php
declare(strict_types=1);

$readings = new SplFixedArray(2);
try { $readings[2] = 20; }
catch (RuntimeException $error) { echo "Для третьего места сначала увеличьте размер\n"; }
try { $readings['evening'] = 20; }
catch (TypeError $error) { echo "Индекс должен обозначать целую позицию\n"; }
try { $readings->setSize(-1); }
catch (ValueError $error) { echo "Размер не может быть отрицательным\n"; }
$readings->setSize(3);
$readings[2] = 20;
echo 'Третье показание: ', $readings[2], "\n";
Ожидаемый результат
Для третьего места сначала увеличьте размер
Индекс должен обозначать целую позицию
Размер не может быть отрицательным
Третье показание: 20

При размере 2 допустимы только 0 и 1; запись [2] не расширяет контейнер. С PHP 8.4 ошибка границы — OutOfBoundsException, наследник RuntimeException: такой catch работает и с прежними версиями. Нечисловой строковый индекс с PHP 8.1 даёт TypeError; отрицательный размер с PHP 8 даёт ValueError.

Скачать самостоятельный пример с результатом и README

Продолжение: SplFixedArray::getSize, SplFixedArray::getIterator.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFixedArray::offsetUnsetОчистить значение без сокращения размера

PHP 5.3+; PHP 8: отрицательный размер → ValueError; PHP 8.1: неверный тип индекса → TypeError; PHP 8.4: выход за границу → OutOfBoundsException (ранее RuntimeException) · SPL

public function SplFixedArray::offsetUnset($index): void

offsetUnset(index), как unset($readings[index]), заменяет содержимое null. Номера остальных мест остаются прежними.

ПараметрЧто означает в задаче
indexНомер очищаемого места.
Часть контрактаЧто важно
Сигнатураpublic function SplFixedArray::offsetUnset($index): void
Результатvoid; размер и остальные позиции сохранены.
Ошибки и особые значенияЗа границей — OutOfBoundsException с PHP 8.4 (до этого RuntimeException); неверный тип индекса — TypeError с PHP 8.1. Числовая строка вроде "2" может обозначать позицию; не путайте это с произвольным именем.
ВерсииPHP 5.3+; PHP 8: отрицательный размер → ValueError; PHP 8.1: неверный тип индекса → TypeError; PHP 8.4: выход за границу → OutOfBoundsException (ранее RuntimeException)
Записать, очистить и проверить ячейкуСамостоятельный пример
<?php
declare(strict_types=1);

$readings = new SplFixedArray(3);
$readings->offsetSet(1, 0);
if ($readings->offsetExists(1)) {
    echo 'Есть показание: ', $readings->offsetGet(1), "\n";
}
$readings->offsetUnset(1);
if (!$readings->offsetExists(1)) { echo "Показание очищено\n"; }
echo 'Мест после очистки: ', $readings->count(), "\n";
echo 'В ячейке: ', $readings[1] === null ? 'null' : 'другое', "\n";
Ожидаемый результат
Есть показание: 0
Показание очищено
Мест после очистки: 3
В ячейке: null

offsetSet/offsetGet соответствуют записи/чтению квадратными скобками. offsetUnset, как unset($readings[1]), очищает значение до null, но не сжимает контейнер. offsetExists имеет isset-смысл: для null false, для 0 true. Проверку допустимого номера выполняют отдельно: 0 <= индекс < getSize().

Скачать самостоятельный пример с результатом и README

Увеличить сетку, затем явно отбросить хвостСамостоятельный пример
<?php
declare(strict_types=1);

$readings = SplFixedArray::fromArray([18, 19]);
$readings->setSize(4);
$readings[3] = 22;
echo 'До сокращения: ', json_encode($readings), "\n";
$readings->setSize(2);
$readings->setSize(4);
echo 'После расширения: ', json_encode($readings), "\n";
Ожидаемый результат
До сокращения: [18,19,null,22]
После расширения: [18,19,null,null]

fromArray создаёт новый контейнер из обычного массива. setSize(4) добавляет два null. Сокращение до 2 уничтожает значения за новой границей; повторное увеличение не возвращает 22. json_encode здесь только делает всю уже объяснённую структуру видимой: внутри скобок значения идут по индексам.

Скачать самостоятельный пример с результатом и README

Продолжение: SplFixedArray::getSize, SplFixedArray::getIterator.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFixedArray::fromArrayИмпортировать значения обычного массива

PHP 5.3+; PHP 8: отрицательный размер → ValueError; PHP 8.1: неверный тип индекса → TypeError; PHP 8.4: выход за границу → OutOfBoundsException (ранее RuntimeException) · SPL

public static function SplFixedArray::fromArray(array $array, bool $preserveKeys = true): SplFixedArray

Статический метод создаёт новый SplFixedArray. preserveKeys=true сохраняет неотрицательные числовые ключи и заполняет промежутки null; false перенумеровывает в порядке входного обхода.

ПараметрЧто означает в задаче
arrayИсходный PHP-массив.
preserveKeysbool, по умолчанию true. false намеренно отбрасывает имена/номера.
Часть контрактаЧто важно
Сигнатураpublic static function SplFixedArray::fromArray(array $array, bool $preserveKeys = true): SplFixedArray
РезультатНовый SplFixedArray; исходный массив не заменяется.
Ошибки и особые значенияПри сохранении недопустимых ключей — InvalidArgumentException. Очень большой максимальный ключ требует большого размера.
ВерсииPHP 5.3+; PHP 8: отрицательный размер → ValueError; PHP 8.1: неверный тип индекса → TypeError; PHP 8.4: выход за границу → OutOfBoundsException (ранее RuntimeException)
Сохранить номера измерений или уплотнить значенияСамостоятельный пример
<?php
declare(strict_types=1);

$source = [3 => 22, 1 => 18];
$slots = SplFixedArray::fromArray($source);
$dense = SplFixedArray::fromArray($source, false);
echo 'С номерами: ', json_encode($slots), "\n";
echo 'По порядку входа: ', json_encode($dense), "\n";
Ожидаемый результат
С номерами: [null,18,null,22]
По порядку входа: [22,18]

:: вызывает статический метод класса, без заранее созданного объекта. По умолчанию preserveKeys=true: максимальный индекс 3 требует четырёх мест, пропуски становятся null. false забывает старые номера и располагает значения в исходном порядке обхода: сначала 22, затем 18.

Скачать самостоятельный пример с результатом и README

Преобразовать данные с именованными ключамиСамостоятельный пример
<?php
declare(strict_types=1);

$source = ['morning' => 18, 'evening' => 22];
try { SplFixedArray::fromArray($source); }
catch (InvalidArgumentException $error) { echo "Имена не являются номерами мест\n"; }
$values = SplFixedArray::fromArray($source, false);
echo 'Первый замер: ', $values[0], "\n";
echo 'Второй замер: ', $values[1], "\n";
Ожидаемый результат
Имена не являются номерами мест
Первый замер: 18
Второй замер: 22

Невозможно сохранить именованные ключи как фиксированные целочисленные позиции. false намеренно отбрасывает имена. Если morning/evening имеют смысл для дальнейшей программы, оставьте обычный массив или храните соответствие отдельно, а не теряйте его незаметно.

Скачать самостоятельный пример с результатом и README

Продолжение: SplFixedArray::getSize, SplFixedArray::getIterator.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFixedArray::toArrayВыгрузить обычный массив для функций array_*

PHP 5.3+; PHP 8: отрицательный размер → ValueError; PHP 8.1: неверный тип индекса → TypeError; PHP 8.4: выход за границу → OutOfBoundsException (ранее RuntimeException) · SPL

public function SplFixedArray::toArray(): array

toArray сохраняет порядок и null-места. Возвращает обычный массив, доступный функциям array_sum и другим инструментам массива.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFixedArray::toArray(): array
Результатarray: поверхностная копия значений.
Ошибки и особые значенияОбъекты внутри не клонируются; дополнительная копия требует памяти.
ВерсииPHP 5.3+; PHP 8: отрицательный размер → ValueError; PHP 8.1: неверный тип индекса → TypeError; PHP 8.4: выход за границу → OutOfBoundsException (ранее RuntimeException)
Передать обычный массив в расчётСамостоятельный пример
<?php
declare(strict_types=1);

$readings = SplFixedArray::fromArray([18, 20, 22]);
$values = $readings->toArray();
$values[0] = 10;
echo 'Среднее копии: ', array_sum($values) / count($values), "\n";
echo 'Первое в контейнере: ', $readings[0], "\n";
Ожидаемый результат
Среднее копии: 17.333333333333
Первое в контейнере: 18

toArray возвращает обычный PHP-массив; array_sum теперь принимает его. Изменение скалярного значения в копии не меняет контейнер. Копия поверхностная: вложенные объекты сохраняют общую идентичность. В рабочем отчёте для среднего дополнительно выбирают правило округления и пропуска null.

Скачать самостоятельный пример с результатом и README

Подготовить данные для JSON, не смешивая массив и строкуСамостоятельный пример
<?php
declare(strict_types=1);

$readings = new SplFixedArray(3);
$readings[0] = 18;
$readings[2] = 22;
$value = $readings->jsonSerialize();
echo 'Первое в массиве: ', $value[0], "\n";
$text = json_encode($readings, JSON_THROW_ON_ERROR);
echo 'JSON: ', $text, "\n";
Ожидаемый результат
Первое в массиве: 18
JSON: [18,null,22]

jsonSerialize возвращает массив-представление, не готовую JSON-строку. json_encode сам вызывает этот договор и создаёт строку в $text. JSON_THROW_ON_ERROR выбирает исключение при ошибке кодирования; здесь значения простые и все позиции сохранены, включая null.

Скачать самостоятельный пример с результатом и README

Продолжение: SplFixedArray::getSize, SplFixedArray::getIterator.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFixedArray::getIteratorПолучить отдельный объект для прохода

PHP 8.0+; переход класса от Iterator к IteratorAggregate · SPL

public function SplFixedArray::getIterator(): Iterator

Возвращённый Iterator имеет собственную позицию, но читает тот же контейнер. foreach получает такой итератор автоматически.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFixedArray::getIterator(): Iterator
РезультатIterator, который присваивается переменной и получает rewind/current/key/next/valid.
Ошибки и особые значенияНе считайте итератор снимком и осторожно изменяйте размер во время обхода.
ВерсииPHP 8.0+; переход класса от Iterator к IteratorAggregate
Получить отдельный указатель вместо старых методовСамостоятельный пример
<?php
declare(strict_types=1);

$readings = SplFixedArray::fromArray([18, 22]);
$iterator = $readings->getIterator();
$iterator->rewind();
while ($iterator->valid()) {
    echo 'Замер ', $iterator->key(), ': ', $iterator->current(), "\n";
    $iterator->next();
}
$iterator->rewind();
echo 'Снова первый: ', $iterator->current(), "\n";
Ожидаемый результат
Замер 0: 18
Замер 1: 22
Снова первый: 18

С PHP 8 SplFixedArray реализует IteratorAggregate: контейнер выдаёт отдельный Iterator. rewind/current/key/next/valid вызываются у $iterator, не у $readings. getIterator возвращает объект в переменную; затем цикл читает индекс и значение, продвигается, останавливается. Значения не удаляются.

Скачать самостоятельный пример с результатом и README

Два просмотра с независимыми позициямиСамостоятельный пример
<?php
declare(strict_types=1);

$readings = SplFixedArray::fromArray([18, 22]);
$left = $readings->getIterator();
$right = $readings->getIterator();
$left->rewind();
$right->rewind();
$left->next();
echo 'Левый просмотр: ', $left->current(), "\n";
echo 'Правый просмотр: ', $right->current(), "\n";
$readings[0] = 19;
echo 'Правый после исправления: ', $right->current(), "\n";
Ожидаемый результат
Левый просмотр: 22
Правый просмотр: 18
Правый после исправления: 19

getIterator создаёт отдельные позиции, но оба просмотра обращаются к одному контейнеру. Следовательно, независимый указатель не равен снимку данных: исправление ячейки видно при следующем чтении. Менять размер во время прохода без отдельного договора не стоит.

Скачать самостоятельный пример с результатом и README

Продолжение: SplFixedArray::toArray, SplFixedArray::count.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFixedArray::jsonSerializeПредставить значения для JSON

PHP 8.1+ · SPL

public function SplFixedArray::jsonSerialize(): array

jsonSerialize отдаёт значение для кодировщика, а json_encode создаёт строку. Это две разных операции с разными результатами.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFixedArray::jsonSerialize(): array
Результатarray с последовательными индексами и null-местами; не JSON-строка.
Ошибки и особые значенияНеподдерживаемые вложенные значения/неверный UTF-8 могут вызвать ошибку именно на этапе json_encode. Используйте JSON_THROW_ON_ERROR и согласованную схему.
ВерсииPHP 8.1+
Подготовить данные для JSON, не смешивая массив и строкуСамостоятельный пример
<?php
declare(strict_types=1);

$readings = new SplFixedArray(3);
$readings[0] = 18;
$readings[2] = 22;
$value = $readings->jsonSerialize();
echo 'Первое в массиве: ', $value[0], "\n";
$text = json_encode($readings, JSON_THROW_ON_ERROR);
echo 'JSON: ', $text, "\n";
Ожидаемый результат
Первое в массиве: 18
JSON: [18,null,22]

jsonSerialize возвращает массив-представление, не готовую JSON-строку. json_encode сам вызывает этот договор и создаёт строку в $text. JSON_THROW_ON_ERROR выбирает исключение при ошибке кодирования; здесь значения простые и все позиции сохранены, включая null.

Скачать самостоятельный пример с результатом и README

Сохранить номера измерений или уплотнить значенияСамостоятельный пример
<?php
declare(strict_types=1);

$source = [3 => 22, 1 => 18];
$slots = SplFixedArray::fromArray($source);
$dense = SplFixedArray::fromArray($source, false);
echo 'С номерами: ', json_encode($slots), "\n";
echo 'По порядку входа: ', json_encode($dense), "\n";
Ожидаемый результат
С номерами: [null,18,null,22]
По порядку входа: [22,18]

:: вызывает статический метод класса, без заранее созданного объекта. По умолчанию preserveKeys=true: максимальный индекс 3 требует четырёх мест, пропуски становятся null. false забывает старые номера и располагает значения в исходном порядке обхода: сначала 22, затем 18.

Скачать самостоятельный пример с результатом и README

Продолжение: SplFixedArray::getSize, SplFixedArray::getIterator.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFixedArray::__serializeПолучить массив состояния для восстановления

PHP 8.2+ · SPL

public function SplFixedArray::__serialize(): array

__serialize — современный magic hook, который обычно вызывает глобальная serialize. Состояние включает элементы и свойства объекта; на обычном контейнере без дополнительных свойств видны позиции.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFixedArray::__serialize(): array
Результатarray состояния. В кратком Return Values официальной страницы ошибочно сказано об отсутствии возврата; сигнатура и php-src возвращают массив.
Ошибки и особые значенияСериализация вложенных значений может быть ограничена их собственным типом и hooks.
ВерсииPHP 8.2+
Передать состояние через новые hooksСамостоятельный пример
<?php
declare(strict_types=1);

$readings = SplFixedArray::fromArray([18, 22]);
$state = $readings->__serialize();
echo 'Состояние: ', json_encode($state), "\n";
$restored = new SplFixedArray();
$restored->__unserialize($state);
echo 'Восстановлены: ', implode(', ', $restored->toArray()), "\n";
Ожидаемый результат
Состояние: [18,22]
Восстановлены: 18, 22

__serialize возвращает массив состояния. В официальном разделе Return Values встречается противоречивое «значение не возвращается»; сигнатура, PHP-src и этот запуск подтверждают array. __unserialize принимает полученный массив и меняет новый объект, возвращая void. Прямой вызов показан для объяснения протокола; обычные serialize/unserialize вызывают hooks автоматически.

Скачать самостоятельный пример с результатом и README

Автоматически восстановить собственный снимокСамостоятельный пример
<?php
declare(strict_types=1);

$readings = SplFixedArray::fromArray([18, 22]);
$text = serialize($readings);
$restored = unserialize($text, ['allowed_classes' => [SplFixedArray::class]]);
foreach ($restored as $index => $value) { echo $index, ': ', $value, "\n"; }
Ожидаемый результат
0: 18
1: 22

Глобальная serialize вызывает __serialize, а unserialize — __unserialize. allowed_classes ограничивает ожидаемый класс, но не делает чужой сериализованный ввод безопасным. Здесь строка собственная, созданная строкой выше. Для обмена с клиентом выбирают JSON и проверку схемы.

Скачать самостоятельный пример с результатом и README

Продолжение: SplFixedArray::getSize, SplFixedArray::getIterator.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFixedArray::__unserializeЗаполнить объект полученным массивом состояния

PHP 8.2+ · SPL

public function SplFixedArray::__unserialize(array $data): void

__unserialize принимает состояние от __serialize; обычно его автоматически вызывает глобальная unserialize при создании объекта.

ПараметрЧто означает в задаче
dataМассив в формате парного hook; не строка от serialize и не произвольный внешний JSON.
Часть контрактаЧто важно
Сигнатураpublic function SplFixedArray::__unserialize(array $data): void
Результатvoid: состояние записано в объект.
Ошибки и особые значенияНеверный тип data — TypeError; не считайте недоверенную структуру подходящим состоянием объекта.
ВерсииPHP 8.2+
Передать состояние через новые hooksСамостоятельный пример
<?php
declare(strict_types=1);

$readings = SplFixedArray::fromArray([18, 22]);
$state = $readings->__serialize();
echo 'Состояние: ', json_encode($state), "\n";
$restored = new SplFixedArray();
$restored->__unserialize($state);
echo 'Восстановлены: ', implode(', ', $restored->toArray()), "\n";
Ожидаемый результат
Состояние: [18,22]
Восстановлены: 18, 22

__serialize возвращает массив состояния. В официальном разделе Return Values встречается противоречивое «значение не возвращается»; сигнатура, PHP-src и этот запуск подтверждают array. __unserialize принимает полученный массив и меняет новый объект, возвращая void. Прямой вызов показан для объяснения протокола; обычные serialize/unserialize вызывают hooks автоматически.

Скачать самостоятельный пример с результатом и README

Автоматически восстановить собственный снимокСамостоятельный пример
<?php
declare(strict_types=1);

$readings = SplFixedArray::fromArray([18, 22]);
$text = serialize($readings);
$restored = unserialize($text, ['allowed_classes' => [SplFixedArray::class]]);
foreach ($restored as $index => $value) { echo $index, ': ', $value, "\n"; }
Ожидаемый результат
0: 18
1: 22

Глобальная serialize вызывает __serialize, а unserialize — __unserialize. allowed_classes ограничивает ожидаемый класс, но не делает чужой сериализованный ввод безопасным. Здесь строка собственная, созданная строкой выше. Для обмена с клиентом выбирают JSON и проверку схемы.

Скачать самостоятельный пример с результатом и README

Продолжение: SplFixedArray::getSize, SplFixedArray::getIterator.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFixedArray::__wakeupРазобрать старый hook и заменить его

PHP 5.5+; deprecated с PHP 8.4 · SPL

public function SplFixedArray::__wakeup(): void

__wakeup исторически переинициализировал внутренний массив после восстановления старого формата. Современная пара __serialize/__unserialize делает ручной вызов ненужным.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFixedArray::__wakeup(): void
Результатvoid; это не получение нового контейнера.
Ошибки и особые значенияС PHP 8.4 E_DEPRECATED. Для нового кода используйте современные hooks и глобальную сериализацию собственных данных.
ВерсииPHP 5.5+; deprecated с PHP 8.4
Увидеть устаревший hook и перейти к современномуСамостоятельный пример
<?php
declare(strict_types=1);

set_error_handler(function (int $level, string $message): bool {
    if ($level === E_DEPRECATED) { echo "Старый __wakeup устарел\n"; return true; }
    return false;
});
$readings = SplFixedArray::fromArray([18, 22]);
try { $readings->__wakeup(); }
finally { restore_error_handler(); }
$restored = new SplFixedArray();
$restored->__unserialize($readings->__serialize());
echo 'После современного восстановления: ', $restored[1], "\n";
Ожидаемый результат
Старый __wakeup устарел
После современного восстановления: 22

Исторический метод устарел с PHP 8.4; пример диагностического перехода рассчитан на PHP 8.4+. Обработчик превращает именно E_DEPRECATED в понятную строку и возвращает true для этой диагностики. finally всегда восстанавливает предыдущий обработчик. Современное состояние передаётся парой __serialize/__unserialize.

Скачать самостоятельный пример с результатом и README

Автоматически восстановить собственный снимокСамостоятельный пример
<?php
declare(strict_types=1);

$readings = SplFixedArray::fromArray([18, 22]);
$text = serialize($readings);
$restored = unserialize($text, ['allowed_classes' => [SplFixedArray::class]]);
foreach ($restored as $index => $value) { echo $index, ': ', $value, "\n"; }
Ожидаемый результат
0: 18
1: 22

Глобальная serialize вызывает __serialize, а unserialize — __unserialize. allowed_classes ограничивает ожидаемый класс, но не делает чужой сериализованный ввод безопасным. Здесь строка собственная, созданная строкой выше. Для обмена с клиентом выбирают JSON и проверку схемы.

Скачать самостоятельный пример с результатом и README

Продолжение: SplFixedArray::getSize, SplFixedArray::getIterator.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFixedArray::currentИсторический current: перенести вызов на Iterator

PHP 5.3–7; метод контейнера удалён в PHP 8.0 · SPL

public function SplFixedArray::current(): mixed

Эта официальная страница относится к PHP 5.3–7: SplFixedArray тогда сам реализовывал Iterator. С PHP 8 метод удалён у контейнера. Сохранён исторический контракт: При недопустимом внутреннем указателе исторический метод выбрасывал RuntimeException. Современный эквивалент — $iterator = $readings->getIterator(), затем $iterator->current().

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFixedArray::current(): mixed
Результатmixed: текущее значение. В современном примере такой результат даёт метод отдельного итератора.
Ошибки и особые значенияПрямой вызов $readings->current() на PHP 8 вызывает Error: такого метода нет. Не вызываем удалённый API в исполняемом примере.
ВерсииPHP 5.3–7; метод контейнера удалён в PHP 8.0
Получить отдельный указатель вместо старых методовСамостоятельный пример
<?php
declare(strict_types=1);

$readings = SplFixedArray::fromArray([18, 22]);
$iterator = $readings->getIterator();
$iterator->rewind();
while ($iterator->valid()) {
    echo 'Замер ', $iterator->key(), ': ', $iterator->current(), "\n";
    $iterator->next();
}
$iterator->rewind();
echo 'Снова первый: ', $iterator->current(), "\n";
Ожидаемый результат
Замер 0: 18
Замер 1: 22
Снова первый: 18

С PHP 8 SplFixedArray реализует IteratorAggregate: контейнер выдаёт отдельный Iterator. rewind/current/key/next/valid вызываются у $iterator, не у $readings. getIterator возвращает объект в переменную; затем цикл читает индекс и значение, продвигается, останавливается. Значения не удаляются.

Скачать самостоятельный пример с результатом и README

Два просмотра с независимыми позициямиСамостоятельный пример
<?php
declare(strict_types=1);

$readings = SplFixedArray::fromArray([18, 22]);
$left = $readings->getIterator();
$right = $readings->getIterator();
$left->rewind();
$right->rewind();
$left->next();
echo 'Левый просмотр: ', $left->current(), "\n";
echo 'Правый просмотр: ', $right->current(), "\n";
$readings[0] = 19;
echo 'Правый после исправления: ', $right->current(), "\n";
Ожидаемый результат
Левый просмотр: 22
Правый просмотр: 18
Правый после исправления: 19

getIterator создаёт отдельные позиции, но оба просмотра обращаются к одному контейнеру. Следовательно, независимый указатель не равен снимку данных: исправление ячейки видно при следующем чтении. Менять размер во время прохода без отдельного договора не стоит.

Скачать самостоятельный пример с результатом и README

Продолжение: SplFixedArray::getIterator.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFixedArray::keyИсторический key: перенести вызов на Iterator

PHP 5.3–7; метод контейнера удалён в PHP 8.0 · SPL

public function SplFixedArray::key(): int

Эта официальная страница относится к PHP 5.3–7: SplFixedArray тогда сам реализовывал Iterator. С PHP 8 метод удалён у контейнера. Сохранён исторический контракт: Номер относится к позиции обхода, а не к бизнес-ID. Современный эквивалент — $iterator = $readings->getIterator(), затем $iterator->key().

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFixedArray::key(): int
Результатint: индекс текущего элемента. В современном примере такой результат даёт метод отдельного итератора.
Ошибки и особые значенияПрямой вызов $readings->key() на PHP 8 вызывает Error: такого метода нет. Не вызываем удалённый API в исполняемом примере.
ВерсииPHP 5.3–7; метод контейнера удалён в PHP 8.0
Получить отдельный указатель вместо старых методовСамостоятельный пример
<?php
declare(strict_types=1);

$readings = SplFixedArray::fromArray([18, 22]);
$iterator = $readings->getIterator();
$iterator->rewind();
while ($iterator->valid()) {
    echo 'Замер ', $iterator->key(), ': ', $iterator->current(), "\n";
    $iterator->next();
}
$iterator->rewind();
echo 'Снова первый: ', $iterator->current(), "\n";
Ожидаемый результат
Замер 0: 18
Замер 1: 22
Снова первый: 18

С PHP 8 SplFixedArray реализует IteratorAggregate: контейнер выдаёт отдельный Iterator. rewind/current/key/next/valid вызываются у $iterator, не у $readings. getIterator возвращает объект в переменную; затем цикл читает индекс и значение, продвигается, останавливается. Значения не удаляются.

Скачать самостоятельный пример с результатом и README

Два просмотра с независимыми позициямиСамостоятельный пример
<?php
declare(strict_types=1);

$readings = SplFixedArray::fromArray([18, 22]);
$left = $readings->getIterator();
$right = $readings->getIterator();
$left->rewind();
$right->rewind();
$left->next();
echo 'Левый просмотр: ', $left->current(), "\n";
echo 'Правый просмотр: ', $right->current(), "\n";
$readings[0] = 19;
echo 'Правый после исправления: ', $right->current(), "\n";
Ожидаемый результат
Левый просмотр: 22
Правый просмотр: 18
Правый после исправления: 19

getIterator создаёт отдельные позиции, но оба просмотра обращаются к одному контейнеру. Следовательно, независимый указатель не равен снимку данных: исправление ячейки видно при следующем чтении. Менять размер во время прохода без отдельного договора не стоит.

Скачать самостоятельный пример с результатом и README

Продолжение: SplFixedArray::getIterator.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFixedArray::nextИсторический next: перенести вызов на Iterator

PHP 5.3–7; метод контейнера удалён в PHP 8.0 · SPL

public function SplFixedArray::next(): void

Эта официальная страница относится к PHP 5.3–7: SplFixedArray тогда сам реализовывал Iterator. С PHP 8 метод удалён у контейнера. Сохранён исторический контракт: Следующий current читал новое место. Современный эквивалент — $iterator = $readings->getIterator(), затем $iterator->next().

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFixedArray::next(): void
Результатvoid: указатель перемещён вперёд. В современном примере такой результат даёт метод отдельного итератора.
Ошибки и особые значенияПрямой вызов $readings->next() на PHP 8 вызывает Error: такого метода нет. Не вызываем удалённый API в исполняемом примере.
ВерсииPHP 5.3–7; метод контейнера удалён в PHP 8.0
Получить отдельный указатель вместо старых методовСамостоятельный пример
<?php
declare(strict_types=1);

$readings = SplFixedArray::fromArray([18, 22]);
$iterator = $readings->getIterator();
$iterator->rewind();
while ($iterator->valid()) {
    echo 'Замер ', $iterator->key(), ': ', $iterator->current(), "\n";
    $iterator->next();
}
$iterator->rewind();
echo 'Снова первый: ', $iterator->current(), "\n";
Ожидаемый результат
Замер 0: 18
Замер 1: 22
Снова первый: 18

С PHP 8 SplFixedArray реализует IteratorAggregate: контейнер выдаёт отдельный Iterator. rewind/current/key/next/valid вызываются у $iterator, не у $readings. getIterator возвращает объект в переменную; затем цикл читает индекс и значение, продвигается, останавливается. Значения не удаляются.

Скачать самостоятельный пример с результатом и README

Два просмотра с независимыми позициямиСамостоятельный пример
<?php
declare(strict_types=1);

$readings = SplFixedArray::fromArray([18, 22]);
$left = $readings->getIterator();
$right = $readings->getIterator();
$left->rewind();
$right->rewind();
$left->next();
echo 'Левый просмотр: ', $left->current(), "\n";
echo 'Правый просмотр: ', $right->current(), "\n";
$readings[0] = 19;
echo 'Правый после исправления: ', $right->current(), "\n";
Ожидаемый результат
Левый просмотр: 22
Правый просмотр: 18
Правый после исправления: 19

getIterator создаёт отдельные позиции, но оба просмотра обращаются к одному контейнеру. Следовательно, независимый указатель не равен снимку данных: исправление ячейки видно при следующем чтении. Менять размер во время прохода без отдельного договора не стоит.

Скачать самостоятельный пример с результатом и README

Продолжение: SplFixedArray::getIterator.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFixedArray::rewindИсторический rewind: перенести вызов на Iterator

PHP 5.3–7; метод контейнера удалён в PHP 8.0 · SPL

public function SplFixedArray::rewind(): void

Эта официальная страница относится к PHP 5.3–7: SplFixedArray тогда сам реализовывал Iterator. С PHP 8 метод удалён у контейнера. Сохранён исторический контракт: Значения при перемещении не удалялись. Современный эквивалент — $iterator = $readings->getIterator(), затем $iterator->rewind().

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFixedArray::rewind(): void
Результатvoid: указатель возвращён к началу. В современном примере такой результат даёт метод отдельного итератора.
Ошибки и особые значенияПрямой вызов $readings->rewind() на PHP 8 вызывает Error: такого метода нет. Не вызываем удалённый API в исполняемом примере.
ВерсииPHP 5.3–7; метод контейнера удалён в PHP 8.0
Получить отдельный указатель вместо старых методовСамостоятельный пример
<?php
declare(strict_types=1);

$readings = SplFixedArray::fromArray([18, 22]);
$iterator = $readings->getIterator();
$iterator->rewind();
while ($iterator->valid()) {
    echo 'Замер ', $iterator->key(), ': ', $iterator->current(), "\n";
    $iterator->next();
}
$iterator->rewind();
echo 'Снова первый: ', $iterator->current(), "\n";
Ожидаемый результат
Замер 0: 18
Замер 1: 22
Снова первый: 18

С PHP 8 SplFixedArray реализует IteratorAggregate: контейнер выдаёт отдельный Iterator. rewind/current/key/next/valid вызываются у $iterator, не у $readings. getIterator возвращает объект в переменную; затем цикл читает индекс и значение, продвигается, останавливается. Значения не удаляются.

Скачать самостоятельный пример с результатом и README

Два просмотра с независимыми позициямиСамостоятельный пример
<?php
declare(strict_types=1);

$readings = SplFixedArray::fromArray([18, 22]);
$left = $readings->getIterator();
$right = $readings->getIterator();
$left->rewind();
$right->rewind();
$left->next();
echo 'Левый просмотр: ', $left->current(), "\n";
echo 'Правый просмотр: ', $right->current(), "\n";
$readings[0] = 19;
echo 'Правый после исправления: ', $right->current(), "\n";
Ожидаемый результат
Левый просмотр: 22
Правый просмотр: 18
Правый после исправления: 19

getIterator создаёт отдельные позиции, но оба просмотра обращаются к одному контейнеру. Следовательно, независимый указатель не равен снимку данных: исправление ячейки видно при следующем чтении. Менять размер во время прохода без отдельного договора не стоит.

Скачать самостоятельный пример с результатом и README

Продолжение: SplFixedArray::getIterator.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFixedArray::validИсторический valid: перенести вызов на Iterator

PHP 5.3–7; метод контейнера удалён в PHP 8.0 · SPL

public function SplFixedArray::valid(): bool

Эта официальная страница относится к PHP 5.3–7: SplFixedArray тогда сам реализовывал Iterator. С PHP 8 метод удалён у контейнера. Сохранён исторический контракт: Позволял остановить ручной цикл перед выходом за границы. Современный эквивалент — $iterator = $readings->getIterator(), затем $iterator->valid().

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFixedArray::valid(): bool
Результатbool: у указателя есть допустимая позиция. В современном примере такой результат даёт метод отдельного итератора.
Ошибки и особые значенияПрямой вызов $readings->valid() на PHP 8 вызывает Error: такого метода нет. Не вызываем удалённый API в исполняемом примере.
ВерсииPHP 5.3–7; метод контейнера удалён в PHP 8.0
Получить отдельный указатель вместо старых методовСамостоятельный пример
<?php
declare(strict_types=1);

$readings = SplFixedArray::fromArray([18, 22]);
$iterator = $readings->getIterator();
$iterator->rewind();
while ($iterator->valid()) {
    echo 'Замер ', $iterator->key(), ': ', $iterator->current(), "\n";
    $iterator->next();
}
$iterator->rewind();
echo 'Снова первый: ', $iterator->current(), "\n";
Ожидаемый результат
Замер 0: 18
Замер 1: 22
Снова первый: 18

С PHP 8 SplFixedArray реализует IteratorAggregate: контейнер выдаёт отдельный Iterator. rewind/current/key/next/valid вызываются у $iterator, не у $readings. getIterator возвращает объект в переменную; затем цикл читает индекс и значение, продвигается, останавливается. Значения не удаляются.

Скачать самостоятельный пример с результатом и README

Два просмотра с независимыми позициямиСамостоятельный пример
<?php
declare(strict_types=1);

$readings = SplFixedArray::fromArray([18, 22]);
$left = $readings->getIterator();
$right = $readings->getIterator();
$left->rewind();
$right->rewind();
$left->next();
echo 'Левый просмотр: ', $left->current(), "\n";
echo 'Правый просмотр: ', $right->current(), "\n";
$readings[0] = 19;
echo 'Правый после исправления: ', $right->current(), "\n";
Ожидаемый результат
Левый просмотр: 22
Правый просмотр: 18
Правый после исправления: 19

getIterator создаёт отдельные позиции, но оба просмотра обращаются к одному контейнеру. Следовательно, независимый указатель не равен снимку данных: исправление ячейки видно при следующем чтении. Менять размер во время прохода без отдельного договора не стоит.

Скачать самостоятельный пример с результатом и README

Продолжение: SplFixedArray::getIterator.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayObject::appendДобавить значение с новым целочисленным ключом

PHP 5+ · SPL

public function ArrayObject::append(mixed $value): void

Добавить значение с новым целочисленным ключом. Вызов относится к одному объекту ArrayObject; квадратные скобки и foreach используют те же записи, если в описании не сказано о копии.

ПараметрЧто означает в задаче
valueдобавляемое значение.
Часть контрактаЧто важно
Сигнатураpublic function ArrayObject::append(mixed $value): void
Результатvoid; меняется хранилище объекта.
Ошибки и особые значенияОбёртка над object не поддерживает append; в PHP 8.5 сам object-вход deprecated.
ВерсииPHP 5+
Добавить этапы в конец списка и увидеть созданные ключиСамостоятельный пример
<?php
$steps = new ArrayObject([0 => 'принят', 5 => 'проверен']);
$steps->append('упакован');
$steps->offsetSet(null, 'отправлен');

foreach ($steps as $key => $step) {
    echo $key, ': ', $step, "\n";
}
Ожидаемый результат
0: принят
5: проверен
6: упакован
7: отправлен

append($value) и offsetSet(null, $value) выбирают следующий целочисленный ключ после наибольшего существующего: после 5 появляются 6 и 7. Это не заполняет пропуски 1–4. foreach получает ключ и значение каждой записи.

Скачать самостоятельный пример с результатом и README

Отличить отсутствующий ключ от сохранённого nullСамостоятельный пример
<?php
$profile = new ArrayObject(['email' => 'dev@example.test', 'phone' => null]);

echo 'email: ', $profile->offsetExists('email') ? 'есть' : 'нет', "\n";
echo 'phone через offsetExists: ', $profile->offsetExists('phone') ? 'есть' : 'нет', "\n";
echo 'phone через array_key_exists: ',
    array_key_exists('phone', $profile->getArrayCopy()) ? 'есть' : 'нет', "\n";

$profile->offsetSet('city', 'Тула');
echo 'city: ', $profile->offsetGet('city'), "\n";
$profile->offsetUnset('email');
echo 'email после удаления: ', $profile->offsetExists('email') ? 'есть' : 'нет', "\n";
Ожидаемый результат
email: есть
phone через offsetExists: есть
phone через array_key_exists: есть
city: Тула
email после удаления: нет

У ArrayObject offsetExists проверяет сам ключ и в PHP 8.5 возвращает true даже при сохранённом null. Это отличается от isset у обычного массива. array_key_exists над экспортированной копией подтверждает тот же факт. offsetSet записывает, offsetGet читает, offsetUnset удаляет; все операции относятся к одной обёртке $profile.

Скачать самостоятельный пример с результатом и README

Продолжение: ArrayObject::offsetSet, ArrayObject::count.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayObject::asortОтсортировать записи по значениям, сохранив ключи

PHP 5+; return true с PHP 8.2 · SPL

public function ArrayObject::asort(int $flags = SORT_REGULAR): true

Отсортировать записи по значениям, сохранив ключи. Вызов относится к одному объекту ArrayObject; квадратные скобки и foreach используют те же записи, если в описании не сказано о копии.

ПараметрЧто означает в задаче
flagsSORT_REGULAR или явный режим сравнения.
Часть контрактаЧто важно
Сигнатураpublic function ArrayObject::asort(int $flags = SORT_REGULAR): true
Результатtrue; объект уже отсортирован.
Ошибки и особые значенияНесовместимые типы дают труднопредсказуемое прикладное сравнение.
ВерсииPHP 5+; return true с PHP 8.2
Сортировать остатки по значению или артикулы по ключуСамостоятельный пример
<?php
$stock = new ArrayObject(['B-2' => 10, 'A-1' => 2, 'C-3' => 10]);
$stock->asort(SORT_NUMERIC);
echo 'По остатку: ', implode(', ', array_keys($stock->getArrayCopy())), "\n";

$stock->ksort(SORT_STRING);
echo 'По артикулу: ', implode(', ', array_keys($stock->getArrayCopy())), "\n";
Ожидаемый результат
По остатку: A-1, B-2, C-3
По артикулу: A-1, B-2, C-3

asort сравнивает значения и сохраняет их ключи; равные 10 в PHP 8+ остаются в исходном относительном порядке B-2, C-3. ksort затем сравнивает ключи. SORT_NUMERIC и SORT_STRING делают выбранное правило явным. Оба метода меняют сам объект и возвращают true.

Скачать самостоятельный пример с результатом и README

Не путать числовую и строковую сортировкуСамостоятельный пример
<?php
$asText = new ArrayObject(['p1' => '20', 'p2' => '3', 'p3' => '100']);
$asNumber = clone $asText;

$asText->asort(SORT_STRING);
$asNumber->asort(SORT_NUMERIC);

echo 'Строки: ', implode(', ', $asText->getArrayCopy()), "\n";
echo 'Числа: ', implode(', ', $asNumber->getArrayCopy()), "\n";
Ожидаемый результат
Строки: 100, 20, 3
Числа: 3, 20, 100

Строковое сравнение идёт посимвольно, поэтому «100» раньше «20». Числовой режим трактует те же строки как числа. Клон нужен, потому что asort изменяет контейнер. Если данные формы должны быть числами, сначала проверьте и преобразуйте их, а не полагайтесь на сортировочный флаг как на валидацию.

Скачать самостоятельный пример с результатом и README

Продолжение: ArrayObject::uasort, ArrayObject::ksort.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayObject::__constructСоздать объект-обёртку вокруг массива

PHP 5+; object deprecated и enum запрещён с PHP 8.5 · SPL

public function ArrayObject::__construct(object|array $array = [], int $flags = 0, string $iteratorClass = 'ArrayIterator')

Создать объект-обёртку вокруг массива. Вызов относится к одному объекту ArrayObject; квадратные скобки и foreach используют те же записи, если в описании не сказано о копии.

ПараметрЧто означает в задаче
arrayначальный array
flagsрежим
iteratorClassподкласс ArrayIterator.
Часть контрактаЧто важно
Сигнатураpublic function ArrayObject::__construct(object|array $array = [], int $flags = 0, string $iteratorClass = 'ArrayIterator')
РезультатНовый отдельный ArrayObject.
Ошибки и особые значенияНеверный iteratorClass — TypeError; enum с PHP 8.5 — InvalidArgumentException; object-вход deprecated.
ВерсииPHP 5+; object deprecated и enum запрещён с PHP 8.5
Объект настроек: чтение, изменение и исходный массивСамостоятельный пример
<?php
$input = ['currency' => 'RUB', 'pageSize' => 20];
$settings = new ArrayObject($input);

$settings['pageSize'] = 50;
echo 'В объекте: ', $settings['pageSize'], "\n";
echo 'В исходном массиве: ', $input['pageSize'], "\n";
echo 'Записей: ', $settings->count(), "\n";
Ожидаемый результат
В объекте: 50
В исходном массиве: 20
Записей: 2

new ArrayObject($input) создаёт объект-обёртку с собственным хранилищем. Квадратные скобки вызывают методы ArrayAccess: чтение соответствует offsetGet, присваивание — offsetSet. Изменение обёртки не переписывает переменную $input. count() считает записи текущего хранилища.

Скачать самостоятельный пример с результатом и README

Подставить итератор, который форматирует только выводСамостоятельный пример
<?php
class UpperTitleIterator extends ArrayIterator {
    public function current(): mixed {
        return strtoupper((string) parent::current());
    }
}

$titles = new ArrayObject(['draft' => 'php guide']);
echo 'Итератор по умолчанию: ', $titles->getIteratorClass(), "\n";
$titles->setIteratorClass(UpperTitleIterator::class);
echo 'Выбранный итератор: ', $titles->getIteratorClass(), "\n";

$iterator = $titles->getIterator();
echo 'Класс экземпляра: ', $iterator::class, "\n";
echo 'При обходе: ', $iterator->current(), "\n";
echo 'В хранилище: ', $titles['draft'], "\n";
Ожидаемый результат
Итератор по умолчанию: ArrayIterator
Выбранный итератор: UpperTitleIterator
Класс экземпляра: UpperTitleIterator
При обходе: PHP GUIDE
В хранилище: php guide

setIteratorClass сохраняет имя подкласса ArrayIterator. getIterator создаёт новый экземпляр этого класса. Переопределённый current форматирует отдаваемое значение, но не меняет хранилище: квадратные скобки по-прежнему возвращают исходную строку.

Скачать самостоятельный пример с результатом и README

Продолжение: ArrayObject::setFlags, ArrayObject::setIteratorClass.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayObject::countУзнать число записей

PHP 5+ · SPL

public function ArrayObject::count(): int

Узнать число записей. Вызов относится к одному объекту ArrayObject; квадратные скобки и foreach используют те же записи, если в описании не сказано о копии.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function ArrayObject::count(): int
Результатint: число записей текущего хранилища.
Ошибки и особые значенияОшибки нет; 0 означает пустое хранилище.
ВерсииPHP 5+
Объект настроек: чтение, изменение и исходный массивСамостоятельный пример
<?php
$input = ['currency' => 'RUB', 'pageSize' => 20];
$settings = new ArrayObject($input);

$settings['pageSize'] = 50;
echo 'В объекте: ', $settings['pageSize'], "\n";
echo 'В исходном массиве: ', $input['pageSize'], "\n";
echo 'Записей: ', $settings->count(), "\n";
Ожидаемый результат
В объекте: 50
В исходном массиве: 20
Записей: 2

new ArrayObject($input) создаёт объект-обёртку с собственным хранилищем. Квадратные скобки вызывают методы ArrayAccess: чтение соответствует offsetGet, присваивание — offsetSet. Изменение обёртки не переписывает переменную $input. count() считает записи текущего хранилища.

Скачать самостоятельный пример с результатом и README

Добавить этапы в конец списка и увидеть созданные ключиСамостоятельный пример
<?php
$steps = new ArrayObject([0 => 'принят', 5 => 'проверен']);
$steps->append('упакован');
$steps->offsetSet(null, 'отправлен');

foreach ($steps as $key => $step) {
    echo $key, ': ', $step, "\n";
}
Ожидаемый результат
0: принят
5: проверен
6: упакован
7: отправлен

append($value) и offsetSet(null, $value) выбирают следующий целочисленный ключ после наибольшего существующего: после 5 появляются 6 и 7. Это не заполняет пропуски 1–4. foreach получает ключ и значение каждой записи.

Скачать самостоятельный пример с результатом и README

Продолжение: ArrayObject::offsetExists, ArrayObject::getArrayCopy.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayObject::exchangeArrayЗаменить всё хранилище и получить прежнее

PHP 5+; object deprecated и enum запрещён с PHP 8.5 · SPL

public function ArrayObject::exchangeArray(object|array $array): array

Заменить всё хранилище и получить прежнее. Вызов относится к одному объекту ArrayObject; квадратные скобки и foreach используют те же записи, если в описании не сказано о копии.

ПараметрЧто означает в задаче
arrayновый набор
object-вход сохранён исторически, но deprecated с PHP 8.5.
Часть контрактаЧто важно
Сигнатураpublic function ArrayObject::exchangeArray(object|array $array): array
Результатarray: прежнее хранилище.
Ошибки и особые значенияEnum запрещён; неподходящая бизнес-схема самим методом не обнаруживается.
ВерсииPHP 5+; object deprecated и enum запрещён с PHP 8.5
Атомарно заменить набор и сохранить старый для откатаСамостоятельный пример
<?php
$config = new ArrayObject(['mode' => 'test', 'limit' => 10]);
$old = $config->exchangeArray(['mode' => 'live', 'limit' => 25]);
echo 'Сейчас: ', $config['mode'], '/', $config['limit'], "\n";
echo 'Было: ', $old['mode'], '/', $old['limit'], "\n";

$config->exchangeArray($old);
echo 'После отката: ', $config['mode'], '/', $config['limit'], "\n";
Ожидаемый результат
Сейчас: live/25
Было: test/10
После отката: test/10

exchangeArray заменяет хранилище целиком и возвращает прежний массив. Поэтому старое состояние можно проверить или вернуть. Метод не проверяет бизнес-схему: обязательные ключи и типы надо валидировать до замены. Передавать object в PHP 8.5 уже deprecated; новый код использует array.

Скачать самостоятельный пример с результатом и README

Объект настроек: чтение, изменение и исходный массивСамостоятельный пример
<?php
$input = ['currency' => 'RUB', 'pageSize' => 20];
$settings = new ArrayObject($input);

$settings['pageSize'] = 50;
echo 'В объекте: ', $settings['pageSize'], "\n";
echo 'В исходном массиве: ', $input['pageSize'], "\n";
echo 'Записей: ', $settings->count(), "\n";
Ожидаемый результат
В объекте: 50
В исходном массиве: 20
Записей: 2

new ArrayObject($input) создаёт объект-обёртку с собственным хранилищем. Квадратные скобки вызывают методы ArrayAccess: чтение соответствует offsetGet, присваивание — offsetSet. Изменение обёртки не переписывает переменную $input. count() считает записи текущего хранилища.

Скачать самостоятельный пример с результатом и README

Продолжение: ArrayObject::getArrayCopy, ArrayObject::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayObject::getArrayCopyЭкспортировать хранилище в PHP-массив

PHP 5+ · SPL

public function ArrayObject::getArrayCopy(): array

Экспортировать хранилище в PHP-массив. Вызов относится к одному объекту ArrayObject; квадратные скобки и foreach используют те же записи, если в описании не сказано о копии.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function ArrayObject::getArrayCopy(): array
Результатarray: неглубокая копия записей.
Ошибки и особые значенияОшибок обычно нет.
ВерсииPHP 5+
Снимок массива: скаляры независимы, вложенный объект общийСамостоятельный пример
<?php
$state = (object) ['status' => 'new'];
$order = new ArrayObject(['quantity' => 2, 'state' => $state]);
$copy = $order->getArrayCopy();

$copy['quantity'] = 5;
$copy['state']->status = 'checked';

echo 'Количество в объекте: ', $order['quantity'], "\n";
echo 'Количество в копии: ', $copy['quantity'], "\n";
echo 'Статус в объекте: ', $order['state']->status, "\n";
Ожидаемый результат
Количество в объекте: 2
Количество в копии: 5
Статус в объекте: checked

getArrayCopy возвращает отдельный PHP-массив. Скаляр quantity меняется только в копии. Копирование неглубокое: обе структуры всё ещё ссылаются на тот же вложенный объект $state, поэтому его свойство изменилось в обеих. Для независимого снимка вложенные объекты надо копировать по выбранным правилам домена.

Скачать самостоятельный пример с результатом и README

Отличить отсутствующий ключ от сохранённого nullСамостоятельный пример
<?php
$profile = new ArrayObject(['email' => 'dev@example.test', 'phone' => null]);

echo 'email: ', $profile->offsetExists('email') ? 'есть' : 'нет', "\n";
echo 'phone через offsetExists: ', $profile->offsetExists('phone') ? 'есть' : 'нет', "\n";
echo 'phone через array_key_exists: ',
    array_key_exists('phone', $profile->getArrayCopy()) ? 'есть' : 'нет', "\n";

$profile->offsetSet('city', 'Тула');
echo 'city: ', $profile->offsetGet('city'), "\n";
$profile->offsetUnset('email');
echo 'email после удаления: ', $profile->offsetExists('email') ? 'есть' : 'нет', "\n";
Ожидаемый результат
email: есть
phone через offsetExists: есть
phone через array_key_exists: есть
city: Тула
email после удаления: нет

У ArrayObject offsetExists проверяет сам ключ и в PHP 8.5 возвращает true даже при сохранённом null. Это отличается от isset у обычного массива. array_key_exists над экспортированной копией подтверждает тот же факт. offsetSet записывает, offsetGet читает, offsetUnset удаляет; все операции относятся к одной обёртке $profile.

Скачать самостоятельный пример с результатом и README

Продолжение: ArrayObject::exchangeArray, ArrayObject::serialize.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayObject::getFlagsПрочитать текущий битовый набор поведения

PHP 5+ · SPL

public function ArrayObject::getFlags(): int

Прочитать текущий битовый набор поведения. Вызов относится к одному объекту ArrayObject; квадратные скобки и foreach используют те же записи, если в описании не сказано о копии.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function ArrayObject::getFlags(): int
Результатint: 0, STD_PROP_LIST, ARRAY_AS_PROPS или их комбинация.
Ошибки и особые значенияОшибок нет.
ВерсииPHP 5+
Доступ к записям как к свойствам — явный режимСамостоятельный пример
<?php
$profile = new ArrayObject(
    ['name' => 'Анна'],
    ArrayObject::ARRAY_AS_PROPS
);

echo 'Флаг: ', $profile->getFlags(), "\n";
echo 'Имя: ', $profile->name, "\n";
$profile->city = 'Казань';
echo 'Через скобки: ', $profile['city'], "\n";

$profile->setFlags(0);
echo 'Флаг после возврата: ', $profile->getFlags(), "\n";
Ожидаемый результат
Флаг: 2
Имя: Анна
Через скобки: Казань
Флаг после возврата: 0

ARRAY_AS_PROPS равен 2 и перенаправляет $profile->name к записи name. Присваивание свойства добавляет запись city, которую видно и через скобки. setFlags(0) отключает этот режим. Такой синтаксис удобен только при контролируемых ключах: запись с именем метода или настоящего свойства может сделать код двусмысленным.

Скачать самостоятельный пример с результатом и README

Объект настроек: чтение, изменение и исходный массивСамостоятельный пример
<?php
$input = ['currency' => 'RUB', 'pageSize' => 20];
$settings = new ArrayObject($input);

$settings['pageSize'] = 50;
echo 'В объекте: ', $settings['pageSize'], "\n";
echo 'В исходном массиве: ', $input['pageSize'], "\n";
echo 'Записей: ', $settings->count(), "\n";
Ожидаемый результат
В объекте: 50
В исходном массиве: 20
Записей: 2

new ArrayObject($input) создаёт объект-обёртку с собственным хранилищем. Квадратные скобки вызывают методы ArrayAccess: чтение соответствует offsetGet, присваивание — offsetSet. Изменение обёртки не переписывает переменную $input. count() считает записи текущего хранилища.

Скачать самостоятельный пример с результатом и README

Продолжение: ArrayObject::setFlags, ArrayObject::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayObject::getIteratorСоздать итератор для текущего хранилища

PHP 5+ · SPL

public function ArrayObject::getIterator(): Iterator

Создать итератор для текущего хранилища. Вызов относится к одному объекту ArrayObject; квадратные скобки и foreach используют те же записи, если в описании не сказано о копии.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function ArrayObject::getIterator(): Iterator
РезультатIterator выбранного класса.
Ошибки и особые значенияКонструктор пользовательского итератора может завершиться исключением.
ВерсииPHP 5+
Подставить итератор, который форматирует только выводСамостоятельный пример
<?php
class UpperTitleIterator extends ArrayIterator {
    public function current(): mixed {
        return strtoupper((string) parent::current());
    }
}

$titles = new ArrayObject(['draft' => 'php guide']);
echo 'Итератор по умолчанию: ', $titles->getIteratorClass(), "\n";
$titles->setIteratorClass(UpperTitleIterator::class);
echo 'Выбранный итератор: ', $titles->getIteratorClass(), "\n";

$iterator = $titles->getIterator();
echo 'Класс экземпляра: ', $iterator::class, "\n";
echo 'При обходе: ', $iterator->current(), "\n";
echo 'В хранилище: ', $titles['draft'], "\n";
Ожидаемый результат
Итератор по умолчанию: ArrayIterator
Выбранный итератор: UpperTitleIterator
Класс экземпляра: UpperTitleIterator
При обходе: PHP GUIDE
В хранилище: php guide

setIteratorClass сохраняет имя подкласса ArrayIterator. getIterator создаёт новый экземпляр этого класса. Переопределённый current форматирует отдаваемое значение, но не меняет хранилище: квадратные скобки по-прежнему возвращают исходную строку.

Скачать самостоятельный пример с результатом и README

Отклонить класс, который не наследует ArrayIteratorСамостоятельный пример
<?php
$items = new ArrayObject(['one']);
try {
    $items->setIteratorClass(stdClass::class);
} catch (TypeError $error) {
    echo "Нужен наследник ArrayIterator\n";
}
echo 'Остался: ', $items->getIteratorClass(), "\n";
Ожидаемый результат
Нужен наследник ArrayIterator
Остался: ArrayIterator

stdClass существует, но не является ArrayIterator. Метод выбрасывает TypeError и сохраняет прежний класс. Проверка ловит именно ожидаемый отказ; после неё объект остаётся пригодным для обхода.

Скачать самостоятельный пример с результатом и README

Продолжение: ArrayObject::getIteratorClass, ArrayObject::setIteratorClass.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayObject::getIteratorClassУзнать класс будущего итератора

PHP 5+ · SPL

public function ArrayObject::getIteratorClass(): string

Узнать класс будущего итератора. Вызов относится к одному объекту ArrayObject; квадратные скобки и foreach используют те же записи, если в описании не сказано о копии.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function ArrayObject::getIteratorClass(): string
Результатstring: полное имя класса.
Ошибки и особые значенияОшибок нет.
ВерсииPHP 5+
Подставить итератор, который форматирует только выводСамостоятельный пример
<?php
class UpperTitleIterator extends ArrayIterator {
    public function current(): mixed {
        return strtoupper((string) parent::current());
    }
}

$titles = new ArrayObject(['draft' => 'php guide']);
echo 'Итератор по умолчанию: ', $titles->getIteratorClass(), "\n";
$titles->setIteratorClass(UpperTitleIterator::class);
echo 'Выбранный итератор: ', $titles->getIteratorClass(), "\n";

$iterator = $titles->getIterator();
echo 'Класс экземпляра: ', $iterator::class, "\n";
echo 'При обходе: ', $iterator->current(), "\n";
echo 'В хранилище: ', $titles['draft'], "\n";
Ожидаемый результат
Итератор по умолчанию: ArrayIterator
Выбранный итератор: UpperTitleIterator
Класс экземпляра: UpperTitleIterator
При обходе: PHP GUIDE
В хранилище: php guide

setIteratorClass сохраняет имя подкласса ArrayIterator. getIterator создаёт новый экземпляр этого класса. Переопределённый current форматирует отдаваемое значение, но не меняет хранилище: квадратные скобки по-прежнему возвращают исходную строку.

Скачать самостоятельный пример с результатом и README

Отклонить класс, который не наследует ArrayIteratorСамостоятельный пример
<?php
$items = new ArrayObject(['one']);
try {
    $items->setIteratorClass(stdClass::class);
} catch (TypeError $error) {
    echo "Нужен наследник ArrayIterator\n";
}
echo 'Остался: ', $items->getIteratorClass(), "\n";
Ожидаемый результат
Нужен наследник ArrayIterator
Остался: ArrayIterator

stdClass существует, но не является ArrayIterator. Метод выбрасывает TypeError и сохраняет прежний класс. Проверка ловит именно ожидаемый отказ; после неё объект остаётся пригодным для обхода.

Скачать самостоятельный пример с результатом и README

Продолжение: ArrayObject::getIterator, ArrayObject::setIteratorClass.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayObject::ksortОтсортировать по ключам, сохранив значения

PHP 5+; return true с PHP 8.2 · SPL

public function ArrayObject::ksort(int $flags = SORT_REGULAR): true

Отсортировать по ключам, сохранив значения. Вызов относится к одному объекту ArrayObject; квадратные скобки и foreach используют те же записи, если в описании не сказано о копии.

ПараметрЧто означает в задаче
flagsправило сравнения ключей.
Часть контрактаЧто важно
Сигнатураpublic function ArrayObject::ksort(int $flags = SORT_REGULAR): true
Результатtrue; объект изменён.
Ошибки и особые значенияСмешанные типы ключей требуют осознанного режима.
ВерсииPHP 5+; return true с PHP 8.2
Сортировать остатки по значению или артикулы по ключуСамостоятельный пример
<?php
$stock = new ArrayObject(['B-2' => 10, 'A-1' => 2, 'C-3' => 10]);
$stock->asort(SORT_NUMERIC);
echo 'По остатку: ', implode(', ', array_keys($stock->getArrayCopy())), "\n";

$stock->ksort(SORT_STRING);
echo 'По артикулу: ', implode(', ', array_keys($stock->getArrayCopy())), "\n";
Ожидаемый результат
По остатку: A-1, B-2, C-3
По артикулу: A-1, B-2, C-3

asort сравнивает значения и сохраняет их ключи; равные 10 в PHP 8+ остаются в исходном относительном порядке B-2, C-3. ksort затем сравнивает ключи. SORT_NUMERIC и SORT_STRING делают выбранное правило явным. Оба метода меняют сам объект и возвращают true.

Скачать самостоятельный пример с результатом и README

Сортировать ключи-номера естественным сравнениемСамостоятельный пример
<?php
$pages = new ArrayObject([
    'page10' => 'Десятая',
    'page2' => 'Вторая',
    'page1' => 'Первая',
]);
$pages->uksort(fn(string $a, string $b): int => strnatcmp($a, $b));
echo implode(', ', array_keys($pages->getArrayCopy())), "\n";
Ожидаемый результат
page1, page2, page10

uksort передаёт callback два ключа, а значения остаются прикреплены к своим ключам. strnatcmp возвращает требуемый целый знак и понимает числовую часть. Если нужно сортировать значения, выбирайте uasort, а не читайте их через внешнюю переменную из callback.

Скачать самостоятельный пример с результатом и README

Продолжение: ArrayObject::uksort, ArrayObject::asort.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayObject::natcasesortЕстественно отсортировать значения без учёта регистра

PHP 5+; return true с PHP 8.2 · SPL

public function ArrayObject::natcasesort(): true

Естественно отсортировать значения без учёта регистра. Вызов относится к одному объекту ArrayObject; квадратные скобки и foreach используют те же записи, если в описании не сказано о копии.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function ArrayObject::natcasesort(): true
Результатtrue с PHP 8.2; объект изменён.
Ошибки и особые значенияОшибок обычно нет.
ВерсииPHP 5+; return true с PHP 8.2
Поставить имена файлов в человеческом порядкеСамостоятельный пример
<?php
$names = new ArrayObject(['img12.png', 'img2.png', 'IMG1.png', 'img10.png']);
$caseSensitive = clone $names;

$caseSensitive->natsort();
$names->natcasesort();

echo 'С учётом регистра: ', implode(', ', $caseSensitive->getArrayCopy()), "\n";
echo 'Без учёта регистра: ', implode(', ', $names->getArrayCopy()), "\n";
Ожидаемый результат
С учётом регистра: IMG1.png, img2.png, img10.png, img12.png
Без учёта регистра: IMG1.png, img2.png, img10.png, img12.png

natsort распознаёт числовые части строк, поэтому img2 идёт раньше img10. natcasesort дополнительно игнорирует регистр. На этих данных результат совпал; отличие проявится на других сочетаниях регистра. Оба метода сохраняют исходные ключи и с PHP 8.2 имеют точный тип возврата true.

Скачать самостоятельный пример с результатом и README

Увидеть отличие сортировки с учётом регистраСамостоятельный пример
<?php
$names = new ArrayObject(['a2', 'A1', 'a1']);
$sensitive = clone $names;
$sensitive->natsort();
$names->natcasesort();

echo 'Регистр важен: ', implode(', ', $sensitive->getArrayCopy()), "\n";
echo 'Регистр не важен: ', implode(', ', $names->getArrayCopy()), "\n";
Ожидаемый результат
Регистр важен: A1, a1, a2
Регистр не важен: A1, a1, a2

Пример оставляет две записи, равные при сравнении без регистра. Начиная с PHP 8.0 равные элементы сохраняют прежний относительный порядок: A1 до a1. Для сортировки по правилам языка пользователя нужен Collator из intl, а не обещание, что natural-порядок знает алфавит конкретного языка.

Скачать самостоятельный пример с результатом и README

Продолжение: ArrayObject::natsort, ArrayObject::asort.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayObject::natsortЕстественно отсортировать значения с учётом регистра

PHP 5+; return true с PHP 8.2 · SPL

public function ArrayObject::natsort(): true

Естественно отсортировать значения с учётом регистра. Вызов относится к одному объекту ArrayObject; квадратные скобки и foreach используют те же записи, если в описании не сказано о копии.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function ArrayObject::natsort(): true
Результатtrue с PHP 8.2; объект изменён.
Ошибки и особые значенияОшибок обычно нет.
ВерсииPHP 5+; return true с PHP 8.2
Поставить имена файлов в человеческом порядкеСамостоятельный пример
<?php
$names = new ArrayObject(['img12.png', 'img2.png', 'IMG1.png', 'img10.png']);
$caseSensitive = clone $names;

$caseSensitive->natsort();
$names->natcasesort();

echo 'С учётом регистра: ', implode(', ', $caseSensitive->getArrayCopy()), "\n";
echo 'Без учёта регистра: ', implode(', ', $names->getArrayCopy()), "\n";
Ожидаемый результат
С учётом регистра: IMG1.png, img2.png, img10.png, img12.png
Без учёта регистра: IMG1.png, img2.png, img10.png, img12.png

natsort распознаёт числовые части строк, поэтому img2 идёт раньше img10. natcasesort дополнительно игнорирует регистр. На этих данных результат совпал; отличие проявится на других сочетаниях регистра. Оба метода сохраняют исходные ключи и с PHP 8.2 имеют точный тип возврата true.

Скачать самостоятельный пример с результатом и README

Увидеть отличие сортировки с учётом регистраСамостоятельный пример
<?php
$names = new ArrayObject(['a2', 'A1', 'a1']);
$sensitive = clone $names;
$sensitive->natsort();
$names->natcasesort();

echo 'Регистр важен: ', implode(', ', $sensitive->getArrayCopy()), "\n";
echo 'Регистр не важен: ', implode(', ', $names->getArrayCopy()), "\n";
Ожидаемый результат
Регистр важен: A1, a1, a2
Регистр не важен: A1, a1, a2

Пример оставляет две записи, равные при сравнении без регистра. Начиная с PHP 8.0 равные элементы сохраняют прежний относительный порядок: A1 до a1. Для сортировки по правилам языка пользователя нужен Collator из intl, а не обещание, что natural-порядок знает алфавит конкретного языка.

Скачать самостоятельный пример с результатом и README

Продолжение: ArrayObject::natcasesort, ArrayObject::asort.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayObject::offsetExistsПроверить, существует ли ключ

PHP 5+ · SPL

public function ArrayObject::offsetExists(mixed $key): bool

Проверить, существует ли ключ. Вызов относится к одному объекту ArrayObject; квадратные скобки и foreach используют те же записи, если в описании не сказано о копии.

ПараметрЧто означает в задаче
keyпроверяемый ключ.
Часть контрактаЧто важно
Сигнатураpublic function ArrayObject::offsetExists(mixed $key): bool
Результатbool; в PHP 8.5 существующий ключ со значением null даёт true.
Ошибки и особые значенияНеверный тип ключа может вызвать TypeError.
ВерсииPHP 5+
Отличить отсутствующий ключ от сохранённого nullСамостоятельный пример
<?php
$profile = new ArrayObject(['email' => 'dev@example.test', 'phone' => null]);

echo 'email: ', $profile->offsetExists('email') ? 'есть' : 'нет', "\n";
echo 'phone через offsetExists: ', $profile->offsetExists('phone') ? 'есть' : 'нет', "\n";
echo 'phone через array_key_exists: ',
    array_key_exists('phone', $profile->getArrayCopy()) ? 'есть' : 'нет', "\n";

$profile->offsetSet('city', 'Тула');
echo 'city: ', $profile->offsetGet('city'), "\n";
$profile->offsetUnset('email');
echo 'email после удаления: ', $profile->offsetExists('email') ? 'есть' : 'нет', "\n";
Ожидаемый результат
email: есть
phone через offsetExists: есть
phone через array_key_exists: есть
city: Тула
email после удаления: нет

У ArrayObject offsetExists проверяет сам ключ и в PHP 8.5 возвращает true даже при сохранённом null. Это отличается от isset у обычного массива. array_key_exists над экспортированной копией подтверждает тот же факт. offsetSet записывает, offsetGet читает, offsetUnset удаляет; все операции относятся к одной обёртке $profile.

Скачать самостоятельный пример с результатом и README

Безопасно заметить чтение отсутствующей настройкиСамостоятельный пример
<?php
$settings = new ArrayObject(['theme' => 'dark']);
$warning = false;
set_error_handler(function (int $severity) use (&$warning): bool {
    if ($severity === E_WARNING) {
        $warning = true;
        return true;
    }
    return false;
});
$value = $settings->offsetGet('locale');
restore_error_handler();

echo 'Предупреждение: ', $warning ? 'да' : 'нет', "\n";
echo 'Результат: ', $value === null ? 'NULL' : $value, "\n";
Ожидаемый результат
Предупреждение: да
Результат: NULL

В PHP 8.5 отсутствующий индекс выдаёт E_WARNING и возвращает null; официальная старая страница всё ещё называет диагностику E_NOTICE. Обработчик здесь только превращает ожидаемую учебную диагностику в видимый факт. В приложении сначала используйте offsetExists/array_key_exists или задайте значение по умолчанию.

Скачать самостоятельный пример с результатом и README

Продолжение: ArrayObject::offsetGet, ArrayObject::getArrayCopy.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayObject::offsetGetПрочитать запись по ключу

PHP 5+ · SPL

public function ArrayObject::offsetGet(mixed $key): mixed

Прочитать запись по ключу. Вызов относится к одному объекту ArrayObject; квадратные скобки и foreach используют те же записи, если в описании не сказано о копии.

ПараметрЧто означает в задаче
keyцелый или строковый ключ.
Часть контрактаЧто важно
Сигнатураpublic function ArrayObject::offsetGet(mixed $key): mixed
Результатmixed; значение либо null при отсутствии.
Ошибки и особые значенияОтсутствующий ключ в современном PHP создаёт E_WARNING; старая документация говорит E_NOTICE.
ВерсииPHP 5+
Отличить отсутствующий ключ от сохранённого nullСамостоятельный пример
<?php
$profile = new ArrayObject(['email' => 'dev@example.test', 'phone' => null]);

echo 'email: ', $profile->offsetExists('email') ? 'есть' : 'нет', "\n";
echo 'phone через offsetExists: ', $profile->offsetExists('phone') ? 'есть' : 'нет', "\n";
echo 'phone через array_key_exists: ',
    array_key_exists('phone', $profile->getArrayCopy()) ? 'есть' : 'нет', "\n";

$profile->offsetSet('city', 'Тула');
echo 'city: ', $profile->offsetGet('city'), "\n";
$profile->offsetUnset('email');
echo 'email после удаления: ', $profile->offsetExists('email') ? 'есть' : 'нет', "\n";
Ожидаемый результат
email: есть
phone через offsetExists: есть
phone через array_key_exists: есть
city: Тула
email после удаления: нет

У ArrayObject offsetExists проверяет сам ключ и в PHP 8.5 возвращает true даже при сохранённом null. Это отличается от isset у обычного массива. array_key_exists над экспортированной копией подтверждает тот же факт. offsetSet записывает, offsetGet читает, offsetUnset удаляет; все операции относятся к одной обёртке $profile.

Скачать самостоятельный пример с результатом и README

Безопасно заметить чтение отсутствующей настройкиСамостоятельный пример
<?php
$settings = new ArrayObject(['theme' => 'dark']);
$warning = false;
set_error_handler(function (int $severity) use (&$warning): bool {
    if ($severity === E_WARNING) {
        $warning = true;
        return true;
    }
    return false;
});
$value = $settings->offsetGet('locale');
restore_error_handler();

echo 'Предупреждение: ', $warning ? 'да' : 'нет', "\n";
echo 'Результат: ', $value === null ? 'NULL' : $value, "\n";
Ожидаемый результат
Предупреждение: да
Результат: NULL

В PHP 8.5 отсутствующий индекс выдаёт E_WARNING и возвращает null; официальная старая страница всё ещё называет диагностику E_NOTICE. Обработчик здесь только превращает ожидаемую учебную диагностику в видимый факт. В приложении сначала используйте offsetExists/array_key_exists или задайте значение по умолчанию.

Скачать самостоятельный пример с результатом и README

Продолжение: ArrayObject::offsetExists, ArrayObject::offsetSet.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayObject::offsetSetЗаписать значение по ключу или добавить в конец

PHP 5+ · SPL

public function ArrayObject::offsetSet(mixed $key, mixed $value): void

Записать значение по ключу или добавить в конец. Вызов относится к одному объекту ArrayObject; квадратные скобки и foreach используют те же записи, если в описании не сказано о копии.

ПараметрЧто означает в задаче
keyключ либо null для append
valueзначение.
Часть контрактаЧто важно
Сигнатураpublic function ArrayObject::offsetSet(mixed $key, mixed $value): void
Результатvoid; меняется хранилище.
Ошибки и особые значенияНеподходящий ключ — TypeError.
ВерсииPHP 5+
Отличить отсутствующий ключ от сохранённого nullСамостоятельный пример
<?php
$profile = new ArrayObject(['email' => 'dev@example.test', 'phone' => null]);

echo 'email: ', $profile->offsetExists('email') ? 'есть' : 'нет', "\n";
echo 'phone через offsetExists: ', $profile->offsetExists('phone') ? 'есть' : 'нет', "\n";
echo 'phone через array_key_exists: ',
    array_key_exists('phone', $profile->getArrayCopy()) ? 'есть' : 'нет', "\n";

$profile->offsetSet('city', 'Тула');
echo 'city: ', $profile->offsetGet('city'), "\n";
$profile->offsetUnset('email');
echo 'email после удаления: ', $profile->offsetExists('email') ? 'есть' : 'нет', "\n";
Ожидаемый результат
email: есть
phone через offsetExists: есть
phone через array_key_exists: есть
city: Тула
email после удаления: нет

У ArrayObject offsetExists проверяет сам ключ и в PHP 8.5 возвращает true даже при сохранённом null. Это отличается от isset у обычного массива. array_key_exists над экспортированной копией подтверждает тот же факт. offsetSet записывает, offsetGet читает, offsetUnset удаляет; все операции относятся к одной обёртке $profile.

Скачать самостоятельный пример с результатом и README

Добавить этапы в конец списка и увидеть созданные ключиСамостоятельный пример
<?php
$steps = new ArrayObject([0 => 'принят', 5 => 'проверен']);
$steps->append('упакован');
$steps->offsetSet(null, 'отправлен');

foreach ($steps as $key => $step) {
    echo $key, ': ', $step, "\n";
}
Ожидаемый результат
0: принят
5: проверен
6: упакован
7: отправлен

append($value) и offsetSet(null, $value) выбирают следующий целочисленный ключ после наибольшего существующего: после 5 появляются 6 и 7. Это не заполняет пропуски 1–4. foreach получает ключ и значение каждой записи.

Скачать самостоятельный пример с результатом и README

Продолжение: ArrayObject::append, ArrayObject::offsetGet.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayObject::offsetUnsetУдалить запись по ключу

PHP 5+ · SPL

public function ArrayObject::offsetUnset(mixed $key): void

Удалить запись по ключу. Вызов относится к одному объекту ArrayObject; квадратные скобки и foreach используют те же записи, если в описании не сказано о копии.

ПараметрЧто означает в задаче
keyудаляемый ключ.
Часть контрактаЧто важно
Сигнатураpublic function ArrayObject::offsetUnset(mixed $key): void
Результатvoid.
Ошибки и особые значенияНеверный тип ключа может вызвать TypeError.
ВерсииPHP 5+
Отличить отсутствующий ключ от сохранённого nullСамостоятельный пример
<?php
$profile = new ArrayObject(['email' => 'dev@example.test', 'phone' => null]);

echo 'email: ', $profile->offsetExists('email') ? 'есть' : 'нет', "\n";
echo 'phone через offsetExists: ', $profile->offsetExists('phone') ? 'есть' : 'нет', "\n";
echo 'phone через array_key_exists: ',
    array_key_exists('phone', $profile->getArrayCopy()) ? 'есть' : 'нет', "\n";

$profile->offsetSet('city', 'Тула');
echo 'city: ', $profile->offsetGet('city'), "\n";
$profile->offsetUnset('email');
echo 'email после удаления: ', $profile->offsetExists('email') ? 'есть' : 'нет', "\n";
Ожидаемый результат
email: есть
phone через offsetExists: есть
phone через array_key_exists: есть
city: Тула
email после удаления: нет

У ArrayObject offsetExists проверяет сам ключ и в PHP 8.5 возвращает true даже при сохранённом null. Это отличается от isset у обычного массива. array_key_exists над экспортированной копией подтверждает тот же факт. offsetSet записывает, offsetGet читает, offsetUnset удаляет; все операции относятся к одной обёртке $profile.

Скачать самостоятельный пример с результатом и README

Добавить этапы в конец списка и увидеть созданные ключиСамостоятельный пример
<?php
$steps = new ArrayObject([0 => 'принят', 5 => 'проверен']);
$steps->append('упакован');
$steps->offsetSet(null, 'отправлен');

foreach ($steps as $key => $step) {
    echo $key, ': ', $step, "\n";
}
Ожидаемый результат
0: принят
5: проверен
6: упакован
7: отправлен

append($value) и offsetSet(null, $value) выбирают следующий целочисленный ключ после наибольшего существующего: после 5 появляются 6 и 7. Это не заполняет пропуски 1–4. foreach получает ключ и значение каждой записи.

Скачать самостоятельный пример с результатом и README

Продолжение: ArrayObject::offsetExists, ArrayObject::count.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayObject::serializeПолучить внутреннюю строку доверенного снимка

PHP 5+ · SPL

public function ArrayObject::serialize(): string

Получить внутреннюю строку доверенного снимка. Вызов относится к одному объекту ArrayObject; квадратные скобки и foreach используют те же записи, если в описании не сказано о копии.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function ArrayObject::serialize(): string
Результатstring: PHP-представление ArrayObject.
Ошибки и особые значенияНеподдерживаемые вложенные значения могут вызвать исключение.
ВерсииPHP 5+
Сделать доверенный снимок и восстановить его в новом объектеСамостоятельный пример
<?php
$source = new ArrayObject(['job' => 'export', 'attempt' => 2]);
$payload = $source->serialize();

$restored = new ArrayObject();
$restored->unserialize($payload);
echo $restored['job'], ': попытка ', $restored['attempt'], "\n";
echo 'Записей: ', $restored->count(), "\n";
Ожидаемый результат
export: попытка 2
Записей: 2

serialize() возвращает внутреннее PHP-представление состояния ArrayObject. unserialize($payload) заполняет уже созданный объект. Формат предназначен для доверенного локального снимка одной PHP-системы, а не для публичного API. Не передавайте сюда строку от пользователя: десериализация объектов может выполнять код классов.

Скачать самостоятельный пример с результатом и README

Сохранить локальный учебный кеш и прочитать егоСамостоятельный пример
<?php
$path = __DIR__ . '/settings.cache';
$settings = new ArrayObject(['locale' => 'ru', 'rows' => 25]);
file_put_contents($path, $settings->serialize());

$loaded = new ArrayObject();
$data = file_get_contents($path);
if ($data === false) {
    throw new RuntimeException('Не прочитан локальный кеш');
}
$loaded->unserialize($data);
echo $loaded['locale'], '/', $loaded['rows'], "\n";
unlink($path);
Ожидаемый результат
ru/25

Файл создаётся только в отдельной учебной папке примера и удаляется в конце. Проверяется отказ file_get_contents. В реальном кеше нужны контроль срока, атомарная запись и политика повреждённого файла. Для обмена между сервисами используйте явную JSON-схему, а не PHP-сериализацию.

Скачать самостоятельный пример с результатом и README

Продолжение: ArrayObject::unserialize, ArrayObject::getArrayCopy.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayObject::setFlagsИзменить режим доступа к записям и свойствам

PHP 5+ · SPL

public function ArrayObject::setFlags(int $flags): void

Изменить режим доступа к записям и свойствам. Вызов относится к одному объекту ArrayObject; квадратные скобки и foreach используют те же записи, если в описании не сказано о копии.

ПараметрЧто означает в задаче
flagsбитовая маска именованных констант.
Часть контрактаЧто важно
Сигнатураpublic function ArrayObject::setFlags(int $flags): void
Результатvoid.
Ошибки и особые значенияНеподходящий тип — TypeError.
ВерсииPHP 5+
Доступ к записям как к свойствам — явный режимСамостоятельный пример
<?php
$profile = new ArrayObject(
    ['name' => 'Анна'],
    ArrayObject::ARRAY_AS_PROPS
);

echo 'Флаг: ', $profile->getFlags(), "\n";
echo 'Имя: ', $profile->name, "\n";
$profile->city = 'Казань';
echo 'Через скобки: ', $profile['city'], "\n";

$profile->setFlags(0);
echo 'Флаг после возврата: ', $profile->getFlags(), "\n";
Ожидаемый результат
Флаг: 2
Имя: Анна
Через скобки: Казань
Флаг после возврата: 0

ARRAY_AS_PROPS равен 2 и перенаправляет $profile->name к записи name. Присваивание свойства добавляет запись city, которую видно и через скобки. setFlags(0) отключает этот режим. Такой синтаксис удобен только при контролируемых ключах: запись с именем метода или настоящего свойства может сделать код двусмысленным.

Скачать самостоятельный пример с результатом и README

Объект настроек: чтение, изменение и исходный массивСамостоятельный пример
<?php
$input = ['currency' => 'RUB', 'pageSize' => 20];
$settings = new ArrayObject($input);

$settings['pageSize'] = 50;
echo 'В объекте: ', $settings['pageSize'], "\n";
echo 'В исходном массиве: ', $input['pageSize'], "\n";
echo 'Записей: ', $settings->count(), "\n";
Ожидаемый результат
В объекте: 50
В исходном массиве: 20
Записей: 2

new ArrayObject($input) создаёт объект-обёртку с собственным хранилищем. Квадратные скобки вызывают методы ArrayAccess: чтение соответствует offsetGet, присваивание — offsetSet. Изменение обёртки не переписывает переменную $input. count() считает записи текущего хранилища.

Скачать самостоятельный пример с результатом и README

Продолжение: ArrayObject::getFlags, ArrayObject::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayObject::setIteratorClassВыбрать подкласс ArrayIterator для обхода

PHP 5+ · SPL

public function ArrayObject::setIteratorClass(string $iteratorClass): void

Выбрать подкласс ArrayIterator для обхода. Вызов относится к одному объекту ArrayObject; квадратные скобки и foreach используют те же записи, если в описании не сказано о копии.

ПараметрЧто означает в задаче
iteratorClassсуществующее имя подкласса ArrayIterator.
Часть контрактаЧто важно
Сигнатураpublic function ArrayObject::setIteratorClass(string $iteratorClass): void
Результатvoid.
Ошибки и особые значенияНеверный класс — TypeError.
ВерсииPHP 5+
Подставить итератор, который форматирует только выводСамостоятельный пример
<?php
class UpperTitleIterator extends ArrayIterator {
    public function current(): mixed {
        return strtoupper((string) parent::current());
    }
}

$titles = new ArrayObject(['draft' => 'php guide']);
echo 'Итератор по умолчанию: ', $titles->getIteratorClass(), "\n";
$titles->setIteratorClass(UpperTitleIterator::class);
echo 'Выбранный итератор: ', $titles->getIteratorClass(), "\n";

$iterator = $titles->getIterator();
echo 'Класс экземпляра: ', $iterator::class, "\n";
echo 'При обходе: ', $iterator->current(), "\n";
echo 'В хранилище: ', $titles['draft'], "\n";
Ожидаемый результат
Итератор по умолчанию: ArrayIterator
Выбранный итератор: UpperTitleIterator
Класс экземпляра: UpperTitleIterator
При обходе: PHP GUIDE
В хранилище: php guide

setIteratorClass сохраняет имя подкласса ArrayIterator. getIterator создаёт новый экземпляр этого класса. Переопределённый current форматирует отдаваемое значение, но не меняет хранилище: квадратные скобки по-прежнему возвращают исходную строку.

Скачать самостоятельный пример с результатом и README

Отклонить класс, который не наследует ArrayIteratorСамостоятельный пример
<?php
$items = new ArrayObject(['one']);
try {
    $items->setIteratorClass(stdClass::class);
} catch (TypeError $error) {
    echo "Нужен наследник ArrayIterator\n";
}
echo 'Остался: ', $items->getIteratorClass(), "\n";
Ожидаемый результат
Нужен наследник ArrayIterator
Остался: ArrayIterator

stdClass существует, но не является ArrayIterator. Метод выбрасывает TypeError и сохраняет прежний класс. Проверка ловит именно ожидаемый отказ; после неё объект остаётся пригодным для обхода.

Скачать самостоятельный пример с результатом и README

Продолжение: ArrayObject::getIteratorClass, ArrayObject::getIterator.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayObject::uasortСортировать значения пользовательским правилом, сохраняя ключи

PHP 5+; return true с PHP 8.2 · SPL

public function ArrayObject::uasort(callable $callback): true

Сортировать значения пользовательским правилом, сохраняя ключи. Вызов относится к одному объекту ArrayObject; квадратные скобки и foreach используют те же записи, если в описании не сказано о копии.

ПараметрЧто означает в задаче
callback($a, $b): intотрицательное/0/положительное.
Часть контрактаЧто важно
Сигнатураpublic function ArrayObject::uasort(callable $callback): true
Результатtrue; объект изменён.
Ошибки и особые значенияИсключение callback прерывает сортировку; float приводится к int и может стать 0.
ВерсииPHP 5+; return true с PHP 8.2
Сортировать товары по цене, затем по названиюСамостоятельный пример
<?php
$products = new ArrayObject([
    'p9' => ['name' => 'Кабель', 'price' => 500],
    'p2' => ['name' => 'Лампа', 'price' => 300],
    'p7' => ['name' => 'Адаптер', 'price' => 500],
]);
$products->uasort(function (array $left, array $right): int {
    return [$left['price'], $left['name']] <=> [$right['price'], $right['name']];
});

foreach ($products as $id => $product) {
    echo $id, ': ', $product['name'], ' — ', $product['price'], "\n";
}
Ожидаемый результат
p2: Лампа — 300
p7: Адаптер — 500
p9: Кабель — 500

callback получает два значения, не ключи. Оператор <=> возвращает отрицательное число, 0 или положительное число. Сначала сравнивается price, при равенстве — name. uasort сохраняет ключи p2/p7/p9 и меняет порядок самого объекта.

Скачать самостоятельный пример с результатом и README

Сохранить порядок равных заявокСамостоятельный пример
<?php
$tickets = new ArrayObject([
    'T-7' => ['priority' => 2, 'title' => 'Первый'],
    'T-8' => ['priority' => 1, 'title' => 'Срочный'],
    'T-9' => ['priority' => 2, 'title' => 'Второй'],
]);
$tickets->uasort(
    fn(array $a, array $b): int => $a['priority'] <=> $b['priority']
);
echo implode(', ', array_keys($tickets->getArrayCopy())), "\n";
Ожидаемый результат
T-8, T-7, T-9

Сравнение возвращает 0 для T-7 и T-9. В PHP 8+ стабильная сортировка оставляет их в исходном порядке. Это не означает FIFO между разными процессами или запросами: здесь сортируется один объект в памяти.

Скачать самостоятельный пример с результатом и README

Продолжение: ArrayObject::asort, ArrayObject::uksort.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayObject::uksortСортировать ключи пользовательским правилом

PHP 5+; return true с PHP 8.2 · SPL

public function ArrayObject::uksort(callable $callback): true

Сортировать ключи пользовательским правилом. Вызов относится к одному объекту ArrayObject; квадратные скобки и foreach используют те же записи, если в описании не сказано о копии.

ПараметрЧто означает в задаче
callback($a, $b): intсравнение двух ключей.
Часть контрактаЧто важно
Сигнатураpublic function ArrayObject::uksort(callable $callback): true
Результатtrue; объект изменён.
Ошибки и особые значенияИсключение callback прерывает сортировку; неверный тип результата приводится.
ВерсииPHP 5+; return true с PHP 8.2
Сортировать ключи-номера естественным сравнениемСамостоятельный пример
<?php
$pages = new ArrayObject([
    'page10' => 'Десятая',
    'page2' => 'Вторая',
    'page1' => 'Первая',
]);
$pages->uksort(fn(string $a, string $b): int => strnatcmp($a, $b));
echo implode(', ', array_keys($pages->getArrayCopy())), "\n";
Ожидаемый результат
page1, page2, page10

uksort передаёт callback два ключа, а значения остаются прикреплены к своим ключам. strnatcmp возвращает требуемый целый знак и понимает числовую часть. Если нужно сортировать значения, выбирайте uasort, а не читайте их через внешнюю переменную из callback.

Скачать самостоятельный пример с результатом и README

Поставить обязательные поля перед дополнительнымиСамостоятельный пример
<?php
$payload = new ArrayObject([
    'comment' => 'Оставить у двери',
    'phone' => '+7-000-000-00-00',
    'name' => 'Ирина',
]);
$rank = ['name' => 0, 'phone' => 1, 'comment' => 2];
$payload->uksort(
    fn(string $a, string $b): int => ($rank[$a] ?? 99) <=> ($rank[$b] ?? 99)
);
echo implode(' → ', array_keys($payload->getArrayCopy())), "\n";
Ожидаемый результат
name → phone → comment

Таблица $rank превращает бизнес-порядок в числа. ?? 99 отправляет неизвестные поля в конец. callback не изменяет массив рангов и всегда возвращает int. Для фиксированного вывода нескольких полей прямой список ключей может быть проще; uksort полезен, когда набор расширяется.

Скачать самостоятельный пример с результатом и README

Продолжение: ArrayObject::ksort, ArrayObject::uasort.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayObject::unserializeЗаполнить объект из доверенной строки ArrayObject

PHP 5+ · SPL

public function ArrayObject::unserialize(string $data): void

Заполнить объект из доверенной строки ArrayObject. Вызов относится к одному объекту ArrayObject; квадратные скобки и foreach используют те же записи, если в описании не сказано о копии.

ПараметрЧто означает в задаче
dataстрока, ранее полученная совместимой сериализацией.
Часть контрактаЧто важно
Сигнатураpublic function ArrayObject::unserialize(string $data): void
Результатvoid; текущий объект получает восстановленное состояние.
Ошибки и особые значенияПовреждённая строка — UnexpectedValueException; классы внутри могут быть недоступны.
ВерсииPHP 5+
Сделать доверенный снимок и восстановить его в новом объектеСамостоятельный пример
<?php
$source = new ArrayObject(['job' => 'export', 'attempt' => 2]);
$payload = $source->serialize();

$restored = new ArrayObject();
$restored->unserialize($payload);
echo $restored['job'], ': попытка ', $restored['attempt'], "\n";
echo 'Записей: ', $restored->count(), "\n";
Ожидаемый результат
export: попытка 2
Записей: 2

serialize() возвращает внутреннее PHP-представление состояния ArrayObject. unserialize($payload) заполняет уже созданный объект. Формат предназначен для доверенного локального снимка одной PHP-системы, а не для публичного API. Не передавайте сюда строку от пользователя: десериализация объектов может выполнять код классов.

Скачать самостоятельный пример с результатом и README

Сохранить локальный учебный кеш и прочитать егоСамостоятельный пример
<?php
$path = __DIR__ . '/settings.cache';
$settings = new ArrayObject(['locale' => 'ru', 'rows' => 25]);
file_put_contents($path, $settings->serialize());

$loaded = new ArrayObject();
$data = file_get_contents($path);
if ($data === false) {
    throw new RuntimeException('Не прочитан локальный кеш');
}
$loaded->unserialize($data);
echo $loaded['locale'], '/', $loaded['rows'], "\n";
unlink($path);
Ожидаемый результат
ru/25

Файл создаётся только в отдельной учебной папке примера и удаляется в конце. Проверяется отказ file_get_contents. В реальном кеше нужны контроль срока, атомарная запись и политика повреждённого файла. Для обмена между сервисами используйте явную JSON-схему, а не PHP-сериализацию.

Скачать самостоятельный пример с результатом и README

Продолжение: ArrayObject::serialize, ArrayObject::exchangeArray.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplObjectStorage::addAllДобавить пары из другого хранилища

PHP 5.3+ · SPL

public function SplObjectStorage::addAll(SplObjectStorage $storage): int

Добавить пары из другого хранилища. SplObjectStorage отделяет object-key от связанного info; операция использует идентичность объекта или результат переопределённого getHash.

ПараметрЧто означает в задаче
storageисточник пар object→info.
Часть контрактаЧто важно
Сигнатураpublic function SplObjectStorage::addAll(SplObjectStorage $storage): int
Результатint: итоговый размер текущего storage.
Ошибки и особые значенияОшибок нет при корректном SplObjectStorage; TypeError для другого типа.
ВерсииPHP 5.3+
Объединить наборы и увидеть замену info совпавшего объектаСамостоятельный пример
<?php
$anna = (object) ['name' => 'Анна'];
$boris = (object) ['name' => 'Борис'];
$reviewers = new SplObjectStorage();
$reviewers[$anna] = 'основной';

$nightShift = new SplObjectStorage();
$nightShift[$anna] = 'ночная смена';
$nightShift[$boris] = 'резерв';

$count = $reviewers->addAll($nightShift);
echo 'После объединения: ', $count, "\n";
echo 'Анна: ', $reviewers[$anna], "\n";
echo 'Борис: ', $reviewers[$boris], "\n";
Ожидаемый результат
После объединения: 2
Анна: ночная смена
Борис: резерв

addAll переносит пары object→info. Совпавшая идентичность $anna не дублируется: её info заменено значением из входного хранилища. Возврат — итоговое число объектов, а не число новых вставок.

Скачать самостоятельный пример с результатом и README

Исключить заблокированных и оставить только допущенныхСамостоятельный пример
<?php
$a = (object) ['name' => 'A'];
$b = (object) ['name' => 'B'];
$c = (object) ['name' => 'C'];
$active = new SplObjectStorage();
$active[$a] = 'online';
$active[$b] = 'online';
$active[$c] = 'online';

$blocked = new SplObjectStorage();
$blocked[$b] = true;
echo 'После исключения: ', $active->removeAll($blocked), "\n";

$allowed = new SplObjectStorage();
$allowed[$c] = true;
echo 'После пересечения: ', $active->removeAllExcept($allowed), "\n";
echo 'Остался C: ', $active->offsetExists($c) ? 'да' : 'нет', "\n";
Ожидаемый результат
После исключения: 2
После пересечения: 1
Остался C: да

removeAll вычитает из active объекты, присутствующие в blocked, не сравнивая info. removeAllExcept оставляет пересечение с allowed. Оба метода возвращают итоговый размер изменённого хранилища. Они работают по идентичности объектов, не по полю name.

Скачать самостоятельный пример с результатом и README

Продолжение: SplObjectStorage::removeAll, SplObjectStorage::offsetSet.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplObjectStorage::attachДобавить object и info старым именем

PHP 5.1+; deprecated с PHP 8.5 · SPL

public function SplObjectStorage::attach(object $object, mixed $info = null): void

Добавить object и info старым именем. SplObjectStorage отделяет object-key от связанного info; операция использует идентичность объекта или результат переопределённого getHash.

ПараметрЧто означает в задаче
objectобъект-ключ
infoметаданные, по умолчанию null.
Часть контрактаЧто важно
Сигнатураpublic function SplObjectStorage::attach(object $object, mixed $info = null): void
Результатvoid.
Ошибки и особые значенияE_DEPRECATED с PHP 8.5; TypeError для не-object.
ВерсииPHP 5.1+; deprecated с PHP 8.5
Увидеть предупреждения старых имён PHP 8.5Самостоятельный пример
<?php
$deprecated = [];
set_error_handler(function (int $severity, string $message) use (&$deprecated): bool {
    if ($severity === E_DEPRECATED) {
        $deprecated[] = true;
        return true;
    }
    return false;
});
$object = (object) ['id' => 1];
$storage = new SplObjectStorage();
$storage->attach($object, 'ready');
echo 'contains: ', $storage->contains($object) ? 'да' : 'нет', "\n";
$storage->detach($object);
restore_error_handler();

echo 'Deprecated-вызовов: ', count($deprecated), "\n";
echo 'Осталось: ', $storage->count(), "\n";
Ожидаемый результат
contains: да
Deprecated-вызовов: 3
Осталось: 0

В PHP 8.5 attach, contains и detach работают как aliases, но каждый выдаёт E_DEPRECATED. Обработчик считает диагностики, не скрывая другой тип ошибки. Новый код использует offsetSet/offsetExists/offsetUnset или синтаксис квадратных скобок. На PHP 8.4 и старше предупреждений ещё нет.

Скачать самостоятельный пример с результатом и README

Выполнить тот же жизненный цикл современными методамиСамостоятельный пример
<?php
$session = (object) ['id' => 's-17'];
$active = new SplObjectStorage();
$active->offsetSet($session, ['user' => 42]);
echo 'Добавлена: ', $active->offsetExists($session) ? 'да' : 'нет', "\n";
echo 'Пользователь: ', $active->offsetGet($session)['user'], "\n";
$active->offsetUnset($session);
echo 'После удаления: ', $active->offsetExists($session) ? 'да' : 'нет', "\n";
Ожидаемый результат
Добавлена: да
Пользователь: 42
После удаления: нет

Это замена трём deprecated aliases без изменения смысла. Пара object→info появляется, читается и удаляется. Все методы требуют именно object; строковый session ID сам по себе ключом SplObjectStorage быть не может — для него подходит обычный array или Map-структура приложения.

Скачать самостоятельный пример с результатом и README

Продолжение: SplObjectStorage::offsetSet, SplObjectStorage::contains.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplObjectStorage::containsПроверить object старым именем

PHP 5.1+; deprecated с PHP 8.5 · SPL

public function SplObjectStorage::contains(object $object): bool

Проверить object старым именем. SplObjectStorage отделяет object-key от связанного info; операция использует идентичность объекта или результат переопределённого getHash.

ПараметрЧто означает в задаче
objectпроверяемый экземпляр.
Часть контрактаЧто важно
Сигнатураpublic function SplObjectStorage::contains(object $object): bool
Результатbool.
Ошибки и особые значенияE_DEPRECATED с PHP 8.5; TypeError для не-object.
ВерсииPHP 5.1+; deprecated с PHP 8.5
Увидеть предупреждения старых имён PHP 8.5Самостоятельный пример
<?php
$deprecated = [];
set_error_handler(function (int $severity, string $message) use (&$deprecated): bool {
    if ($severity === E_DEPRECATED) {
        $deprecated[] = true;
        return true;
    }
    return false;
});
$object = (object) ['id' => 1];
$storage = new SplObjectStorage();
$storage->attach($object, 'ready');
echo 'contains: ', $storage->contains($object) ? 'да' : 'нет', "\n";
$storage->detach($object);
restore_error_handler();

echo 'Deprecated-вызовов: ', count($deprecated), "\n";
echo 'Осталось: ', $storage->count(), "\n";
Ожидаемый результат
contains: да
Deprecated-вызовов: 3
Осталось: 0

В PHP 8.5 attach, contains и detach работают как aliases, но каждый выдаёт E_DEPRECATED. Обработчик считает диагностики, не скрывая другой тип ошибки. Новый код использует offsetSet/offsetExists/offsetUnset или синтаксис квадратных скобок. На PHP 8.4 и старше предупреждений ещё нет.

Скачать самостоятельный пример с результатом и README

Связать состояние обработки с конкретными объектамиСамостоятельный пример
<?php
class Document {
    public function __construct(public string $number) {}
}

$first = new Document('A-17');
$second = new Document('A-17');
$states = new SplObjectStorage();
$states[$first] = 'проверен';
$states[$second] = 'ожидает';

echo 'Объектов: ', $states->count(), "\n";
echo 'Первый: ', $states[$first], "\n";
echo 'Второй: ', $states[$second], "\n";
Ожидаемый результат
Объектов: 2
Первый: проверен
Второй: ожидает

Одинаковое поле number не делает два экземпляра одним ключом. SplObjectStorage сопоставляет info конкретной идентичности объекта. Запись $states[$first] = ... вызывает offsetSet; чтение — offsetGet. Это удобно для временной метаинформации, которую не надо добавлять в сам Document.

Скачать самостоятельный пример с результатом и README

Продолжение: SplObjectStorage::offsetExists, SplObjectStorage::getHash.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplObjectStorage::countПосчитать object-ключи

PHP 5.1+ · SPL

public function SplObjectStorage::count(int $mode = COUNT_NORMAL): int

Посчитать object-ключи. SplObjectStorage отделяет object-key от связанного info; операция использует идентичность объекта или результат переопределённого getHash.

ПараметрЧто означает в задаче
modeCOUNT_NORMAL или COUNT_RECURSIVE.
Часть контрактаЧто важно
Сигнатураpublic function SplObjectStorage::count(int $mode = COUNT_NORMAL): int
Результатint: число записей storage.
Ошибки и особые значенияНеверный тип mode — TypeError.
ВерсииPHP 5.1+
Понять границу COUNT_RECURSIVEСамостоятельный пример
<?php
$one = (object) ['id' => 1];
$two = (object) ['id' => 2];
$storage = new SplObjectStorage();
$storage[$one] = ['tags' => ['new', 'paid']];
$storage[$two] = null;

echo 'Обычный: ', $storage->count(), "\n";
echo 'COUNT_RECURSIVE: ', $storage->count(COUNT_RECURSIVE), "\n";
echo 'Теги первого: ', count($storage[$one]['tags']), "\n";
Ожидаемый результат
Обычный: 2
COUNT_RECURSIVE: 2
Теги первого: 2

Оба режима PHP 8.5 считают записи SplObjectStorage и не спускаются в произвольный массив info. Поэтому теги считаются отдельно. Не используйте COUNT_RECURSIVE как обещание подсчёта бизнес-графа; официальный краткий текст «recursively count the storage» не описывает это ограничение достаточно ясно.

Скачать самостоятельный пример с результатом и README

Связать состояние обработки с конкретными объектамиСамостоятельный пример
<?php
class Document {
    public function __construct(public string $number) {}
}

$first = new Document('A-17');
$second = new Document('A-17');
$states = new SplObjectStorage();
$states[$first] = 'проверен';
$states[$second] = 'ожидает';

echo 'Объектов: ', $states->count(), "\n";
echo 'Первый: ', $states[$first], "\n";
echo 'Второй: ', $states[$second], "\n";
Ожидаемый результат
Объектов: 2
Первый: проверен
Второй: ожидает

Одинаковое поле number не делает два экземпляра одним ключом. SplObjectStorage сопоставляет info конкретной идентичности объекта. Запись $states[$first] = ... вызывает offsetSet; чтение — offsetGet. Это удобно для временной метаинформации, которую не надо добавлять в сам Document.

Скачать самостоятельный пример с результатом и README

Продолжение: SplObjectStorage::addAll, SplObjectStorage::valid.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplObjectStorage::currentПолучить object текущей позиции

PHP 5.1+ · SPL

public function SplObjectStorage::current(): object

Получить object текущей позиции. SplObjectStorage отделяет object-key от связанного info; операция использует идентичность объекта или результат переопределённого getHash.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplObjectStorage::current(): object
Результатobject.
Ошибки и особые значенияНедействительная позиция — RuntimeException в PHP 8.5; официальная страница всё ещё говорит Error.
ВерсииPHP 5.1+
Пройти объекты и их метаданные вручнуюСамостоятельный пример
<?php
class Task {
    public function __construct(public string $name) {}
}
$build = new Task('Сборка');
$test = new Task('Тесты');
$states = new SplObjectStorage();
$states[$build] = 'done';
$states[$test] = 'waiting';

$states->rewind();
while ($states->valid()) {
    $position = $states->key();
    $task = $states->current();
    $info = $states->getInfo();
    echo $position, ': ', $task->name, ' — ', $info, "\n";
    $states->next();
}
Ожидаемый результат
0: Сборка — done
1: Тесты — waiting

rewind ставит итератор на первую запись. valid разрешает current/getInfo/key. current возвращает объект-ключ, getInfo — связанную метаинформацию, key — позицию обхода 0,1… . next переводит к следующей записи. Позиция не является ID объекта.

Скачать самостоятельный пример с результатом и README

Не читать current после конца обходаСамостоятельный пример
<?php
$storage = new SplObjectStorage();
$object = (object) ['id' => 7];
$storage[$object] = 'ready';
$storage->rewind();
$storage->next();

echo 'Позиция действительна: ', $storage->valid() ? 'да' : 'нет', "\n";
try {
    $storage->current();
} catch (RuntimeException $error) {
    echo "current() остановлен на недействительной позиции\n";
}
Ожидаемый результат
Позиция действительна: нет
current() остановлен на недействительной позиции

После единственного next итератор находится за последней записью. PHP 8.5 выбрасывает RuntimeException. Официальная страница current всё ещё указывает Error с PHP 8.1; пример фиксирует поведение текущего исходника и runtime. Надёжный цикл всегда вызывает current только после valid().

Скачать самостоятельный пример с результатом и README

Продолжение: SplObjectStorage::getInfo, SplObjectStorage::valid.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplObjectStorage::detachУдалить object старым именем

PHP 5.1+; deprecated с PHP 8.5 · SPL

public function SplObjectStorage::detach(object $object): void

Удалить object старым именем. SplObjectStorage отделяет object-key от связанного info; операция использует идентичность объекта или результат переопределённого getHash.

ПараметрЧто означает в задаче
objectудаляемый экземпляр.
Часть контрактаЧто важно
Сигнатураpublic function SplObjectStorage::detach(object $object): void
Результатvoid.
Ошибки и особые значенияE_DEPRECATED с PHP 8.5; TypeError для не-object.
ВерсииPHP 5.1+; deprecated с PHP 8.5
Увидеть предупреждения старых имён PHP 8.5Самостоятельный пример
<?php
$deprecated = [];
set_error_handler(function (int $severity, string $message) use (&$deprecated): bool {
    if ($severity === E_DEPRECATED) {
        $deprecated[] = true;
        return true;
    }
    return false;
});
$object = (object) ['id' => 1];
$storage = new SplObjectStorage();
$storage->attach($object, 'ready');
echo 'contains: ', $storage->contains($object) ? 'да' : 'нет', "\n";
$storage->detach($object);
restore_error_handler();

echo 'Deprecated-вызовов: ', count($deprecated), "\n";
echo 'Осталось: ', $storage->count(), "\n";
Ожидаемый результат
contains: да
Deprecated-вызовов: 3
Осталось: 0

В PHP 8.5 attach, contains и detach работают как aliases, но каждый выдаёт E_DEPRECATED. Обработчик считает диагностики, не скрывая другой тип ошибки. Новый код использует offsetSet/offsetExists/offsetUnset или синтаксис квадратных скобок. На PHP 8.4 и старше предупреждений ещё нет.

Скачать самостоятельный пример с результатом и README

Выполнить тот же жизненный цикл современными методамиСамостоятельный пример
<?php
$session = (object) ['id' => 's-17'];
$active = new SplObjectStorage();
$active->offsetSet($session, ['user' => 42]);
echo 'Добавлена: ', $active->offsetExists($session) ? 'да' : 'нет', "\n";
echo 'Пользователь: ', $active->offsetGet($session)['user'], "\n";
$active->offsetUnset($session);
echo 'После удаления: ', $active->offsetExists($session) ? 'да' : 'нет', "\n";
Ожидаемый результат
Добавлена: да
Пользователь: 42
После удаления: нет

Это замена трём deprecated aliases без изменения смысла. Пара object→info появляется, читается и удаляется. Все методы требуют именно object; строковый session ID сам по себе ключом SplObjectStorage быть не может — для него подходит обычный array или Map-структура приложения.

Скачать самостоятельный пример с результатом и README

Продолжение: SplObjectStorage::offsetUnset, SplObjectStorage::contains.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplObjectStorage::getHashПолучить технический hash по правилу storage

PHP 5.4+ · SPL

public function SplObjectStorage::getHash(object $object): string

Получить технический hash по правилу storage. SplObjectStorage отделяет object-key от связанного info; операция использует идентичность объекта или результат переопределённого getHash.

ПараметрЧто означает в задаче
objectэкземпляр.
Часть контрактаЧто важно
Сигнатураpublic function SplObjectStorage::getHash(object $object): string
Результатstring.
Ошибки и особые значенияПереопределение, вернувшее не-string, вызывает RuntimeException.
ВерсииPHP 5.4+
Сравнить идентификаторы, не раскрывая их случайные значенияСамостоятельный пример
<?php
$storage = new SplObjectStorage();
$first = (object) ['id' => 10];
$second = (object) ['id' => 10];

$firstHash = $storage->getHash($first);
echo 'Повтор стабилен: ', $firstHash === $storage->getHash($first) ? 'да' : 'нет', "\n";
echo 'Другой объект отличен: ', $firstHash !== $storage->getHash($second) ? 'да' : 'нет', "\n";
Ожидаемый результат
Повтор стабилен: да
Другой объект отличен: да

Стандартный getHash эквивалентен spl_object_hash для текущего процесса. Сам текст хеша намеренно не выводится: это техническая идентичность, не постоянный ID базы, не токен и не значение для хранения между запросами.

Скачать самостоятельный пример с результатом и README

Показать последствия предметного getHash и коллизииСамостоятельный пример
<?php
class ByExternalIdStorage extends SplObjectStorage {
    public function getHash(object $object): string {
        return (string) $object->externalId;
    }
}
$first = (object) ['externalId' => 7, 'name' => 'Старый'];
$second = (object) ['externalId' => 7, 'name' => 'Новый'];
$storage = new ByExternalIdStorage();
$storage[$first] = 'первая запись';
$storage[$second] = 'вторая запись';

echo 'Объектов: ', $storage->count(), "\n";
echo 'Info через первый: ', $storage[$first], "\n";
echo 'Info через второй: ', $storage[$second], "\n";
Ожидаемый результат
Объектов: 1
Info через первый: вторая запись
Info через второй: вторая запись

Переопределённый getHash объявил объекты с одинаковым externalId одним ключом. Вторая запись заменила info первой. Это может быть осознанной предметной семантикой, но коллизия означает потерю различия экземпляров. Возвращаемое значение обязано быть string, стабильным и уникальным по выбранному правилу.

Скачать самостоятельный пример с результатом и README

Продолжение: SplObjectStorage::offsetExists, SplObjectStorage::offsetSet.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplObjectStorage::getInfoПолучить info текущего object

PHP 5.3+ · SPL

public function SplObjectStorage::getInfo(): mixed

Получить info текущего object. SplObjectStorage отделяет object-key от связанного info; операция использует идентичность объекта или результат переопределённого getHash.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplObjectStorage::getInfo(): mixed
Результатmixed: связанное значение, включая null.
Ошибки и особые значенияНедействительная позиция вызывает RuntimeException.
ВерсииPHP 5.3+
Пройти объекты и их метаданные вручнуюСамостоятельный пример
<?php
class Task {
    public function __construct(public string $name) {}
}
$build = new Task('Сборка');
$test = new Task('Тесты');
$states = new SplObjectStorage();
$states[$build] = 'done';
$states[$test] = 'waiting';

$states->rewind();
while ($states->valid()) {
    $position = $states->key();
    $task = $states->current();
    $info = $states->getInfo();
    echo $position, ': ', $task->name, ' — ', $info, "\n";
    $states->next();
}
Ожидаемый результат
0: Сборка — done
1: Тесты — waiting

rewind ставит итератор на первую запись. valid разрешает current/getInfo/key. current возвращает объект-ключ, getInfo — связанную метаинформацию, key — позицию обхода 0,1… . next переводит к следующей записи. Позиция не является ID объекта.

Скачать самостоятельный пример с результатом и README

Обновить info текущей записи во время обходаСамостоятельный пример
<?php
$a = (object) ['name' => 'Изображение'];
$b = (object) ['name' => 'PDF'];
$files = new SplObjectStorage();
$files[$a] = 'queued';
$files[$b] = 'queued';

$files->rewind();
while ($files->valid()) {
    echo $files->current()->name, ': ', $files->getInfo(), ' → done', "\n";
    $files->setInfo('done');
    $files->next();
}
echo 'Итог PDF: ', $files[$b], "\n";
Ожидаемый результат
Изображение: queued → done
PDF: queued → done
Итог PDF: done

setInfo меняет info только объекта в текущей позиции итератора. current нужен для имени, getInfo читает старое состояние. После next текущей становится другая запись. Для обновления конкретного известного объекта проще $files[$b] = ... .

Скачать самостоятельный пример с результатом и README

Продолжение: SplObjectStorage::current, SplObjectStorage::setInfo.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplObjectStorage::keyПолучить позицию обхода

PHP 5.1+ · SPL

public function SplObjectStorage::key(): int

Получить позицию обхода. SplObjectStorage отделяет object-key от связанного info; операция использует идентичность объекта или результат переопределённого getHash.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplObjectStorage::key(): int
Результатint: 0,1,… для текущей позиции.
Ошибки и особые значенияНедействительная позиция не даёт бизнес-ключа.
ВерсииPHP 5.1+
Пройти объекты и их метаданные вручнуюСамостоятельный пример
<?php
class Task {
    public function __construct(public string $name) {}
}
$build = new Task('Сборка');
$test = new Task('Тесты');
$states = new SplObjectStorage();
$states[$build] = 'done';
$states[$test] = 'waiting';

$states->rewind();
while ($states->valid()) {
    $position = $states->key();
    $task = $states->current();
    $info = $states->getInfo();
    echo $position, ': ', $task->name, ' — ', $info, "\n";
    $states->next();
}
Ожидаемый результат
0: Сборка — done
1: Тесты — waiting

rewind ставит итератор на первую запись. valid разрешает current/getInfo/key. current возвращает объект-ключ, getInfo — связанную метаинформацию, key — позицию обхода 0,1… . next переводит к следующей записи. Позиция не является ID объекта.

Скачать самостоятельный пример с результатом и README

Перейти к позиции и обработать выход за границыСамостоятельный пример
<?php
$storage = new SplObjectStorage();
foreach (['A', 'B', 'C'] as $name) {
    $object = (object) ['name' => $name];
    $storage[$object] = 'item-' . $name;
}

$storage->seek(1);
echo 'Позиция ', $storage->key(), ': ', $storage->current()->name, "\n";
try {
    $storage->seek(5);
} catch (OutOfBoundsException $error) {
    echo "Позиции 5 нет\n";
}
Ожидаемый результат
Позиция 1: B
Позиции 5 нет

seek(1) выбирает вторую позицию итератора, потому что отсчёт начинается с нуля. seek(5) вне трёх элементов выбрасывает OutOfBoundsException. Метод доступен с PHP 8.4 и предназначен для позиции обхода, не для поиска бизнес-ID.

Скачать самостоятельный пример с результатом и README

Продолжение: SplObjectStorage::current, SplObjectStorage::seek.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplObjectStorage::nextПерейти к следующей записи

PHP 5.1+ · SPL

public function SplObjectStorage::next(): void

Перейти к следующей записи. SplObjectStorage отделяет object-key от связанного info; операция использует идентичность объекта или результат переопределённого getHash.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplObjectStorage::next(): void
Результатvoid.
Ошибки и особые значенияПосле конца current/getInfo недопустимы.
ВерсииPHP 5.1+
Пройти объекты и их метаданные вручнуюСамостоятельный пример
<?php
class Task {
    public function __construct(public string $name) {}
}
$build = new Task('Сборка');
$test = new Task('Тесты');
$states = new SplObjectStorage();
$states[$build] = 'done';
$states[$test] = 'waiting';

$states->rewind();
while ($states->valid()) {
    $position = $states->key();
    $task = $states->current();
    $info = $states->getInfo();
    echo $position, ': ', $task->name, ' — ', $info, "\n";
    $states->next();
}
Ожидаемый результат
0: Сборка — done
1: Тесты — waiting

rewind ставит итератор на первую запись. valid разрешает current/getInfo/key. current возвращает объект-ключ, getInfo — связанную метаинформацию, key — позицию обхода 0,1… . next переводит к следующей записи. Позиция не является ID объекта.

Скачать самостоятельный пример с результатом и README

Не читать current после конца обходаСамостоятельный пример
<?php
$storage = new SplObjectStorage();
$object = (object) ['id' => 7];
$storage[$object] = 'ready';
$storage->rewind();
$storage->next();

echo 'Позиция действительна: ', $storage->valid() ? 'да' : 'нет', "\n";
try {
    $storage->current();
} catch (RuntimeException $error) {
    echo "current() остановлен на недействительной позиции\n";
}
Ожидаемый результат
Позиция действительна: нет
current() остановлен на недействительной позиции

После единственного next итератор находится за последней записью. PHP 8.5 выбрасывает RuntimeException. Официальная страница current всё ещё указывает Error с PHP 8.1; пример фиксирует поведение текущего исходника и runtime. Надёжный цикл всегда вызывает current только после valid().

Скачать самостоятельный пример с результатом и README

Продолжение: SplObjectStorage::valid, SplObjectStorage::rewind.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplObjectStorage::offsetExistsПроверить наличие конкретного object

PHP 5.1+ · SPL

public function SplObjectStorage::offsetExists(object $object): bool

Проверить наличие конкретного object. SplObjectStorage отделяет object-key от связанного info; операция использует идентичность объекта или результат переопределённого getHash.

ПараметрЧто означает в задаче
objectпроверяемый экземпляр.
Часть контрактаЧто важно
Сигнатураpublic function SplObjectStorage::offsetExists(object $object): bool
Результатbool; info=null всё равно даёт true.
Ошибки и особые значенияTypeError для не-object.
ВерсииPHP 5.1+
Отличить объект с null-метаданными от отсутствующегоСамостоятельный пример
<?php
$known = (object) ['id' => 1];
$unknown = (object) ['id' => 2];
$storage = new SplObjectStorage();
$storage[$known] = null;

echo 'Известный: ', $storage->offsetExists($known) ? 'да' : 'нет', "\n";
echo 'Его info: ', $storage[$known] === null ? 'NULL' : 'значение', "\n";
echo 'Неизвестный: ', $storage->offsetExists($unknown) ? 'да' : 'нет', "\n";
try {
    $storage->offsetGet($unknown);
} catch (UnexpectedValueException $error) {
    echo "Чтение отсутствующего остановлено\n";
}
Ожидаемый результат
Известный: да
Его info: NULL
Неизвестный: нет
Чтение отсутствующего остановлено

Здесь offsetExists проверяет присутствие самого объекта, а не значение info: null остаётся допустимой метаинформацией. offsetGet неизвестного объекта выбрасывает UnexpectedValueException, поэтому сначала проверяется наличие или исключение обрабатывается как ожидаемый отказ.

Скачать самостоятельный пример с результатом и README

Выполнить тот же жизненный цикл современными методамиСамостоятельный пример
<?php
$session = (object) ['id' => 's-17'];
$active = new SplObjectStorage();
$active->offsetSet($session, ['user' => 42]);
echo 'Добавлена: ', $active->offsetExists($session) ? 'да' : 'нет', "\n";
echo 'Пользователь: ', $active->offsetGet($session)['user'], "\n";
$active->offsetUnset($session);
echo 'После удаления: ', $active->offsetExists($session) ? 'да' : 'нет', "\n";
Ожидаемый результат
Добавлена: да
Пользователь: 42
После удаления: нет

Это замена трём deprecated aliases без изменения смысла. Пара object→info появляется, читается и удаляется. Все методы требуют именно object; строковый session ID сам по себе ключом SplObjectStorage быть не может — для него подходит обычный array или Map-структура приложения.

Скачать самостоятельный пример с результатом и README

Продолжение: SplObjectStorage::offsetGet, SplObjectStorage::getHash.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplObjectStorage::offsetGetПолучить info по object

PHP 5.1+ · SPL

public function SplObjectStorage::offsetGet(object $object): mixed

Получить info по object. SplObjectStorage отделяет object-key от связанного info; операция использует идентичность объекта или результат переопределённого getHash.

ПараметрЧто означает в задаче
objectсуществующий объект-ключ.
Часть контрактаЧто важно
Сигнатураpublic function SplObjectStorage::offsetGet(object $object): mixed
Результатmixed, включая null.
Ошибки и особые значенияНеизвестный object — UnexpectedValueException; не-object — TypeError.
ВерсииPHP 5.1+
Отличить объект с null-метаданными от отсутствующегоСамостоятельный пример
<?php
$known = (object) ['id' => 1];
$unknown = (object) ['id' => 2];
$storage = new SplObjectStorage();
$storage[$known] = null;

echo 'Известный: ', $storage->offsetExists($known) ? 'да' : 'нет', "\n";
echo 'Его info: ', $storage[$known] === null ? 'NULL' : 'значение', "\n";
echo 'Неизвестный: ', $storage->offsetExists($unknown) ? 'да' : 'нет', "\n";
try {
    $storage->offsetGet($unknown);
} catch (UnexpectedValueException $error) {
    echo "Чтение отсутствующего остановлено\n";
}
Ожидаемый результат
Известный: да
Его info: NULL
Неизвестный: нет
Чтение отсутствующего остановлено

Здесь offsetExists проверяет присутствие самого объекта, а не значение info: null остаётся допустимой метаинформацией. offsetGet неизвестного объекта выбрасывает UnexpectedValueException, поэтому сначала проверяется наличие или исключение обрабатывается как ожидаемый отказ.

Скачать самостоятельный пример с результатом и README

Обновить массив метаданных через read–modify–writeСамостоятельный пример
<?php
$job = (object) ['id' => 42];
$states = new SplObjectStorage();
$states[$job] = ['attempt' => 1, 'status' => 'queued'];

$info = $states[$job];
$info['attempt']++;
$info['status'] = 'sent';
$states[$job] = $info;

echo 'Попытка: ', $states[$job]['attempt'], "\n";
echo 'Статус: ', $states[$job]['status'], "\n";
Ожидаемый результат
Попытка: 2
Статус: sent

offsetGet возвращает metadata по значению. Поэтому массив сначала читается в $info, изменяется и целиком записывается обратно. Выражение $states[$job]["attempt"]++ пытается косвенно менять временный результат и не является надёжным обновлением хранилища.

Скачать самостоятельный пример с результатом и README

Продолжение: SplObjectStorage::offsetExists, SplObjectStorage::offsetSet.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplObjectStorage::offsetSetДобавить object или заменить его info

PHP 5.1+ · SPL

public function SplObjectStorage::offsetSet(object $object, mixed $info = null): void

Добавить object или заменить его info. SplObjectStorage отделяет object-key от связанного info; операция использует идентичность объекта или результат переопределённого getHash.

ПараметрЧто означает в задаче
objectобъект-ключ
infoметаданные, по умолчанию null.
Часть контрактаЧто важно
Сигнатураpublic function SplObjectStorage::offsetSet(object $object, mixed $info = null): void
Результатvoid.
Ошибки и особые значенияTypeError для не-object.
ВерсииPHP 5.1+
Связать состояние обработки с конкретными объектамиСамостоятельный пример
<?php
class Document {
    public function __construct(public string $number) {}
}

$first = new Document('A-17');
$second = new Document('A-17');
$states = new SplObjectStorage();
$states[$first] = 'проверен';
$states[$second] = 'ожидает';

echo 'Объектов: ', $states->count(), "\n";
echo 'Первый: ', $states[$first], "\n";
echo 'Второй: ', $states[$second], "\n";
Ожидаемый результат
Объектов: 2
Первый: проверен
Второй: ожидает

Одинаковое поле number не делает два экземпляра одним ключом. SplObjectStorage сопоставляет info конкретной идентичности объекта. Запись $states[$first] = ... вызывает offsetSet; чтение — offsetGet. Это удобно для временной метаинформации, которую не надо добавлять в сам Document.

Скачать самостоятельный пример с результатом и README

Выполнить тот же жизненный цикл современными методамиСамостоятельный пример
<?php
$session = (object) ['id' => 's-17'];
$active = new SplObjectStorage();
$active->offsetSet($session, ['user' => 42]);
echo 'Добавлена: ', $active->offsetExists($session) ? 'да' : 'нет', "\n";
echo 'Пользователь: ', $active->offsetGet($session)['user'], "\n";
$active->offsetUnset($session);
echo 'После удаления: ', $active->offsetExists($session) ? 'да' : 'нет', "\n";
Ожидаемый результат
Добавлена: да
Пользователь: 42
После удаления: нет

Это замена трём deprecated aliases без изменения смысла. Пара object→info появляется, читается и удаляется. Все методы требуют именно object; строковый session ID сам по себе ключом SplObjectStorage быть не может — для него подходит обычный array или Map-структура приложения.

Скачать самостоятельный пример с результатом и README

Продолжение: SplObjectStorage::offsetGet, SplObjectStorage::offsetUnset.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplObjectStorage::offsetUnsetУдалить object и его info

PHP 5.1+ · SPL

public function SplObjectStorage::offsetUnset(object $object): void

Удалить object и его info. SplObjectStorage отделяет object-key от связанного info; операция использует идентичность объекта или результат переопределённого getHash.

ПараметрЧто означает в задаче
objectудаляемый экземпляр.
Часть контрактаЧто важно
Сигнатураpublic function SplObjectStorage::offsetUnset(object $object): void
Результатvoid.
Ошибки и особые значенияTypeError для не-object.
ВерсииPHP 5.1+
Выполнить тот же жизненный цикл современными методамиСамостоятельный пример
<?php
$session = (object) ['id' => 's-17'];
$active = new SplObjectStorage();
$active->offsetSet($session, ['user' => 42]);
echo 'Добавлена: ', $active->offsetExists($session) ? 'да' : 'нет', "\n";
echo 'Пользователь: ', $active->offsetGet($session)['user'], "\n";
$active->offsetUnset($session);
echo 'После удаления: ', $active->offsetExists($session) ? 'да' : 'нет', "\n";
Ожидаемый результат
Добавлена: да
Пользователь: 42
После удаления: нет

Это замена трём deprecated aliases без изменения смысла. Пара object→info появляется, читается и удаляется. Все методы требуют именно object; строковый session ID сам по себе ключом SplObjectStorage быть не может — для него подходит обычный array или Map-структура приложения.

Скачать самостоятельный пример с результатом и README

Увидеть, что хранилище удерживает объект живымСамостоятельный пример
<?php
$storage = new SplObjectStorage();
$object = (object) ['id' => 5];
$weak = WeakReference::create($object);
$storage[$object] = 'held';
unset($object);
gc_collect_cycles();
echo 'Пока в storage: ', $weak->get() !== null ? 'жив' : 'удалён', "\n";

$storage->rewind();
$held = $storage->current();
$storage->offsetUnset($held);
unset($held);
gc_collect_cycles();
echo 'После удаления: ', $weak->get() !== null ? 'жив' : 'удалён', "\n";
Ожидаемый результат
Пока в storage: жив
После удаления: удалён

SplObjectStorage хранит сильную ссылку на object-key, поэтому unset внешней переменной не уничтожает объект. После offsetUnset и удаления временной $held сильных ссылок не остаётся, WeakReference возвращает null. Если таблица не должна продлевать жизнь объектов, рассмотрите WeakMap.

Скачать самостоятельный пример с результатом и README

Продолжение: SplObjectStorage::offsetExists, SplObjectStorage::removeAll.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplObjectStorage::removeAllВычесть объекты другого storage

PHP 5.3+ · SPL

public function SplObjectStorage::removeAll(SplObjectStorage $storage): int

Вычесть объекты другого storage. SplObjectStorage отделяет object-key от связанного info; операция использует идентичность объекта или результат переопределённого getHash.

ПараметрЧто означает в задаче
storageмножество объектов для удаления.
Часть контрактаЧто важно
Сигнатураpublic function SplObjectStorage::removeAll(SplObjectStorage $storage): int
Результатint: размер после удаления.
Ошибки и особые значенияTypeError для другого типа.
ВерсииPHP 5.3+
Исключить заблокированных и оставить только допущенныхСамостоятельный пример
<?php
$a = (object) ['name' => 'A'];
$b = (object) ['name' => 'B'];
$c = (object) ['name' => 'C'];
$active = new SplObjectStorage();
$active[$a] = 'online';
$active[$b] = 'online';
$active[$c] = 'online';

$blocked = new SplObjectStorage();
$blocked[$b] = true;
echo 'После исключения: ', $active->removeAll($blocked), "\n";

$allowed = new SplObjectStorage();
$allowed[$c] = true;
echo 'После пересечения: ', $active->removeAllExcept($allowed), "\n";
echo 'Остался C: ', $active->offsetExists($c) ? 'да' : 'нет', "\n";
Ожидаемый результат
После исключения: 2
После пересечения: 1
Остался C: да

removeAll вычитает из active объекты, присутствующие в blocked, не сравнивая info. removeAllExcept оставляет пересечение с allowed. Оба метода возвращают итоговый размер изменённого хранилища. Они работают по идентичности объектов, не по полю name.

Скачать самостоятельный пример с результатом и README

Объединить наборы и увидеть замену info совпавшего объектаСамостоятельный пример
<?php
$anna = (object) ['name' => 'Анна'];
$boris = (object) ['name' => 'Борис'];
$reviewers = new SplObjectStorage();
$reviewers[$anna] = 'основной';

$nightShift = new SplObjectStorage();
$nightShift[$anna] = 'ночная смена';
$nightShift[$boris] = 'резерв';

$count = $reviewers->addAll($nightShift);
echo 'После объединения: ', $count, "\n";
echo 'Анна: ', $reviewers[$anna], "\n";
echo 'Борис: ', $reviewers[$boris], "\n";
Ожидаемый результат
После объединения: 2
Анна: ночная смена
Борис: резерв

addAll переносит пары object→info. Совпавшая идентичность $anna не дублируется: её info заменено значением из входного хранилища. Возврат — итоговое число объектов, а не число новых вставок.

Скачать самостоятельный пример с результатом и README

Продолжение: SplObjectStorage::removeAllExcept, SplObjectStorage::addAll.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplObjectStorage::removeAllExceptОставить пересечение с другим storage

PHP 5.3.6+ · SPL

public function SplObjectStorage::removeAllExcept(SplObjectStorage $storage): int

Оставить пересечение с другим storage. SplObjectStorage отделяет object-key от связанного info; операция использует идентичность объекта или результат переопределённого getHash.

ПараметрЧто означает в задаче
storageмножество объектов, которые разрешено сохранить.
Часть контрактаЧто важно
Сигнатураpublic function SplObjectStorage::removeAllExcept(SplObjectStorage $storage): int
Результатint: размер после фильтра.
Ошибки и особые значенияTypeError для другого типа.
ВерсииPHP 5.3.6+
Исключить заблокированных и оставить только допущенныхСамостоятельный пример
<?php
$a = (object) ['name' => 'A'];
$b = (object) ['name' => 'B'];
$c = (object) ['name' => 'C'];
$active = new SplObjectStorage();
$active[$a] = 'online';
$active[$b] = 'online';
$active[$c] = 'online';

$blocked = new SplObjectStorage();
$blocked[$b] = true;
echo 'После исключения: ', $active->removeAll($blocked), "\n";

$allowed = new SplObjectStorage();
$allowed[$c] = true;
echo 'После пересечения: ', $active->removeAllExcept($allowed), "\n";
echo 'Остался C: ', $active->offsetExists($c) ? 'да' : 'нет', "\n";
Ожидаемый результат
После исключения: 2
После пересечения: 1
Остался C: да

removeAll вычитает из active объекты, присутствующие в blocked, не сравнивая info. removeAllExcept оставляет пересечение с allowed. Оба метода возвращают итоговый размер изменённого хранилища. Они работают по идентичности объектов, не по полю name.

Скачать самостоятельный пример с результатом и README

Объединить наборы и увидеть замену info совпавшего объектаСамостоятельный пример
<?php
$anna = (object) ['name' => 'Анна'];
$boris = (object) ['name' => 'Борис'];
$reviewers = new SplObjectStorage();
$reviewers[$anna] = 'основной';

$nightShift = new SplObjectStorage();
$nightShift[$anna] = 'ночная смена';
$nightShift[$boris] = 'резерв';

$count = $reviewers->addAll($nightShift);
echo 'После объединения: ', $count, "\n";
echo 'Анна: ', $reviewers[$anna], "\n";
echo 'Борис: ', $reviewers[$boris], "\n";
Ожидаемый результат
После объединения: 2
Анна: ночная смена
Борис: резерв

addAll переносит пары object→info. Совпавшая идентичность $anna не дублируется: её info заменено значением из входного хранилища. Возврат — итоговое число объектов, а не число новых вставок.

Скачать самостоятельный пример с результатом и README

Продолжение: SplObjectStorage::removeAll, SplObjectStorage::offsetExists.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplObjectStorage::rewindВернуть итератор к первой записи

PHP 5.1+ · SPL

public function SplObjectStorage::rewind(): void

Вернуть итератор к первой записи. SplObjectStorage отделяет object-key от связанного info; операция использует идентичность объекта или результат переопределённого getHash.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplObjectStorage::rewind(): void
Результатvoid.
Ошибки и особые значенияПустой storage остаётся с valid=false.
ВерсииPHP 5.1+
Пройти объекты и их метаданные вручнуюСамостоятельный пример
<?php
class Task {
    public function __construct(public string $name) {}
}
$build = new Task('Сборка');
$test = new Task('Тесты');
$states = new SplObjectStorage();
$states[$build] = 'done';
$states[$test] = 'waiting';

$states->rewind();
while ($states->valid()) {
    $position = $states->key();
    $task = $states->current();
    $info = $states->getInfo();
    echo $position, ': ', $task->name, ' — ', $info, "\n";
    $states->next();
}
Ожидаемый результат
0: Сборка — done
1: Тесты — waiting

rewind ставит итератор на первую запись. valid разрешает current/getInfo/key. current возвращает объект-ключ, getInfo — связанную метаинформацию, key — позицию обхода 0,1… . next переводит к следующей записи. Позиция не является ID объекта.

Скачать самостоятельный пример с результатом и README

Обновить info текущей записи во время обходаСамостоятельный пример
<?php
$a = (object) ['name' => 'Изображение'];
$b = (object) ['name' => 'PDF'];
$files = new SplObjectStorage();
$files[$a] = 'queued';
$files[$b] = 'queued';

$files->rewind();
while ($files->valid()) {
    echo $files->current()->name, ': ', $files->getInfo(), ' → done', "\n";
    $files->setInfo('done');
    $files->next();
}
echo 'Итог PDF: ', $files[$b], "\n";
Ожидаемый результат
Изображение: queued → done
PDF: queued → done
Итог PDF: done

setInfo меняет info только объекта в текущей позиции итератора. current нужен для имени, getInfo читает старое состояние. После next текущей становится другая запись. Для обновления конкретного известного объекта проще $files[$b] = ... .

Скачать самостоятельный пример с результатом и README

Продолжение: SplObjectStorage::valid, SplObjectStorage::next.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplObjectStorage::seekПерейти к позиции итератора

PHP 8.4+ · SPL

public function SplObjectStorage::seek(int $offset): void

Перейти к позиции итератора. SplObjectStorage отделяет object-key от связанного info; операция использует идентичность объекта или результат переопределённого getHash.

ПараметрЧто означает в задаче
offsetпозиция от 0.
Часть контрактаЧто важно
Сигнатураpublic function SplObjectStorage::seek(int $offset): void
Результатvoid.
Ошибки и особые значенияOutOfBoundsException для недоступной позиции.
ВерсииPHP 8.4+
Перейти к позиции и обработать выход за границыСамостоятельный пример
<?php
$storage = new SplObjectStorage();
foreach (['A', 'B', 'C'] as $name) {
    $object = (object) ['name' => $name];
    $storage[$object] = 'item-' . $name;
}

$storage->seek(1);
echo 'Позиция ', $storage->key(), ': ', $storage->current()->name, "\n";
try {
    $storage->seek(5);
} catch (OutOfBoundsException $error) {
    echo "Позиции 5 нет\n";
}
Ожидаемый результат
Позиция 1: B
Позиции 5 нет

seek(1) выбирает вторую позицию итератора, потому что отсчёт начинается с нуля. seek(5) вне трёх элементов выбрасывает OutOfBoundsException. Метод доступен с PHP 8.4 и предназначен для позиции обхода, не для поиска бизнес-ID.

Скачать самостоятельный пример с результатом и README

Пройти объекты и их метаданные вручнуюСамостоятельный пример
<?php
class Task {
    public function __construct(public string $name) {}
}
$build = new Task('Сборка');
$test = new Task('Тесты');
$states = new SplObjectStorage();
$states[$build] = 'done';
$states[$test] = 'waiting';

$states->rewind();
while ($states->valid()) {
    $position = $states->key();
    $task = $states->current();
    $info = $states->getInfo();
    echo $position, ': ', $task->name, ' — ', $info, "\n";
    $states->next();
}
Ожидаемый результат
0: Сборка — done
1: Тесты — waiting

rewind ставит итератор на первую запись. valid разрешает current/getInfo/key. current возвращает объект-ключ, getInfo — связанную метаинформацию, key — позицию обхода 0,1… . next переводит к следующей записи. Позиция не является ID объекта.

Скачать самостоятельный пример с результатом и README

Продолжение: SplObjectStorage::key, SplObjectStorage::current.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplObjectStorage::serializeПолучить строку доверенного снимка

PHP 5.1+ · SPL

public function SplObjectStorage::serialize(): string

Получить строку доверенного снимка. SplObjectStorage отделяет object-key от связанного info; операция использует идентичность объекта или результат переопределённого getHash.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplObjectStorage::serialize(): string
Результатstring.
Ошибки и особые значенияНеподдерживаемое вложенное значение/состояние может завершить сериализацию ошибкой.
ВерсииPHP 5.1+
Восстановить доверенный снимок и заметить новую идентичностьСамостоятельный пример
<?php
class StoredJob {
    public function __construct(public int $id) {}
}
$original = new StoredJob(42);
$source = new SplObjectStorage();
$source[$original] = 'queued';
$payload = $source->serialize();

$restored = new SplObjectStorage();
$restored->unserialize($payload);
$restored->rewind();
echo 'Записей: ', $restored->count(), "\n";
echo 'Восстановлено: ', $restored->current()->id, '/', $restored->getInfo(), "\n";
echo 'Исходный экземпляр — ключ: ', $restored->offsetExists($original) ? 'да' : 'нет', "\n";
Ожидаемый результат
Записей: 1
Восстановлено: 42/queued
Исходный экземпляр — ключ: нет

После unserialize создан новый объект StoredJob со значением id=42. Он не тождествен $original, поэтому исходный экземпляр не является ключом restored. Это принципиально для identity-map. Строка допустима только из доверенного локального источника; десериализация неизвестных классов опасна.

Скачать самостоятельный пример с результатом и README

Сохранить доверенный локальный снимок в файлСамостоятельный пример
<?php
$path = __DIR__ . '/storage.cache';
$object = (object) ['name' => 'report'];
$source = new SplObjectStorage();
$source[$object] = ['status' => 'ready'];
file_put_contents($path, $source->serialize());

$payload = file_get_contents($path);
if ($payload === false) {
    throw new RuntimeException('Кеш не прочитан');
}
$loaded = new SplObjectStorage();
$loaded->unserialize($payload);
$loaded->rewind();
echo $loaded->current()->name, ': ', $loaded->getInfo()['status'], "\n";
unlink($path);
Ожидаемый результат
report: ready

Пример создаёт файл только в изолированной учебной папке, проверяет чтение и удаляет его. В производстве добавляют атомарную запись, контроль срока/версии и обработку повреждения. Для внешнего API лучше явные ID и JSON-схема, потому что PHP-сериализация восстанавливает объекты.

Скачать самостоятельный пример с результатом и README

Продолжение: SplObjectStorage::unserialize, SplObjectStorage::getHash.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplObjectStorage::setInfoЗаменить info текущей записи

PHP 5.3+ · SPL

public function SplObjectStorage::setInfo(mixed $info): void

Заменить info текущей записи. SplObjectStorage отделяет object-key от связанного info; операция использует идентичность объекта или результат переопределённого getHash.

ПараметрЧто означает в задаче
infoновое значение.
Часть контрактаЧто важно
Сигнатураpublic function SplObjectStorage::setInfo(mixed $info): void
Результатvoid.
Ошибки и особые значенияНедействительная позиция — RuntimeException.
ВерсииPHP 5.3+
Обновить info текущей записи во время обходаСамостоятельный пример
<?php
$a = (object) ['name' => 'Изображение'];
$b = (object) ['name' => 'PDF'];
$files = new SplObjectStorage();
$files[$a] = 'queued';
$files[$b] = 'queued';

$files->rewind();
while ($files->valid()) {
    echo $files->current()->name, ': ', $files->getInfo(), ' → done', "\n";
    $files->setInfo('done');
    $files->next();
}
echo 'Итог PDF: ', $files[$b], "\n";
Ожидаемый результат
Изображение: queued → done
PDF: queued → done
Итог PDF: done

setInfo меняет info только объекта в текущей позиции итератора. current нужен для имени, getInfo читает старое состояние. После next текущей становится другая запись. Для обновления конкретного известного объекта проще $files[$b] = ... .

Скачать самостоятельный пример с результатом и README

Пройти объекты и их метаданные вручнуюСамостоятельный пример
<?php
class Task {
    public function __construct(public string $name) {}
}
$build = new Task('Сборка');
$test = new Task('Тесты');
$states = new SplObjectStorage();
$states[$build] = 'done';
$states[$test] = 'waiting';

$states->rewind();
while ($states->valid()) {
    $position = $states->key();
    $task = $states->current();
    $info = $states->getInfo();
    echo $position, ': ', $task->name, ' — ', $info, "\n";
    $states->next();
}
Ожидаемый результат
0: Сборка — done
1: Тесты — waiting

rewind ставит итератор на первую запись. valid разрешает current/getInfo/key. current возвращает объект-ключ, getInfo — связанную метаинформацию, key — позицию обхода 0,1… . next переводит к следующей записи. Позиция не является ID объекта.

Скачать самостоятельный пример с результатом и README

Продолжение: SplObjectStorage::getInfo, SplObjectStorage::offsetSet.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplObjectStorage::unserializeЗаполнить storage из доверенной строки

PHP 5.1+ · SPL

public function SplObjectStorage::unserialize(string $data): void

Заполнить storage из доверенной строки. SplObjectStorage отделяет object-key от связанного info; операция использует идентичность объекта или результат переопределённого getHash.

ПараметрЧто означает в задаче
dataсовместимый сериализованный snapshot.
Часть контрактаЧто важно
Сигнатураpublic function SplObjectStorage::unserialize(string $data): void
Результатvoid.
Ошибки и особые значенияПовреждённая строка — UnexpectedValueException; неизвестные классы дают неполные объекты.
ВерсииPHP 5.1+
Восстановить доверенный снимок и заметить новую идентичностьСамостоятельный пример
<?php
class StoredJob {
    public function __construct(public int $id) {}
}
$original = new StoredJob(42);
$source = new SplObjectStorage();
$source[$original] = 'queued';
$payload = $source->serialize();

$restored = new SplObjectStorage();
$restored->unserialize($payload);
$restored->rewind();
echo 'Записей: ', $restored->count(), "\n";
echo 'Восстановлено: ', $restored->current()->id, '/', $restored->getInfo(), "\n";
echo 'Исходный экземпляр — ключ: ', $restored->offsetExists($original) ? 'да' : 'нет', "\n";
Ожидаемый результат
Записей: 1
Восстановлено: 42/queued
Исходный экземпляр — ключ: нет

После unserialize создан новый объект StoredJob со значением id=42. Он не тождествен $original, поэтому исходный экземпляр не является ключом restored. Это принципиально для identity-map. Строка допустима только из доверенного локального источника; десериализация неизвестных классов опасна.

Скачать самостоятельный пример с результатом и README

Сохранить доверенный локальный снимок в файлСамостоятельный пример
<?php
$path = __DIR__ . '/storage.cache';
$object = (object) ['name' => 'report'];
$source = new SplObjectStorage();
$source[$object] = ['status' => 'ready'];
file_put_contents($path, $source->serialize());

$payload = file_get_contents($path);
if ($payload === false) {
    throw new RuntimeException('Кеш не прочитан');
}
$loaded = new SplObjectStorage();
$loaded->unserialize($payload);
$loaded->rewind();
echo $loaded->current()->name, ': ', $loaded->getInfo()['status'], "\n";
unlink($path);
Ожидаемый результат
report: ready

Пример создаёт файл только в изолированной учебной папке, проверяет чтение и удаляет его. В производстве добавляют атомарную запись, контроль срока/версии и обработку повреждения. Для внешнего API лучше явные ID и JSON-схема, потому что PHP-сериализация восстанавливает объекты.

Скачать самостоятельный пример с результатом и README

Продолжение: SplObjectStorage::serialize, SplObjectStorage::offsetExists.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplObjectStorage::validПроверить, можно ли читать текущую позицию

PHP 5.1+ · SPL

public function SplObjectStorage::valid(): bool

Проверить, можно ли читать текущую позицию. SplObjectStorage отделяет object-key от связанного info; операция использует идентичность объекта или результат переопределённого getHash.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplObjectStorage::valid(): bool
Результатbool.
Ошибки и особые значенияОшибок нет.
ВерсииPHP 5.1+
Пройти объекты и их метаданные вручнуюСамостоятельный пример
<?php
class Task {
    public function __construct(public string $name) {}
}
$build = new Task('Сборка');
$test = new Task('Тесты');
$states = new SplObjectStorage();
$states[$build] = 'done';
$states[$test] = 'waiting';

$states->rewind();
while ($states->valid()) {
    $position = $states->key();
    $task = $states->current();
    $info = $states->getInfo();
    echo $position, ': ', $task->name, ' — ', $info, "\n";
    $states->next();
}
Ожидаемый результат
0: Сборка — done
1: Тесты — waiting

rewind ставит итератор на первую запись. valid разрешает current/getInfo/key. current возвращает объект-ключ, getInfo — связанную метаинформацию, key — позицию обхода 0,1… . next переводит к следующей записи. Позиция не является ID объекта.

Скачать самостоятельный пример с результатом и README

Не читать current после конца обходаСамостоятельный пример
<?php
$storage = new SplObjectStorage();
$object = (object) ['id' => 7];
$storage[$object] = 'ready';
$storage->rewind();
$storage->next();

echo 'Позиция действительна: ', $storage->valid() ? 'да' : 'нет', "\n";
try {
    $storage->current();
} catch (RuntimeException $error) {
    echo "current() остановлен на недействительной позиции\n";
}
Ожидаемый результат
Позиция действительна: нет
current() остановлен на недействительной позиции

После единственного next итератор находится за последней записью. PHP 8.5 выбрасывает RuntimeException. Официальная страница current всё ещё указывает Error с PHP 8.1; пример фиксирует поведение текущего исходника и runtime. Надёжный цикл всегда вызывает current только после valid().

Скачать самостоятельный пример с результатом и README

Продолжение: SplObjectStorage::current, SplObjectStorage::next.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

AppendIterator::appendAppendIterator::append: добавить ещё один источник в конец общего обхода

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function AppendIterator::append(Iterator $iterator): void

AppendIterator::append нужен, чтобы добавить ещё один источник в конец общего обхода. В этой задаче AppendIterator помогает последовательно пройти несколько уже готовых итераторов как один поток, не склеивая все значения в новый массив. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
iteratorИсходный Iterator или Traversable указанного сигнатурой типа. Объект не копируется: декоратор читает тот же курсор.
Часть контрактаЧто важно
Сигнатураpublic function AppendIterator::append(Iterator $iterator): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияTypeError и исключения вложенного источника не скрываются. Особые значения, предупреждения и версии перечислены в полном официальном контракте ниже.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Два отдела уже отдали по Iterator. Нужно обработать их подряд, но не создавать третий массив со всеми заказами.

Объединить заказы сайта и магазинаСамостоятельный пример
<?php
declare(strict_types=1);

$web = new ArrayIterator(['web-42', 'web-43']);
$shop = new ArrayIterator(['shop-7']);
$orders = new AppendIterator();
$orders->append($web);
$orders->append($shop);
foreach ($orders as $key => $order) {
    echo $orders->getIteratorIndex(), '|', $key, '|', $order, "\n";
}
echo 'Источников: ', $orders->getArrayIterator()->count(), "\n";
Ожидаемый результат
0|0|web-42
0|1|web-43
1|0|shop-7
Источников: 2

append() сохранил оба объекта-источника. Во время foreach getIteratorIndex() показывает, откуда пришла строка; key() остаётся ключом конкретного источника. getArrayIterator() здесь считает подключённые источники, а не заказы.

Скачать самостоятельный пример с fixtures, результатом и README

Для диагностики нужно увидеть не только значение, но и переход курсора между источниками.

Пройти общий поток вручную и вернуться к началуСамостоятельный пример
<?php
declare(strict_types=1);

$all = new AppendIterator();
$all->append(new ArrayIterator(['A-1']));
$all->append(new ArrayIterator(['B-1', 'B-2']));
$all->rewind();
while ($all->valid()) {
    echo $all->getIteratorIndex(), ':', $all->key(), '=', $all->current(), "\n";
    $all->next();
}
$all->rewind();
echo 'Снова первый: ', $all->current(), "\n";
Ожидаемый результат
0:0=A-1
1:0=B-1
1:1=B-2
Снова первый: A-1

rewind() поставил курсор в начало первого непустого источника. Цикл проверял valid(), читал current()/key(), затем next() переходил дальше; после конца повторный rewind() вернул первый элемент, потому что оба ArrayIterator повторяемы.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

AppendIterator::append

(PHP 5 >= 5.1.0, PHP 7, PHP 8) AppendIterator::append — Appends an iterator

Description

public function AppendIterator::append(Iterator $iterator): void

Appends an iterator.

Parameters

iterator

The iterator to append.

Return Values

No value is returned.

See Also

AppendIterator::__construct() - Constructs an AppendIterator

Связанные карточки: ArrayIterator::__construct, IteratorIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

AppendIterator::__constructAppendIterator::__construct: создать и настроить объект для дальнейшего обхода

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function AppendIterator::__construct()

AppendIterator::__construct нужен, чтобы создать и настроить объект для дальнейшего обхода. В этой задаче AppendIterator помогает последовательно пройти несколько уже готовых итераторов как один поток, не склеивая все значения в новый массив. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function AppendIterator::__construct()
РезультатКонструктор не возвращает прикладное значение; выражение new создаёт объект, который затем сохраняется в переменной.
Ошибки и особые значенияНеподходящий тип аргумента приводит к TypeError; несовместимые флаги, маска или путь имеют отдельные ValueError/RuntimeException либо файловые предупреждения согласно полному контракту.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Два отдела уже отдали по Iterator. Нужно обработать их подряд, но не создавать третий массив со всеми заказами.

Объединить заказы сайта и магазинаСамостоятельный пример
<?php
declare(strict_types=1);

$web = new ArrayIterator(['web-42', 'web-43']);
$shop = new ArrayIterator(['shop-7']);
$orders = new AppendIterator();
$orders->append($web);
$orders->append($shop);
foreach ($orders as $key => $order) {
    echo $orders->getIteratorIndex(), '|', $key, '|', $order, "\n";
}
echo 'Источников: ', $orders->getArrayIterator()->count(), "\n";
Ожидаемый результат
0|0|web-42
0|1|web-43
1|0|shop-7
Источников: 2

append() сохранил оба объекта-источника. Во время foreach getIteratorIndex() показывает, откуда пришла строка; key() остаётся ключом конкретного источника. getArrayIterator() здесь считает подключённые источники, а не заказы.

Скачать самостоятельный пример с fixtures, результатом и README

Для диагностики нужно увидеть не только значение, но и переход курсора между источниками.

Пройти общий поток вручную и вернуться к началуСамостоятельный пример
<?php
declare(strict_types=1);

$all = new AppendIterator();
$all->append(new ArrayIterator(['A-1']));
$all->append(new ArrayIterator(['B-1', 'B-2']));
$all->rewind();
while ($all->valid()) {
    echo $all->getIteratorIndex(), ':', $all->key(), '=', $all->current(), "\n";
    $all->next();
}
$all->rewind();
echo 'Снова первый: ', $all->current(), "\n";
Ожидаемый результат
0:0=A-1
1:0=B-1
1:1=B-2
Снова первый: A-1

rewind() поставил курсор в начало первого непустого источника. Цикл проверял valid(), читал current()/key(), затем next() переходил дальше; после конца повторный rewind() вернул первый элемент, потому что оба ArrayIterator повторяемы.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

AppendIterator::__construct

(PHP 5 >= 5.1.0, PHP 7, PHP 8) AppendIterator::__construct — Constructs an AppendIterator

Description

public function AppendIterator::__construct()

Constructs an AppendIterator.

Parameters

This function has no parameters.

Notes

Caution

When using iterator_to_array() to copy the values of the AppendIterator into an array, you have to set the optional use_key argument to false. When use_key is not false any keys reoccurring in inner iterators will get overwritten in the returned array. There is no way to preserve the original keys.

See Also

AppendIterator::append() - Appends an iterator

Связанные карточки: ArrayIterator::__construct, IteratorIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

AppendIterator::currentAppendIterator::current: получить текущее значение без продвижения курсора

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function AppendIterator::current(): mixed

AppendIterator::current нужен, чтобы получить текущее значение без продвижения курсора. В этой задаче AppendIterator помогает последовательно пройти несколько уже готовых итераторов как один поток, не склеивая все значения в новый массив. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function AppendIterator::current(): mixed
Результатmixed: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияСначала вызывайте valid(). На недействительном курсоре особое значение зависит от класса и не должно смешиваться с настоящим null.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Два отдела уже отдали по Iterator. Нужно обработать их подряд, но не создавать третий массив со всеми заказами.

Объединить заказы сайта и магазинаСамостоятельный пример
<?php
declare(strict_types=1);

$web = new ArrayIterator(['web-42', 'web-43']);
$shop = new ArrayIterator(['shop-7']);
$orders = new AppendIterator();
$orders->append($web);
$orders->append($shop);
foreach ($orders as $key => $order) {
    echo $orders->getIteratorIndex(), '|', $key, '|', $order, "\n";
}
echo 'Источников: ', $orders->getArrayIterator()->count(), "\n";
Ожидаемый результат
0|0|web-42
0|1|web-43
1|0|shop-7
Источников: 2

append() сохранил оба объекта-источника. Во время foreach getIteratorIndex() показывает, откуда пришла строка; key() остаётся ключом конкретного источника. getArrayIterator() здесь считает подключённые источники, а не заказы.

Скачать самостоятельный пример с fixtures, результатом и README

Для диагностики нужно увидеть не только значение, но и переход курсора между источниками.

Пройти общий поток вручную и вернуться к началуСамостоятельный пример
<?php
declare(strict_types=1);

$all = new AppendIterator();
$all->append(new ArrayIterator(['A-1']));
$all->append(new ArrayIterator(['B-1', 'B-2']));
$all->rewind();
while ($all->valid()) {
    echo $all->getIteratorIndex(), ':', $all->key(), '=', $all->current(), "\n";
    $all->next();
}
$all->rewind();
echo 'Снова первый: ', $all->current(), "\n";
Ожидаемый результат
0:0=A-1
1:0=B-1
1:1=B-2
Снова первый: A-1

rewind() поставил курсор в начало первого непустого источника. Цикл проверял valid(), читал current()/key(), затем next() переходил дальше; после конца повторный rewind() вернул первый элемент, потому что оба ArrayIterator повторяемы.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

AppendIterator::current

(PHP 5 >= 5.1.0, PHP 7, PHP 8) AppendIterator::current — Gets the current value

Description

public function AppendIterator::current(): mixed

Gets the current value.

Parameters

This function has no parameters.

Return Values

The current value if it is valid or null otherwise.

See Also

Iterator::current() - Return the current element

AppendIterator::key() - Gets the current key

AppendIterator::valid() - Checks validity of the current element

AppendIterator::next() - Moves to the next element

AppendIterator::rewind() - Rewinds the Iterator

Связанные карточки: ArrayIterator::__construct, IteratorIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

AppendIterator::getArrayIteratorAppendIterator::getArrayIterator: получить объект, содержащий подключённые внутренние итераторы

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function AppendIterator::getArrayIterator(): ArrayIterator

AppendIterator::getArrayIterator нужен, чтобы получить объект, содержащий подключённые внутренние итераторы. В этой задаче AppendIterator помогает последовательно пройти несколько уже готовых итераторов как один поток, не склеивая все значения в новый массив. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function AppendIterator::getArrayIterator(): ArrayIterator
РезультатArrayIterator: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения вложенного источника не скрываются. Особые значения, предупреждения и версии перечислены в полном официальном контракте ниже.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Два отдела уже отдали по Iterator. Нужно обработать их подряд, но не создавать третий массив со всеми заказами.

Объединить заказы сайта и магазинаСамостоятельный пример
<?php
declare(strict_types=1);

$web = new ArrayIterator(['web-42', 'web-43']);
$shop = new ArrayIterator(['shop-7']);
$orders = new AppendIterator();
$orders->append($web);
$orders->append($shop);
foreach ($orders as $key => $order) {
    echo $orders->getIteratorIndex(), '|', $key, '|', $order, "\n";
}
echo 'Источников: ', $orders->getArrayIterator()->count(), "\n";
Ожидаемый результат
0|0|web-42
0|1|web-43
1|0|shop-7
Источников: 2

append() сохранил оба объекта-источника. Во время foreach getIteratorIndex() показывает, откуда пришла строка; key() остаётся ключом конкретного источника. getArrayIterator() здесь считает подключённые источники, а не заказы.

Скачать самостоятельный пример с fixtures, результатом и README

Для диагностики нужно увидеть не только значение, но и переход курсора между источниками.

Пройти общий поток вручную и вернуться к началуСамостоятельный пример
<?php
declare(strict_types=1);

$all = new AppendIterator();
$all->append(new ArrayIterator(['A-1']));
$all->append(new ArrayIterator(['B-1', 'B-2']));
$all->rewind();
while ($all->valid()) {
    echo $all->getIteratorIndex(), ':', $all->key(), '=', $all->current(), "\n";
    $all->next();
}
$all->rewind();
echo 'Снова первый: ', $all->current(), "\n";
Ожидаемый результат
0:0=A-1
1:0=B-1
1:1=B-2
Снова первый: A-1

rewind() поставил курсор в начало первого непустого источника. Цикл проверял valid(), читал current()/key(), затем next() переходил дальше; после конца повторный rewind() вернул первый элемент, потому что оба ArrayIterator повторяемы.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

AppendIterator::getArrayIterator

(PHP 5 >= 5.2.0, PHP 7, PHP 8) AppendIterator::getArrayIterator — Gets the ArrayIterator

Description

public function AppendIterator::getArrayIterator(): ArrayIterator

This method gets the ArrayIterator that is used to store the iterators added with AppendIterator::append().

Parameters

This function has no parameters.

Return Values

Returns an ArrayIterator containing the appended iterators.

See Also

AppendIterator::getInnerIterator()

Связанные карточки: ArrayIterator::__construct, IteratorIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

AppendIterator::getIteratorIndexAppendIterator::getIteratorIndex: узнать номер внутреннего источника, который сейчас отдаёт значение

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function AppendIterator::getIteratorIndex(): ?int

AppendIterator::getIteratorIndex нужен, чтобы узнать номер внутреннего источника, который сейчас отдаёт значение. В этой задаче AppendIterator помогает последовательно пройти несколько уже готовых итераторов как один поток, не склеивая все значения в новый массив. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function AppendIterator::getIteratorIndex(): ?int
Результат?int: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения вложенного источника не скрываются. Особые значения, предупреждения и версии перечислены в полном официальном контракте ниже.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Два отдела уже отдали по Iterator. Нужно обработать их подряд, но не создавать третий массив со всеми заказами.

Объединить заказы сайта и магазинаСамостоятельный пример
<?php
declare(strict_types=1);

$web = new ArrayIterator(['web-42', 'web-43']);
$shop = new ArrayIterator(['shop-7']);
$orders = new AppendIterator();
$orders->append($web);
$orders->append($shop);
foreach ($orders as $key => $order) {
    echo $orders->getIteratorIndex(), '|', $key, '|', $order, "\n";
}
echo 'Источников: ', $orders->getArrayIterator()->count(), "\n";
Ожидаемый результат
0|0|web-42
0|1|web-43
1|0|shop-7
Источников: 2

append() сохранил оба объекта-источника. Во время foreach getIteratorIndex() показывает, откуда пришла строка; key() остаётся ключом конкретного источника. getArrayIterator() здесь считает подключённые источники, а не заказы.

Скачать самостоятельный пример с fixtures, результатом и README

Для диагностики нужно увидеть не только значение, но и переход курсора между источниками.

Пройти общий поток вручную и вернуться к началуСамостоятельный пример
<?php
declare(strict_types=1);

$all = new AppendIterator();
$all->append(new ArrayIterator(['A-1']));
$all->append(new ArrayIterator(['B-1', 'B-2']));
$all->rewind();
while ($all->valid()) {
    echo $all->getIteratorIndex(), ':', $all->key(), '=', $all->current(), "\n";
    $all->next();
}
$all->rewind();
echo 'Снова первый: ', $all->current(), "\n";
Ожидаемый результат
0:0=A-1
1:0=B-1
1:1=B-2
Снова первый: A-1

rewind() поставил курсор в начало первого непустого источника. Цикл проверял valid(), читал current()/key(), затем next() переходил дальше; после конца повторный rewind() вернул первый элемент, потому что оба ArrayIterator повторяемы.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

AppendIterator::getIteratorIndex

(PHP 5 >= 5.2.0, PHP 7, PHP 8) AppendIterator::getIteratorIndex — Gets an index of iterators

Description

public function AppendIterator::getIteratorIndex(): ?int

Gets the index of the current inner iterator.

Parameters

This function has no parameters.

Return Values

Returns the zero-based, integer index of the current inner iterator if it exists, or null otherwise.

See Also

AppendIterator::getInnerIterator()

AppendIterator::getArrayIterator() - Gets the ArrayIterator

Связанные карточки: ArrayIterator::__construct, IteratorIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

AppendIterator::keyAppendIterator::key: получить ключ или позицию текущего элемента

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function AppendIterator::key(): mixed

AppendIterator::key нужен, чтобы получить ключ или позицию текущего элемента. В этой задаче AppendIterator помогает последовательно пройти несколько уже готовых итераторов как один поток, не склеивая все значения в новый массив. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function AppendIterator::key(): mixed
Результатmixed: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияСначала вызывайте valid(). Ключ может быть int, string или составным массивом и не обязан быть бизнес-идентификатором.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Два отдела уже отдали по Iterator. Нужно обработать их подряд, но не создавать третий массив со всеми заказами.

Объединить заказы сайта и магазинаСамостоятельный пример
<?php
declare(strict_types=1);

$web = new ArrayIterator(['web-42', 'web-43']);
$shop = new ArrayIterator(['shop-7']);
$orders = new AppendIterator();
$orders->append($web);
$orders->append($shop);
foreach ($orders as $key => $order) {
    echo $orders->getIteratorIndex(), '|', $key, '|', $order, "\n";
}
echo 'Источников: ', $orders->getArrayIterator()->count(), "\n";
Ожидаемый результат
0|0|web-42
0|1|web-43
1|0|shop-7
Источников: 2

append() сохранил оба объекта-источника. Во время foreach getIteratorIndex() показывает, откуда пришла строка; key() остаётся ключом конкретного источника. getArrayIterator() здесь считает подключённые источники, а не заказы.

Скачать самостоятельный пример с fixtures, результатом и README

Для диагностики нужно увидеть не только значение, но и переход курсора между источниками.

Пройти общий поток вручную и вернуться к началуСамостоятельный пример
<?php
declare(strict_types=1);

$all = new AppendIterator();
$all->append(new ArrayIterator(['A-1']));
$all->append(new ArrayIterator(['B-1', 'B-2']));
$all->rewind();
while ($all->valid()) {
    echo $all->getIteratorIndex(), ':', $all->key(), '=', $all->current(), "\n";
    $all->next();
}
$all->rewind();
echo 'Снова первый: ', $all->current(), "\n";
Ожидаемый результат
0:0=A-1
1:0=B-1
1:1=B-2
Снова первый: A-1

rewind() поставил курсор в начало первого непустого источника. Цикл проверял valid(), читал current()/key(), затем next() переходил дальше; после конца повторный rewind() вернул первый элемент, потому что оба ArrayIterator повторяемы.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

AppendIterator::key

(PHP 5 >= 5.1.0, PHP 7, PHP 8) AppendIterator::key — Gets the current key

Description

public function AppendIterator::key(): scalar

Get the current key.

Parameters

This function has no parameters.

Return Values

The current key if it is valid or null otherwise.

See Also

Iterator::key() - Return the key of the current element

AppendIterator::current() - Gets the current value

AppendIterator::valid() - Checks validity of the current element

AppendIterator::next() - Moves to the next element

AppendIterator::rewind() - Rewinds the Iterator

Связанные карточки: ArrayIterator::__construct, IteratorIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

AppendIterator::nextAppendIterator::next: перевести курсор к следующему элементу

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function AppendIterator::next(): void

AppendIterator::next нужен, чтобы перевести курсор к следующему элементу. В этой задаче AppendIterator помогает последовательно пройти несколько уже готовых итераторов как один поток, не склеивая все значения в новый массив. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function AppendIterator::next(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияПродвижение одноразового источника нельзя отменить. Исключение из вложенного источника передаётся вызывающему коду.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Два отдела уже отдали по Iterator. Нужно обработать их подряд, но не создавать третий массив со всеми заказами.

Объединить заказы сайта и магазинаСамостоятельный пример
<?php
declare(strict_types=1);

$web = new ArrayIterator(['web-42', 'web-43']);
$shop = new ArrayIterator(['shop-7']);
$orders = new AppendIterator();
$orders->append($web);
$orders->append($shop);
foreach ($orders as $key => $order) {
    echo $orders->getIteratorIndex(), '|', $key, '|', $order, "\n";
}
echo 'Источников: ', $orders->getArrayIterator()->count(), "\n";
Ожидаемый результат
0|0|web-42
0|1|web-43
1|0|shop-7
Источников: 2

append() сохранил оба объекта-источника. Во время foreach getIteratorIndex() показывает, откуда пришла строка; key() остаётся ключом конкретного источника. getArrayIterator() здесь считает подключённые источники, а не заказы.

Скачать самостоятельный пример с fixtures, результатом и README

Для диагностики нужно увидеть не только значение, но и переход курсора между источниками.

Пройти общий поток вручную и вернуться к началуСамостоятельный пример
<?php
declare(strict_types=1);

$all = new AppendIterator();
$all->append(new ArrayIterator(['A-1']));
$all->append(new ArrayIterator(['B-1', 'B-2']));
$all->rewind();
while ($all->valid()) {
    echo $all->getIteratorIndex(), ':', $all->key(), '=', $all->current(), "\n";
    $all->next();
}
$all->rewind();
echo 'Снова первый: ', $all->current(), "\n";
Ожидаемый результат
0:0=A-1
1:0=B-1
1:1=B-2
Снова первый: A-1

rewind() поставил курсор в начало первого непустого источника. Цикл проверял valid(), читал current()/key(), затем next() переходил дальше; после конца повторный rewind() вернул первый элемент, потому что оба ArrayIterator повторяемы.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

AppendIterator::next

(PHP 5 >= 5.1.0, PHP 7, PHP 8) AppendIterator::next — Moves to the next element

Description

public function AppendIterator::next(): void

Moves to the next element. If this means to another Iterator then it rewinds that Iterator.

Parameters

This function has no parameters.

Return Values

No value is returned.

See Also

Iterator::next() - Move forward to next element

AppendIterator::current() - Gets the current value

AppendIterator::key() - Gets the current key

AppendIterator::valid() - Checks validity of the current element

AppendIterator::rewind() - Rewinds the Iterator

Связанные карточки: ArrayIterator::__construct, IteratorIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

AppendIterator::rewindAppendIterator::rewind: попытаться установить курсор на первый элемент

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function AppendIterator::rewind(): void

AppendIterator::rewind нужен, чтобы попытаться установить курсор на первый элемент. В этой задаче AppendIterator помогает последовательно пройти несколько уже готовых итераторов как один поток, не склеивая все значения в новый массив. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function AppendIterator::rewind(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияНе каждый Traversable можно повторить. NoRewindIterator намеренно игнорирует повторную перемотку, а Generator после завершения может выбросить исключение.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Два отдела уже отдали по Iterator. Нужно обработать их подряд, но не создавать третий массив со всеми заказами.

Объединить заказы сайта и магазинаСамостоятельный пример
<?php
declare(strict_types=1);

$web = new ArrayIterator(['web-42', 'web-43']);
$shop = new ArrayIterator(['shop-7']);
$orders = new AppendIterator();
$orders->append($web);
$orders->append($shop);
foreach ($orders as $key => $order) {
    echo $orders->getIteratorIndex(), '|', $key, '|', $order, "\n";
}
echo 'Источников: ', $orders->getArrayIterator()->count(), "\n";
Ожидаемый результат
0|0|web-42
0|1|web-43
1|0|shop-7
Источников: 2

append() сохранил оба объекта-источника. Во время foreach getIteratorIndex() показывает, откуда пришла строка; key() остаётся ключом конкретного источника. getArrayIterator() здесь считает подключённые источники, а не заказы.

Скачать самостоятельный пример с fixtures, результатом и README

Для диагностики нужно увидеть не только значение, но и переход курсора между источниками.

Пройти общий поток вручную и вернуться к началуСамостоятельный пример
<?php
declare(strict_types=1);

$all = new AppendIterator();
$all->append(new ArrayIterator(['A-1']));
$all->append(new ArrayIterator(['B-1', 'B-2']));
$all->rewind();
while ($all->valid()) {
    echo $all->getIteratorIndex(), ':', $all->key(), '=', $all->current(), "\n";
    $all->next();
}
$all->rewind();
echo 'Снова первый: ', $all->current(), "\n";
Ожидаемый результат
0:0=A-1
1:0=B-1
1:1=B-2
Снова первый: A-1

rewind() поставил курсор в начало первого непустого источника. Цикл проверял valid(), читал current()/key(), затем next() переходил дальше; после конца повторный rewind() вернул первый элемент, потому что оба ArrayIterator повторяемы.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

AppendIterator::rewind

(PHP 5 >= 5.1.0, PHP 7, PHP 8) AppendIterator::rewind — Rewinds the Iterator

Description

public function AppendIterator::rewind(): void

Rewind to the first element of the first inner Iterator.

Parameters

This function has no parameters.

Return Values

No value is returned.

See Also

Iterator::rewind() - Rewind the Iterator to the first element

AppendIterator::current() - Gets the current value

AppendIterator::key() - Gets the current key

AppendIterator::next() - Moves to the next element

AppendIterator::valid() - Checks validity of the current element

Связанные карточки: ArrayIterator::__construct, IteratorIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

AppendIterator::validAppendIterator::valid: проверить, указывает ли курсор на существующий элемент

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function AppendIterator::valid(): bool

AppendIterator::valid нужен, чтобы проверить, указывает ли курсор на существующий элемент. В этой задаче AppendIterator помогает последовательно пройти несколько уже готовых итераторов как один поток, не склеивая все значения в новый массив. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function AppendIterator::valid(): bool
Результатbool: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияfalse означает отсутствие текущего элемента, а не ошибку бизнес-данных. Ошибки источника могут возникнуть отдельно.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Два отдела уже отдали по Iterator. Нужно обработать их подряд, но не создавать третий массив со всеми заказами.

Объединить заказы сайта и магазинаСамостоятельный пример
<?php
declare(strict_types=1);

$web = new ArrayIterator(['web-42', 'web-43']);
$shop = new ArrayIterator(['shop-7']);
$orders = new AppendIterator();
$orders->append($web);
$orders->append($shop);
foreach ($orders as $key => $order) {
    echo $orders->getIteratorIndex(), '|', $key, '|', $order, "\n";
}
echo 'Источников: ', $orders->getArrayIterator()->count(), "\n";
Ожидаемый результат
0|0|web-42
0|1|web-43
1|0|shop-7
Источников: 2

append() сохранил оба объекта-источника. Во время foreach getIteratorIndex() показывает, откуда пришла строка; key() остаётся ключом конкретного источника. getArrayIterator() здесь считает подключённые источники, а не заказы.

Скачать самостоятельный пример с fixtures, результатом и README

Для диагностики нужно увидеть не только значение, но и переход курсора между источниками.

Пройти общий поток вручную и вернуться к началуСамостоятельный пример
<?php
declare(strict_types=1);

$all = new AppendIterator();
$all->append(new ArrayIterator(['A-1']));
$all->append(new ArrayIterator(['B-1', 'B-2']));
$all->rewind();
while ($all->valid()) {
    echo $all->getIteratorIndex(), ':', $all->key(), '=', $all->current(), "\n";
    $all->next();
}
$all->rewind();
echo 'Снова первый: ', $all->current(), "\n";
Ожидаемый результат
0:0=A-1
1:0=B-1
1:1=B-2
Снова первый: A-1

rewind() поставил курсор в начало первого непустого источника. Цикл проверял valid(), читал current()/key(), затем next() переходил дальше; после конца повторный rewind() вернул первый элемент, потому что оба ArrayIterator повторяемы.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

AppendIterator::valid

(PHP 5 >= 5.1.0, PHP 7, PHP 8) AppendIterator::valid — Checks validity of the current element

Description

public function AppendIterator::valid(): bool

Checks validity of the current element.

Parameters

This function has no parameters.

Return Values

Returns true if the current iteration is valid, false otherwise.

See Also

AppendIterator::current() - Gets the current value

AppendIterator::key() - Gets the current key

AppendIterator::next() - Moves to the next element

AppendIterator::rewind() - Rewinds the Iterator

Связанные карточки: ArrayIterator::__construct, IteratorIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayIterator::appendArrayIterator::append: добавить ещё один источник в конец общего обхода

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function ArrayIterator::append(mixed $value): void

ArrayIterator::append нужен, чтобы добавить ещё один источник в конец общего обхода. В этой задаче ArrayIterator помогает обходить и изменять массив через объект с явным курсором, сортировкой, позиционированием и ArrayAccess. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
valueЗначение параметра связано с текущей операцией; допустимый тип и значение по умолчанию видны в сигнатуре, а фактическая роль показана перед примером.
Часть контрактаЧто важно
Сигнатураpublic function ArrayIterator::append(mixed $value): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияTypeError и исключения вложенного источника не скрываются. Особые значения, предупреждения и версии перечислены в полном официальном контракте ниже.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Остатки уже находятся в ArrayIterator. Нужно добавить именованный товар, добавить значение с автоматическим ключом и удалить старый ключ.

Обновить остатки и получить обычный массивСамостоятельный пример
<?php
declare(strict_types=1);

$stock = new ArrayIterator(['brush' => 2]);
$stock->offsetSet('paint', 3);
$stock->append(7);
echo 'brush exists: ', $stock->offsetExists('brush') ? 'yes' : 'no', "\n";
echo 'paint: ', $stock->offsetGet('paint'), "\n";
$stock->offsetUnset('brush');
echo 'count: ', $stock->count(), "\n";
echo json_encode($stock->getArrayCopy(), JSON_UNESCAPED_UNICODE), "\n";
Ожидаемый результат
brush exists: yes
paint: 3
count: 2
{"paint":3,"0":7}

offsetSet("paint", 3) создал именованный элемент, append(7) выбрал следующий целочисленный ключ 0. После offsetUnset("brush") count() равен двум, а getArrayCopy() вернул независимое обычное представление данных.

Скачать самостоятельный пример с fixtures, результатом и README

Интерфейс хранит текущую позицию списка, а ключи товаров остаются строковыми артикулами.

Перейти ко второму товару каталогаСамостоятельный пример
<?php
declare(strict_types=1);

$catalog = new ArrayIterator([
    'sku-10' => 'Кисть',
    'sku-20' => 'Лак',
    'sku-30' => 'Валик',
]);
$catalog->seek(1);
echo $catalog->key(), ': ', $catalog->current(), "\n";
$catalog->next();
echo $catalog->key(), ': ', $catalog->current(), "\n";
Ожидаемый результат
sku-20: Лак
sku-30: Валик

seek(1) выбрал вторую позицию порядка обхода, хотя её ключ — sku-20. current() вернул название, key() — артикул, next() передвинул курсор на третью позицию.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

ArrayIterator::append

(PHP 5, PHP 7, PHP 8) ArrayIterator::append — Append an element

Description

public function ArrayIterator::append(mixed $value): void

Appends value as the last element.

WarningThis function is currently not documented; only its argument list is available.

Parameters

value

The value to append.

Return Values

No value is returned.

Notes

Note:

This method cannot be called when the ArrayIterator refers to an object.

See Also

ArrayIterator::next() - Move to next entry

Связанные карточки: ArrayIterator::getArrayCopy, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayIterator::__constructArrayIterator::__construct: создать и настроить объект для дальнейшего обхода

PHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.5.0) · SPL

public function ArrayIterator::__construct(object|array $array = [], int $flags = 0)

ArrayIterator::__construct нужен, чтобы создать и настроить объект для дальнейшего обхода. В этой задаче ArrayIterator помогает обходить и изменять массив через объект с явным курсором, сортировкой, позиционированием и ArrayAccess. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
arrayИсходный массив либо поддерживаемый объект. Изменения и копирование зависят от конкретного класса и показаны в примерах.
flagsБитовая маска режима. Оператор | объединяет совместимые константы; setFlags заменяет прежнюю маску целиком.
Часть контрактаЧто важно
Сигнатураpublic function ArrayIterator::__construct(object|array $array = [], int $flags = 0)
РезультатКонструктор не возвращает прикладное значение; выражение new создаёт объект, который затем сохраняется в переменной.
Ошибки и особые значенияНеподходящий тип аргумента приводит к TypeError; несовместимые флаги, маска или путь имеют отдельные ValueError/RuntimeException либо файловые предупреждения согласно полному контракту.
ВерсииPHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.5.0)

Интерфейс хранит текущую позицию списка, а ключи товаров остаются строковыми артикулами.

Перейти ко второму товару каталогаСамостоятельный пример
<?php
declare(strict_types=1);

$catalog = new ArrayIterator([
    'sku-10' => 'Кисть',
    'sku-20' => 'Лак',
    'sku-30' => 'Валик',
]);
$catalog->seek(1);
echo $catalog->key(), ': ', $catalog->current(), "\n";
$catalog->next();
echo $catalog->key(), ': ', $catalog->current(), "\n";
Ожидаемый результат
sku-20: Лак
sku-30: Валик

seek(1) выбрал вторую позицию порядка обхода, хотя её ключ — sku-20. current() вернул название, key() — артикул, next() передвинул курсор на третью позицию.

Скачать самостоятельный пример с fixtures, результатом и README

Чужой код ожидает краткую запись $row->qty. Флаг меняет способ доступа, но не превращает строку qty в объявленное типизированное свойство.

Включить доступ к ключам как к свойствамСамостоятельный пример
<?php
declare(strict_types=1);

$row = new ArrayIterator(['qty' => 2], ArrayIterator::ARRAY_AS_PROPS);
echo 'qty: ', $row->qty, "\n";
echo 'array-as-props: ', ($row->getFlags() & ArrayIterator::ARRAY_AS_PROPS) ? 'yes' : 'no', "\n";
$row->setFlags(ArrayIterator::STD_PROP_LIST);
echo 'std-prop-list: ', ($row->getFlags() & ArrayIterator::STD_PROP_LIST) ? 'yes' : 'no', "\n";
echo 'array qty stays: ', $row['qty'], "\n";
Ожидаемый результат
qty: 2
array-as-props: yes
std-prop-list: yes
array qty stays: 2

Первый getFlags() подтвердил ARRAY_AS_PROPS. setFlags() заменил маску на STD_PROP_LIST; элемент массива при этом сохранился и читается через $row["qty"].

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

ArrayIterator::__construct

(PHP 5, PHP 7, PHP 8) ArrayIterator::__construct — Construct an ArrayIterator

Description

public function ArrayIterator::__construct(array|object $array = [], int $flags = 0)

Constructs an ArrayIterator object.

WarningThis function is currently not documented; only its argument list is available.

Parameters

array

The array or object to be iterated on. Passing an object is deprecated as of PHP 8.5.0.

flags

Flags to control the behaviour of the ArrayIterator object. See ArrayIterator::setFlags().

Errors/Exceptions

As of PHP 8.5.0, throws an InvalidArgumentException if array is an enum.

Changelog

Version Description

8.5.0

Passing an enum as array now throws an InvalidArgumentException.

8.5.0

Passing an object as array is deprecated.

See Also

ArrayIterator::getArrayCopy() - Get array copy

ArrayIterator::setFlags() - Set behaviour flags

ArrayObject::__construct() - Construct a new array object

Связанные карточки: ArrayIterator::getArrayCopy, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayIterator::countArrayIterator::count: получить число элементов, которое определяет этот класс

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function ArrayIterator::count(): int

ArrayIterator::count нужен, чтобы получить число элементов, которое определяет этот класс. В этой задаче ArrayIterator помогает обходить и изменять массив через объект с явным курсором, сортировкой, позиционированием и ArrayAccess. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function ArrayIterator::count(): int
Результатint: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения вложенного источника не скрываются. Особые значения, предупреждения и версии перечислены в полном официальном контракте ниже.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Остатки уже находятся в ArrayIterator. Нужно добавить именованный товар, добавить значение с автоматическим ключом и удалить старый ключ.

Обновить остатки и получить обычный массивСамостоятельный пример
<?php
declare(strict_types=1);

$stock = new ArrayIterator(['brush' => 2]);
$stock->offsetSet('paint', 3);
$stock->append(7);
echo 'brush exists: ', $stock->offsetExists('brush') ? 'yes' : 'no', "\n";
echo 'paint: ', $stock->offsetGet('paint'), "\n";
$stock->offsetUnset('brush');
echo 'count: ', $stock->count(), "\n";
echo json_encode($stock->getArrayCopy(), JSON_UNESCAPED_UNICODE), "\n";
Ожидаемый результат
brush exists: yes
paint: 3
count: 2
{"paint":3,"0":7}

offsetSet("paint", 3) создал именованный элемент, append(7) выбрал следующий целочисленный ключ 0. После offsetUnset("brush") count() равен двум, а getArrayCopy() вернул независимое обычное представление данных.

Скачать самостоятельный пример с fixtures, результатом и README

Интерфейс хранит текущую позицию списка, а ключи товаров остаются строковыми артикулами.

Перейти ко второму товару каталогаСамостоятельный пример
<?php
declare(strict_types=1);

$catalog = new ArrayIterator([
    'sku-10' => 'Кисть',
    'sku-20' => 'Лак',
    'sku-30' => 'Валик',
]);
$catalog->seek(1);
echo $catalog->key(), ': ', $catalog->current(), "\n";
$catalog->next();
echo $catalog->key(), ': ', $catalog->current(), "\n";
Ожидаемый результат
sku-20: Лак
sku-30: Валик

seek(1) выбрал вторую позицию порядка обхода, хотя её ключ — sku-20. current() вернул название, key() — артикул, next() передвинул курсор на третью позицию.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

ArrayIterator::count

(PHP 5, PHP 7, PHP 8) ArrayIterator::count — Count elements

Description

public function ArrayIterator::count(): int

Gets the number of elements in the array, or the number of public properties in the object.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

The number of elements or public properties in the associated array or object, respectively.

See Also

ArrayIterator::getFlags() - Get behavior flags

Связанные карточки: ArrayIterator::getArrayCopy, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayIterator::currentArrayIterator::current: получить текущее значение без продвижения курсора

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function ArrayIterator::current(): mixed

ArrayIterator::current нужен, чтобы получить текущее значение без продвижения курсора. В этой задаче ArrayIterator помогает обходить и изменять массив через объект с явным курсором, сортировкой, позиционированием и ArrayAccess. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function ArrayIterator::current(): mixed
Результатmixed: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияСначала вызывайте valid(). На недействительном курсоре особое значение зависит от класса и не должно смешиваться с настоящим null.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Интерфейс хранит текущую позицию списка, а ключи товаров остаются строковыми артикулами.

Перейти ко второму товару каталогаСамостоятельный пример
<?php
declare(strict_types=1);

$catalog = new ArrayIterator([
    'sku-10' => 'Кисть',
    'sku-20' => 'Лак',
    'sku-30' => 'Валик',
]);
$catalog->seek(1);
echo $catalog->key(), ': ', $catalog->current(), "\n";
$catalog->next();
echo $catalog->key(), ': ', $catalog->current(), "\n";
Ожидаемый результат
sku-20: Лак
sku-30: Валик

seek(1) выбрал вторую позицию порядка обхода, хотя её ключ — sku-20. current() вернул название, key() — артикул, next() передвинул курсор на третью позицию.

Скачать самостоятельный пример с fixtures, результатом и README

foreach сам вызывает пять методов Iterator. Этот пример раскрывает тот же порядок явно.

Показать протокол курсора без foreachСамостоятельный пример
<?php
declare(strict_types=1);

$rows = new ArrayIterator(['draft', 'paid']);
$rows->rewind();
while ($rows->valid()) {
    echo $rows->key(), '=', $rows->current(), "\n";
    $rows->next();
}
echo 'После конца valid: ', $rows->valid() ? 'yes' : 'no', "\n";
$rows->rewind();
echo 'После rewind: ', $rows->current(), "\n";
Ожидаемый результат
0=draft
1=paid
После конца valid: no
После rewind: draft

После rewind() valid() разрешает чтение. next() переводит курсор; после последней строки valid() становится false. Новый rewind() возвращает повторяемый ArrayIterator к первой строке.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

ArrayIterator::current

(PHP 5, PHP 7, PHP 8) ArrayIterator::current — Return current array entry

Description

public function ArrayIterator::current(): mixed

Get the current array entry.

Parameters

This function has no parameters.

Return Values

The current array entry.

Связанные карточки: ArrayIterator::getArrayCopy, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayIterator::getArrayCopyArrayIterator::getArrayCopy: получить обычный массив с текущими данными контейнера

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function ArrayIterator::getArrayCopy(): array

ArrayIterator::getArrayCopy нужен, чтобы получить обычный массив с текущими данными контейнера. В этой задаче ArrayIterator помогает обходить и изменять массив через объект с явным курсором, сортировкой, позиционированием и ArrayAccess. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function ArrayIterator::getArrayCopy(): array
Результатarray: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения вложенного источника не скрываются. Особые значения, предупреждения и версии перечислены в полном официальном контракте ниже.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Остатки уже находятся в ArrayIterator. Нужно добавить именованный товар, добавить значение с автоматическим ключом и удалить старый ключ.

Обновить остатки и получить обычный массивСамостоятельный пример
<?php
declare(strict_types=1);

$stock = new ArrayIterator(['brush' => 2]);
$stock->offsetSet('paint', 3);
$stock->append(7);
echo 'brush exists: ', $stock->offsetExists('brush') ? 'yes' : 'no', "\n";
echo 'paint: ', $stock->offsetGet('paint'), "\n";
$stock->offsetUnset('brush');
echo 'count: ', $stock->count(), "\n";
echo json_encode($stock->getArrayCopy(), JSON_UNESCAPED_UNICODE), "\n";
Ожидаемый результат
brush exists: yes
paint: 3
count: 2
{"paint":3,"0":7}

offsetSet("paint", 3) создал именованный элемент, append(7) выбрал следующий целочисленный ключ 0. После offsetUnset("brush") count() равен двум, а getArrayCopy() вернул независимое обычное представление данных.

Скачать самостоятельный пример с fixtures, результатом и README

Таблица содержит собственные ключи. Перед сортировкой нужно решить: меняется порядок по цене или по артикулу.

Сравнить сортировку по значениям и по ключамСамостоятельный пример
<?php
declare(strict_types=1);

$byValue = new ArrayIterator(['b' => 10, 'a' => 20]);
$byValue->asort();
echo 'asort: ', json_encode($byValue->getArrayCopy()), "\n";
$byKey = new ArrayIterator(['b' => 10, 'a' => 20]);
$byKey->ksort();
echo 'ksort: ', json_encode($byKey->getArrayCopy()), "\n";
Ожидаемый результат
asort: {"b":10,"a":20}
ksort: {"a":20,"b":10}

asort() сравнил значения 10 и 20 и сохранил ключи. ksort() сравнил ключи a и b. Обе операции изменили порядок самого объекта.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

ArrayIterator::getArrayCopy

(PHP 5, PHP 7, PHP 8) ArrayIterator::getArrayCopy — Get array copy

Description

public function ArrayIterator::getArrayCopy(): array

Get a copy of an array.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

A copy of the array, or array of public properties if ArrayIterator refers to an object.

See Also

ArrayIterator::valid() - Check whether array contains more entries

Связанные карточки: ArrayIterator::getArrayCopy, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayIterator::getFlagsArrayIterator::getFlags: прочитать действующую битовую маску режима объекта

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function ArrayIterator::getFlags(): int

ArrayIterator::getFlags нужен, чтобы прочитать действующую битовую маску режима объекта. В этой задаче ArrayIterator помогает обходить и изменять массив через объект с явным курсором, сортировкой, позиционированием и ArrayAccess. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function ArrayIterator::getFlags(): int
Результатint: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения вложенного источника не скрываются. Особые значения, предупреждения и версии перечислены в полном официальном контракте ниже.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Чужой код ожидает краткую запись $row->qty. Флаг меняет способ доступа, но не превращает строку qty в объявленное типизированное свойство.

Включить доступ к ключам как к свойствамСамостоятельный пример
<?php
declare(strict_types=1);

$row = new ArrayIterator(['qty' => 2], ArrayIterator::ARRAY_AS_PROPS);
echo 'qty: ', $row->qty, "\n";
echo 'array-as-props: ', ($row->getFlags() & ArrayIterator::ARRAY_AS_PROPS) ? 'yes' : 'no', "\n";
$row->setFlags(ArrayIterator::STD_PROP_LIST);
echo 'std-prop-list: ', ($row->getFlags() & ArrayIterator::STD_PROP_LIST) ? 'yes' : 'no', "\n";
echo 'array qty stays: ', $row['qty'], "\n";
Ожидаемый результат
qty: 2
array-as-props: yes
std-prop-list: yes
array qty stays: 2

Первый getFlags() подтвердил ARRAY_AS_PROPS. setFlags() заменил маску на STD_PROP_LIST; элемент массива при этом сохранился и читается через $row["qty"].

Скачать самостоятельный пример с fixtures, результатом и README

Остатки уже находятся в ArrayIterator. Нужно добавить именованный товар, добавить значение с автоматическим ключом и удалить старый ключ.

Обновить остатки и получить обычный массивСамостоятельный пример
<?php
declare(strict_types=1);

$stock = new ArrayIterator(['brush' => 2]);
$stock->offsetSet('paint', 3);
$stock->append(7);
echo 'brush exists: ', $stock->offsetExists('brush') ? 'yes' : 'no', "\n";
echo 'paint: ', $stock->offsetGet('paint'), "\n";
$stock->offsetUnset('brush');
echo 'count: ', $stock->count(), "\n";
echo json_encode($stock->getArrayCopy(), JSON_UNESCAPED_UNICODE), "\n";
Ожидаемый результат
brush exists: yes
paint: 3
count: 2
{"paint":3,"0":7}

offsetSet("paint", 3) создал именованный элемент, append(7) выбрал следующий целочисленный ключ 0. После offsetUnset("brush") count() равен двум, а getArrayCopy() вернул независимое обычное представление данных.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

ArrayIterator::getFlags

(PHP 5 >= 5.1.0, PHP 7, PHP 8) ArrayIterator::getFlags — Get behavior flags

Description

public function ArrayIterator::getFlags(): int

Gets the behavior flags of the ArrayIterator. See the ArrayIterator::setFlags method for a list of the available flags.

Parameters

This function has no parameters.

Return Values

Returns the behavior flags of the ArrayIterator.

See Also

ArrayIterator::setFlags() - Set behaviour flags

ArrayIterator::valid() - Check whether array contains more entries

Связанные карточки: ArrayIterator::getArrayCopy, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayIterator::keyArrayIterator::key: получить ключ или позицию текущего элемента

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function ArrayIterator::key(): string|int|null

ArrayIterator::key нужен, чтобы получить ключ или позицию текущего элемента. В этой задаче ArrayIterator помогает обходить и изменять массив через объект с явным курсором, сортировкой, позиционированием и ArrayAccess. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function ArrayIterator::key(): string|int|null
Результатstring|int|null: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияСначала вызывайте valid(). Ключ может быть int, string или составным массивом и не обязан быть бизнес-идентификатором.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Интерфейс хранит текущую позицию списка, а ключи товаров остаются строковыми артикулами.

Перейти ко второму товару каталогаСамостоятельный пример
<?php
declare(strict_types=1);

$catalog = new ArrayIterator([
    'sku-10' => 'Кисть',
    'sku-20' => 'Лак',
    'sku-30' => 'Валик',
]);
$catalog->seek(1);
echo $catalog->key(), ': ', $catalog->current(), "\n";
$catalog->next();
echo $catalog->key(), ': ', $catalog->current(), "\n";
Ожидаемый результат
sku-20: Лак
sku-30: Валик

seek(1) выбрал вторую позицию порядка обхода, хотя её ключ — sku-20. current() вернул название, key() — артикул, next() передвинул курсор на третью позицию.

Скачать самостоятельный пример с fixtures, результатом и README

foreach сам вызывает пять методов Iterator. Этот пример раскрывает тот же порядок явно.

Показать протокол курсора без foreachСамостоятельный пример
<?php
declare(strict_types=1);

$rows = new ArrayIterator(['draft', 'paid']);
$rows->rewind();
while ($rows->valid()) {
    echo $rows->key(), '=', $rows->current(), "\n";
    $rows->next();
}
echo 'После конца valid: ', $rows->valid() ? 'yes' : 'no', "\n";
$rows->rewind();
echo 'После rewind: ', $rows->current(), "\n";
Ожидаемый результат
0=draft
1=paid
После конца valid: no
После rewind: draft

После rewind() valid() разрешает чтение. next() переводит курсор; после последней строки valid() становится false. Новый rewind() возвращает повторяемый ArrayIterator к первой строке.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

ArrayIterator::key

(PHP 5, PHP 7, PHP 8) ArrayIterator::key — Return current array key

Description

public function ArrayIterator::key(): string|int|null

This function returns the current array key

Parameters

This function has no parameters.

Return Values

The current array key.

Связанные карточки: ArrayIterator::getArrayCopy, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayIterator::nextArrayIterator::next: перевести курсор к следующему элементу

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function ArrayIterator::next(): void

ArrayIterator::next нужен, чтобы перевести курсор к следующему элементу. В этой задаче ArrayIterator помогает обходить и изменять массив через объект с явным курсором, сортировкой, позиционированием и ArrayAccess. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function ArrayIterator::next(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияПродвижение одноразового источника нельзя отменить. Исключение из вложенного источника передаётся вызывающему коду.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Интерфейс хранит текущую позицию списка, а ключи товаров остаются строковыми артикулами.

Перейти ко второму товару каталогаСамостоятельный пример
<?php
declare(strict_types=1);

$catalog = new ArrayIterator([
    'sku-10' => 'Кисть',
    'sku-20' => 'Лак',
    'sku-30' => 'Валик',
]);
$catalog->seek(1);
echo $catalog->key(), ': ', $catalog->current(), "\n";
$catalog->next();
echo $catalog->key(), ': ', $catalog->current(), "\n";
Ожидаемый результат
sku-20: Лак
sku-30: Валик

seek(1) выбрал вторую позицию порядка обхода, хотя её ключ — sku-20. current() вернул название, key() — артикул, next() передвинул курсор на третью позицию.

Скачать самостоятельный пример с fixtures, результатом и README

foreach сам вызывает пять методов Iterator. Этот пример раскрывает тот же порядок явно.

Показать протокол курсора без foreachСамостоятельный пример
<?php
declare(strict_types=1);

$rows = new ArrayIterator(['draft', 'paid']);
$rows->rewind();
while ($rows->valid()) {
    echo $rows->key(), '=', $rows->current(), "\n";
    $rows->next();
}
echo 'После конца valid: ', $rows->valid() ? 'yes' : 'no', "\n";
$rows->rewind();
echo 'После rewind: ', $rows->current(), "\n";
Ожидаемый результат
0=draft
1=paid
После конца valid: no
После rewind: draft

После rewind() valid() разрешает чтение. next() переводит курсор; после последней строки valid() становится false. Новый rewind() возвращает повторяемый ArrayIterator к первой строке.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

ArrayIterator::next

(PHP 5, PHP 7, PHP 8) ArrayIterator::next — Move to next entry

Description

public function ArrayIterator::next(): void

Moves the iterator to the next entry.

Parameters

This function has no parameters.

Return Values

No value is returned.

Связанные карточки: ArrayIterator::getArrayCopy, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayIterator::offsetExistsArrayIterator::offsetExists: проверить наличие элемента по ключу без чтения несуществующего значения

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function ArrayIterator::offsetExists(mixed $key): bool

ArrayIterator::offsetExists нужен, чтобы проверить наличие элемента по ключу без чтения несуществующего значения. В этой задаче ArrayIterator помогает обходить и изменять массив через объект с явным курсором, сортировкой, позиционированием и ArrayAccess. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
keyЗначение параметра связано с текущей операцией; допустимый тип и значение по умолчанию видны в сигнатуре, а фактическая роль показана перед примером.
Часть контрактаЧто важно
Сигнатураpublic function ArrayIterator::offsetExists(mixed $key): bool
Результатbool: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения вложенного источника не скрываются. Особые значения, предупреждения и версии перечислены в полном официальном контракте ниже.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Остатки уже находятся в ArrayIterator. Нужно добавить именованный товар, добавить значение с автоматическим ключом и удалить старый ключ.

Обновить остатки и получить обычный массивСамостоятельный пример
<?php
declare(strict_types=1);

$stock = new ArrayIterator(['brush' => 2]);
$stock->offsetSet('paint', 3);
$stock->append(7);
echo 'brush exists: ', $stock->offsetExists('brush') ? 'yes' : 'no', "\n";
echo 'paint: ', $stock->offsetGet('paint'), "\n";
$stock->offsetUnset('brush');
echo 'count: ', $stock->count(), "\n";
echo json_encode($stock->getArrayCopy(), JSON_UNESCAPED_UNICODE), "\n";
Ожидаемый результат
brush exists: yes
paint: 3
count: 2
{"paint":3,"0":7}

offsetSet("paint", 3) создал именованный элемент, append(7) выбрал следующий целочисленный ключ 0. После offsetUnset("brush") count() равен двум, а getArrayCopy() вернул независимое обычное представление данных.

Скачать самостоятельный пример с fixtures, результатом и README

Чужой код ожидает краткую запись $row->qty. Флаг меняет способ доступа, но не превращает строку qty в объявленное типизированное свойство.

Включить доступ к ключам как к свойствамСамостоятельный пример
<?php
declare(strict_types=1);

$row = new ArrayIterator(['qty' => 2], ArrayIterator::ARRAY_AS_PROPS);
echo 'qty: ', $row->qty, "\n";
echo 'array-as-props: ', ($row->getFlags() & ArrayIterator::ARRAY_AS_PROPS) ? 'yes' : 'no', "\n";
$row->setFlags(ArrayIterator::STD_PROP_LIST);
echo 'std-prop-list: ', ($row->getFlags() & ArrayIterator::STD_PROP_LIST) ? 'yes' : 'no', "\n";
echo 'array qty stays: ', $row['qty'], "\n";
Ожидаемый результат
qty: 2
array-as-props: yes
std-prop-list: yes
array qty stays: 2

Первый getFlags() подтвердил ARRAY_AS_PROPS. setFlags() заменил маску на STD_PROP_LIST; элемент массива при этом сохранился и читается через $row["qty"].

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

ArrayIterator::offsetExists

(PHP 5, PHP 7, PHP 8) ArrayIterator::offsetExists — Check if offset exists

Description

public function ArrayIterator::offsetExists(mixed $key): bool

Checks if the offset exists.

WarningThis function is currently not documented; only its argument list is available.

Parameters

key

The offset being checked.

Return Values

true if the offset exists, otherwise false

See Also

ArrayIterator::valid() - Check whether array contains more entries

Связанные карточки: ArrayIterator::getArrayCopy, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayIterator::offsetGetArrayIterator::offsetGet: прочитать элемент по ключу через ArrayAccess

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function ArrayIterator::offsetGet(mixed $key): mixed

ArrayIterator::offsetGet нужен, чтобы прочитать элемент по ключу через ArrayAccess. В этой задаче ArrayIterator помогает обходить и изменять массив через объект с явным курсором, сортировкой, позиционированием и ArrayAccess. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
keyЗначение параметра связано с текущей операцией; допустимый тип и значение по умолчанию видны в сигнатуре, а фактическая роль показана перед примером.
Часть контрактаЧто важно
Сигнатураpublic function ArrayIterator::offsetGet(mixed $key): mixed
Результатmixed: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияЧтение отсутствующего ключа не равно успешному чтению null. Сначала используйте offsetExists()/isset с учётом семантики класса.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Остатки уже находятся в ArrayIterator. Нужно добавить именованный товар, добавить значение с автоматическим ключом и удалить старый ключ.

Обновить остатки и получить обычный массивСамостоятельный пример
<?php
declare(strict_types=1);

$stock = new ArrayIterator(['brush' => 2]);
$stock->offsetSet('paint', 3);
$stock->append(7);
echo 'brush exists: ', $stock->offsetExists('brush') ? 'yes' : 'no', "\n";
echo 'paint: ', $stock->offsetGet('paint'), "\n";
$stock->offsetUnset('brush');
echo 'count: ', $stock->count(), "\n";
echo json_encode($stock->getArrayCopy(), JSON_UNESCAPED_UNICODE), "\n";
Ожидаемый результат
brush exists: yes
paint: 3
count: 2
{"paint":3,"0":7}

offsetSet("paint", 3) создал именованный элемент, append(7) выбрал следующий целочисленный ключ 0. После offsetUnset("brush") count() равен двум, а getArrayCopy() вернул независимое обычное представление данных.

Скачать самостоятельный пример с fixtures, результатом и README

Чужой код ожидает краткую запись $row->qty. Флаг меняет способ доступа, но не превращает строку qty в объявленное типизированное свойство.

Включить доступ к ключам как к свойствамСамостоятельный пример
<?php
declare(strict_types=1);

$row = new ArrayIterator(['qty' => 2], ArrayIterator::ARRAY_AS_PROPS);
echo 'qty: ', $row->qty, "\n";
echo 'array-as-props: ', ($row->getFlags() & ArrayIterator::ARRAY_AS_PROPS) ? 'yes' : 'no', "\n";
$row->setFlags(ArrayIterator::STD_PROP_LIST);
echo 'std-prop-list: ', ($row->getFlags() & ArrayIterator::STD_PROP_LIST) ? 'yes' : 'no', "\n";
echo 'array qty stays: ', $row['qty'], "\n";
Ожидаемый результат
qty: 2
array-as-props: yes
std-prop-list: yes
array qty stays: 2

Первый getFlags() подтвердил ARRAY_AS_PROPS. setFlags() заменил маску на STD_PROP_LIST; элемент массива при этом сохранился и читается через $row["qty"].

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

ArrayIterator::offsetGet

(PHP 5, PHP 7, PHP 8) ArrayIterator::offsetGet — Get value for an offset

Description

public function ArrayIterator::offsetGet(mixed $key): mixed

Gets the value from the provided offset.

WarningThis function is currently not documented; only its argument list is available.

Parameters

key

The offset to get the value from.

Return Values

The value at offset key.

See Also

ArrayIterator::offsetSet() - Set value for an offset

ArrayIterator::offsetUnset() - Unset value for an offset

Связанные карточки: ArrayIterator::getArrayCopy, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayIterator::offsetSetArrayIterator::offsetSet: записать или добавить элемент через ArrayAccess

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function ArrayIterator::offsetSet(mixed $key, mixed $value): void

ArrayIterator::offsetSet нужен, чтобы записать или добавить элемент через ArrayAccess. В этой задаче ArrayIterator помогает обходить и изменять массив через объект с явным курсором, сортировкой, позиционированием и ArrayAccess. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
keyЗначение параметра связано с текущей операцией; допустимый тип и значение по умолчанию видны в сигнатуре, а фактическая роль показана перед примером.
valueЗначение параметра связано с текущей операцией; допустимый тип и значение по умолчанию видны в сигнатуре, а фактическая роль показана перед примером.
Часть контрактаЧто важно
Сигнатураpublic function ArrayIterator::offsetSet(mixed $key, mixed $value): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияНекоторые обёртки запрещают изменение или используют ключи только для кэша. Полный контракт ниже определяет допустимость.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Остатки уже находятся в ArrayIterator. Нужно добавить именованный товар, добавить значение с автоматическим ключом и удалить старый ключ.

Обновить остатки и получить обычный массивСамостоятельный пример
<?php
declare(strict_types=1);

$stock = new ArrayIterator(['brush' => 2]);
$stock->offsetSet('paint', 3);
$stock->append(7);
echo 'brush exists: ', $stock->offsetExists('brush') ? 'yes' : 'no', "\n";
echo 'paint: ', $stock->offsetGet('paint'), "\n";
$stock->offsetUnset('brush');
echo 'count: ', $stock->count(), "\n";
echo json_encode($stock->getArrayCopy(), JSON_UNESCAPED_UNICODE), "\n";
Ожидаемый результат
brush exists: yes
paint: 3
count: 2
{"paint":3,"0":7}

offsetSet("paint", 3) создал именованный элемент, append(7) выбрал следующий целочисленный ключ 0. После offsetUnset("brush") count() равен двум, а getArrayCopy() вернул независимое обычное представление данных.

Скачать самостоятельный пример с fixtures, результатом и README

Чужой код ожидает краткую запись $row->qty. Флаг меняет способ доступа, но не превращает строку qty в объявленное типизированное свойство.

Включить доступ к ключам как к свойствамСамостоятельный пример
<?php
declare(strict_types=1);

$row = new ArrayIterator(['qty' => 2], ArrayIterator::ARRAY_AS_PROPS);
echo 'qty: ', $row->qty, "\n";
echo 'array-as-props: ', ($row->getFlags() & ArrayIterator::ARRAY_AS_PROPS) ? 'yes' : 'no', "\n";
$row->setFlags(ArrayIterator::STD_PROP_LIST);
echo 'std-prop-list: ', ($row->getFlags() & ArrayIterator::STD_PROP_LIST) ? 'yes' : 'no', "\n";
echo 'array qty stays: ', $row['qty'], "\n";
Ожидаемый результат
qty: 2
array-as-props: yes
std-prop-list: yes
array qty stays: 2

Первый getFlags() подтвердил ARRAY_AS_PROPS. setFlags() заменил маску на STD_PROP_LIST; элемент массива при этом сохранился и читается через $row["qty"].

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

ArrayIterator::offsetSet

(PHP 5, PHP 7, PHP 8) ArrayIterator::offsetSet — Set value for an offset

Description

public function ArrayIterator::offsetSet(mixed $key, mixed $value): void

Sets a value for a given offset.

WarningThis function is currently not documented; only its argument list is available.

Parameters

key

The index to set for.

value

The new value to store at the index.

Return Values

No value is returned.

See Also

ArrayIterator::offsetGet() - Get value for an offset

ArrayIterator::offsetUnset() - Unset value for an offset

Связанные карточки: ArrayIterator::getArrayCopy, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayIterator::offsetUnsetArrayIterator::offsetUnset: удалить элемент по ключу через ArrayAccess

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function ArrayIterator::offsetUnset(mixed $key): void

ArrayIterator::offsetUnset нужен, чтобы удалить элемент по ключу через ArrayAccess. В этой задаче ArrayIterator помогает обходить и изменять массив через объект с явным курсором, сортировкой, позиционированием и ArrayAccess. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
keyЗначение параметра связано с текущей операцией; допустимый тип и значение по умолчанию видны в сигнатуре, а фактическая роль показана перед примером.
Часть контрактаЧто важно
Сигнатураpublic function ArrayIterator::offsetUnset(mixed $key): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияУдаление меняет контейнер или кэш; курсор и последующие ключи могут измениться.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Остатки уже находятся в ArrayIterator. Нужно добавить именованный товар, добавить значение с автоматическим ключом и удалить старый ключ.

Обновить остатки и получить обычный массивСамостоятельный пример
<?php
declare(strict_types=1);

$stock = new ArrayIterator(['brush' => 2]);
$stock->offsetSet('paint', 3);
$stock->append(7);
echo 'brush exists: ', $stock->offsetExists('brush') ? 'yes' : 'no', "\n";
echo 'paint: ', $stock->offsetGet('paint'), "\n";
$stock->offsetUnset('brush');
echo 'count: ', $stock->count(), "\n";
echo json_encode($stock->getArrayCopy(), JSON_UNESCAPED_UNICODE), "\n";
Ожидаемый результат
brush exists: yes
paint: 3
count: 2
{"paint":3,"0":7}

offsetSet("paint", 3) создал именованный элемент, append(7) выбрал следующий целочисленный ключ 0. После offsetUnset("brush") count() равен двум, а getArrayCopy() вернул независимое обычное представление данных.

Скачать самостоятельный пример с fixtures, результатом и README

Интерфейс хранит текущую позицию списка, а ключи товаров остаются строковыми артикулами.

Перейти ко второму товару каталогаСамостоятельный пример
<?php
declare(strict_types=1);

$catalog = new ArrayIterator([
    'sku-10' => 'Кисть',
    'sku-20' => 'Лак',
    'sku-30' => 'Валик',
]);
$catalog->seek(1);
echo $catalog->key(), ': ', $catalog->current(), "\n";
$catalog->next();
echo $catalog->key(), ': ', $catalog->current(), "\n";
Ожидаемый результат
sku-20: Лак
sku-30: Валик

seek(1) выбрал вторую позицию порядка обхода, хотя её ключ — sku-20. current() вернул название, key() — артикул, next() передвинул курсор на третью позицию.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

ArrayIterator::offsetUnset

(PHP 5, PHP 7, PHP 8) ArrayIterator::offsetUnset — Unset value for an offset

Description

public function ArrayIterator::offsetUnset(mixed $key): void

Unsets a value for an offset.

If iteration is in progress, and ArrayIterator::offsetUnset() is used to unset the current index of iteration, the iteration position will be advanced to the next index. Since the iteration position is also advanced at the end of a foreach loop body, use of ArrayIterator::offsetUnset() inside a foreach loop may result in indices being skipped.

Parameters

key

The offset to unset.

Return Values

No value is returned.

See Also

ArrayIterator::offsetGet() - Get value for an offset

ArrayIterator::offsetSet() - Set value for an offset

Связанные карточки: ArrayIterator::getArrayCopy, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayIterator::rewindArrayIterator::rewind: попытаться установить курсор на первый элемент

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function ArrayIterator::rewind(): void

ArrayIterator::rewind нужен, чтобы попытаться установить курсор на первый элемент. В этой задаче ArrayIterator помогает обходить и изменять массив через объект с явным курсором, сортировкой, позиционированием и ArrayAccess. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function ArrayIterator::rewind(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияНе каждый Traversable можно повторить. NoRewindIterator намеренно игнорирует повторную перемотку, а Generator после завершения может выбросить исключение.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

foreach сам вызывает пять методов Iterator. Этот пример раскрывает тот же порядок явно.

Показать протокол курсора без foreachСамостоятельный пример
<?php
declare(strict_types=1);

$rows = new ArrayIterator(['draft', 'paid']);
$rows->rewind();
while ($rows->valid()) {
    echo $rows->key(), '=', $rows->current(), "\n";
    $rows->next();
}
echo 'После конца valid: ', $rows->valid() ? 'yes' : 'no', "\n";
$rows->rewind();
echo 'После rewind: ', $rows->current(), "\n";
Ожидаемый результат
0=draft
1=paid
После конца valid: no
После rewind: draft

После rewind() valid() разрешает чтение. next() переводит курсор; после последней строки valid() становится false. Новый rewind() возвращает повторяемый ArrayIterator к первой строке.

Скачать самостоятельный пример с fixtures, результатом и README

Интерфейс хранит текущую позицию списка, а ключи товаров остаются строковыми артикулами.

Перейти ко второму товару каталогаСамостоятельный пример
<?php
declare(strict_types=1);

$catalog = new ArrayIterator([
    'sku-10' => 'Кисть',
    'sku-20' => 'Лак',
    'sku-30' => 'Валик',
]);
$catalog->seek(1);
echo $catalog->key(), ': ', $catalog->current(), "\n";
$catalog->next();
echo $catalog->key(), ': ', $catalog->current(), "\n";
Ожидаемый результат
sku-20: Лак
sku-30: Валик

seek(1) выбрал вторую позицию порядка обхода, хотя её ключ — sku-20. current() вернул название, key() — артикул, next() передвинул курсор на третью позицию.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

ArrayIterator::rewind

(PHP 5, PHP 7, PHP 8) ArrayIterator::rewind — Rewind array back to the start

Description

public function ArrayIterator::rewind(): void

This rewinds the iterator to the beginning.

Parameters

This function has no parameters.

Return Values

No value is returned.

Связанные карточки: ArrayIterator::getArrayCopy, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayIterator::seekArrayIterator::seek: перейти к заданной позиции обхода

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function ArrayIterator::seek(int $offset): void

ArrayIterator::seek нужен, чтобы перейти к заданной позиции обхода. В этой задаче ArrayIterator помогает обходить и изменять массив через объект с явным курсором, сортировкой, позиционированием и ArrayAccess. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
offsetПозиция от нуля. Это место в порядке обхода, а не бизнес-ID записи.
Часть контрактаЧто важно
Сигнатураpublic function ArrayIterator::seek(int $offset): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияНедоступная позиция вызывает OutOfBoundsException. Позиции считаются в порядке данного итератора, а не по ключам исходных данных.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Интерфейс хранит текущую позицию списка, а ключи товаров остаются строковыми артикулами.

Перейти ко второму товару каталогаСамостоятельный пример
<?php
declare(strict_types=1);

$catalog = new ArrayIterator([
    'sku-10' => 'Кисть',
    'sku-20' => 'Лак',
    'sku-30' => 'Валик',
]);
$catalog->seek(1);
echo $catalog->key(), ': ', $catalog->current(), "\n";
$catalog->next();
echo $catalog->key(), ': ', $catalog->current(), "\n";
Ожидаемый результат
sku-20: Лак
sku-30: Валик

seek(1) выбрал вторую позицию порядка обхода, хотя её ключ — sku-20. current() вернул название, key() — артикул, next() передвинул курсор на третью позицию.

Скачать самостоятельный пример с fixtures, результатом и README

foreach сам вызывает пять методов Iterator. Этот пример раскрывает тот же порядок явно.

Показать протокол курсора без foreachСамостоятельный пример
<?php
declare(strict_types=1);

$rows = new ArrayIterator(['draft', 'paid']);
$rows->rewind();
while ($rows->valid()) {
    echo $rows->key(), '=', $rows->current(), "\n";
    $rows->next();
}
echo 'После конца valid: ', $rows->valid() ? 'yes' : 'no', "\n";
$rows->rewind();
echo 'После rewind: ', $rows->current(), "\n";
Ожидаемый результат
0=draft
1=paid
После конца valid: no
После rewind: draft

После rewind() valid() разрешает чтение. next() переводит курсор; после последней строки valid() становится false. Новый rewind() возвращает повторяемый ArrayIterator к первой строке.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

ArrayIterator::seek

(PHP 5, PHP 7, PHP 8) ArrayIterator::seek — Seeks to a position

Description

public function ArrayIterator::seek(int $offset): void

Seeks to a given position in the iterator.

Parameters

offset

The position to seek to.

Return Values

No value is returned.

Errors/Exceptions

Throws an OutOfBoundsException if the offset is not seekable.

Связанные карточки: ArrayIterator::getArrayCopy, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayIterator::serializeArrayIterator::serialize: получить сериализованное представление состояния

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function ArrayIterator::serialize(): string

ArrayIterator::serialize нужен, чтобы получить сериализованное представление состояния. В этой задаче ArrayIterator помогает обходить и изменять массив через объект с явным курсором, сортировкой, позиционированием и ArrayAccess. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function ArrayIterator::serialize(): string
Результатstring: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияФормат предназначен для совместимого PHP-состояния и не является безопасным форматом недоверенного обмена.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Пример сохраняет только что созданное доверенное состояние и сразу восстанавливает его в том же runtime.

Сохранить и восстановить локальное состояниеСамостоятельный пример
<?php
declare(strict_types=1);

$before = new ArrayIterator(['draft' => 2], ArrayIterator::ARRAY_AS_PROPS);
$payload = $before->serialize();
$after = new ArrayIterator();
$after->unserialize($payload);
echo 'payload bytes: ', strlen($payload) > 0 ? 'yes' : 'no', "\n";
echo 'draft: ', $after['draft'], "\n";
echo 'array-as-props: ', ($after->getFlags() & ArrayIterator::ARRAY_AS_PROPS) ? 'yes' : 'no', "\n";
Ожидаемый результат
payload bytes: yes
draft: 2
array-as-props: yes

serialize() вернул непустую строку внутреннего формата. unserialize() изменил пустой объект: восстановились значение draft и маска ARRAY_AS_PROPS. Это не JSON и не формат для клиентского ввода.

Скачать самостоятельный пример с fixtures, результатом и README

Остатки уже находятся в ArrayIterator. Нужно добавить именованный товар, добавить значение с автоматическим ключом и удалить старый ключ.

Обновить остатки и получить обычный массивСамостоятельный пример
<?php
declare(strict_types=1);

$stock = new ArrayIterator(['brush' => 2]);
$stock->offsetSet('paint', 3);
$stock->append(7);
echo 'brush exists: ', $stock->offsetExists('brush') ? 'yes' : 'no', "\n";
echo 'paint: ', $stock->offsetGet('paint'), "\n";
$stock->offsetUnset('brush');
echo 'count: ', $stock->count(), "\n";
echo json_encode($stock->getArrayCopy(), JSON_UNESCAPED_UNICODE), "\n";
Ожидаемый результат
brush exists: yes
paint: 3
count: 2
{"paint":3,"0":7}

offsetSet("paint", 3) создал именованный элемент, append(7) выбрал следующий целочисленный ключ 0. После offsetUnset("brush") count() равен двум, а getArrayCopy() вернул независимое обычное представление данных.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

ArrayIterator::serialize

(PHP 5 >= 5.3.0, PHP 7, PHP 8) ArrayIterator::serialize — Serialize

Description

public function ArrayIterator::serialize(): string

Serialize.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

The serialized ArrayIterator.

See Also

ArrayIterator::unserialize() - Unserialize

Связанные карточки: ArrayIterator::getArrayCopy, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayIterator::setFlagsArrayIterator::setFlags: заменить действующую битовую маску режима

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function ArrayIterator::setFlags(int $flags): void

ArrayIterator::setFlags нужен, чтобы заменить действующую битовую маску режима. В этой задаче ArrayIterator помогает обходить и изменять массив через объект с явным курсором, сортировкой, позиционированием и ArrayAccess. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
flagsБитовая маска режима. Оператор | объединяет совместимые константы; setFlags заменяет прежнюю маску целиком.
Часть контрактаЧто важно
Сигнатураpublic function ArrayIterator::setFlags(int $flags): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияНеверная комбинация констант может дать ValueError либо неожиданную форму current/key; проверяйте полный контракт.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Чужой код ожидает краткую запись $row->qty. Флаг меняет способ доступа, но не превращает строку qty в объявленное типизированное свойство.

Включить доступ к ключам как к свойствамСамостоятельный пример
<?php
declare(strict_types=1);

$row = new ArrayIterator(['qty' => 2], ArrayIterator::ARRAY_AS_PROPS);
echo 'qty: ', $row->qty, "\n";
echo 'array-as-props: ', ($row->getFlags() & ArrayIterator::ARRAY_AS_PROPS) ? 'yes' : 'no', "\n";
$row->setFlags(ArrayIterator::STD_PROP_LIST);
echo 'std-prop-list: ', ($row->getFlags() & ArrayIterator::STD_PROP_LIST) ? 'yes' : 'no', "\n";
echo 'array qty stays: ', $row['qty'], "\n";
Ожидаемый результат
qty: 2
array-as-props: yes
std-prop-list: yes
array qty stays: 2

Первый getFlags() подтвердил ARRAY_AS_PROPS. setFlags() заменил маску на STD_PROP_LIST; элемент массива при этом сохранился и читается через $row["qty"].

Скачать самостоятельный пример с fixtures, результатом и README

Остатки уже находятся в ArrayIterator. Нужно добавить именованный товар, добавить значение с автоматическим ключом и удалить старый ключ.

Обновить остатки и получить обычный массивСамостоятельный пример
<?php
declare(strict_types=1);

$stock = new ArrayIterator(['brush' => 2]);
$stock->offsetSet('paint', 3);
$stock->append(7);
echo 'brush exists: ', $stock->offsetExists('brush') ? 'yes' : 'no', "\n";
echo 'paint: ', $stock->offsetGet('paint'), "\n";
$stock->offsetUnset('brush');
echo 'count: ', $stock->count(), "\n";
echo json_encode($stock->getArrayCopy(), JSON_UNESCAPED_UNICODE), "\n";
Ожидаемый результат
brush exists: yes
paint: 3
count: 2
{"paint":3,"0":7}

offsetSet("paint", 3) создал именованный элемент, append(7) выбрал следующий целочисленный ключ 0. После offsetUnset("brush") count() равен двум, а getArrayCopy() вернул независимое обычное представление данных.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

ArrayIterator::setFlags

(PHP 5 >= 5.1.0, PHP 7, PHP 8) ArrayIterator::setFlags — Set behaviour flags

Description

public function ArrayIterator::setFlags(int $flags): void

Set the flags that change the behavior of the ArrayIterator.

Parameters

flags

The new ArrayIterator behavior. It takes on either a bitmask, or named constants. Using named constants is strongly encouraged to ensure compatibility for future versions.

The available behavior flags are listed below. The actual meanings of these flags are described in the predefined constants.

ArrayIterator behavior flags

value constant

1

ArrayIterator::STD_PROP_LIST

2

ArrayIterator::ARRAY_AS_PROPS

Return Values

No value is returned.

See Also

ArrayIterator::getFlags() - Get behavior flags

Связанные карточки: ArrayIterator::getArrayCopy, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayIterator::unserializeArrayIterator::unserialize: восстановить состояние из совместимой сериализованной строки

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function ArrayIterator::unserialize(string $data): void

ArrayIterator::unserialize нужен, чтобы восстановить состояние из совместимой сериализованной строки. В этой задаче ArrayIterator помогает обходить и изменять массив через объект с явным курсором, сортировкой, позиционированием и ArrayAccess. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
dataЗначение параметра связано с текущей операцией; допустимый тип и значение по умолчанию видны в сигнатуре, а фактическая роль показана перед примером.
Часть контрактаЧто важно
Сигнатураpublic function ArrayIterator::unserialize(string $data): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияНе передавайте строку от клиента: десериализация объектов имеет отдельные риски и ограничения совместимости.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Пример сохраняет только что созданное доверенное состояние и сразу восстанавливает его в том же runtime.

Сохранить и восстановить локальное состояниеСамостоятельный пример
<?php
declare(strict_types=1);

$before = new ArrayIterator(['draft' => 2], ArrayIterator::ARRAY_AS_PROPS);
$payload = $before->serialize();
$after = new ArrayIterator();
$after->unserialize($payload);
echo 'payload bytes: ', strlen($payload) > 0 ? 'yes' : 'no', "\n";
echo 'draft: ', $after['draft'], "\n";
echo 'array-as-props: ', ($after->getFlags() & ArrayIterator::ARRAY_AS_PROPS) ? 'yes' : 'no', "\n";
Ожидаемый результат
payload bytes: yes
draft: 2
array-as-props: yes

serialize() вернул непустую строку внутреннего формата. unserialize() изменил пустой объект: восстановились значение draft и маска ARRAY_AS_PROPS. Это не JSON и не формат для клиентского ввода.

Скачать самостоятельный пример с fixtures, результатом и README

Чужой код ожидает краткую запись $row->qty. Флаг меняет способ доступа, но не превращает строку qty в объявленное типизированное свойство.

Включить доступ к ключам как к свойствамСамостоятельный пример
<?php
declare(strict_types=1);

$row = new ArrayIterator(['qty' => 2], ArrayIterator::ARRAY_AS_PROPS);
echo 'qty: ', $row->qty, "\n";
echo 'array-as-props: ', ($row->getFlags() & ArrayIterator::ARRAY_AS_PROPS) ? 'yes' : 'no', "\n";
$row->setFlags(ArrayIterator::STD_PROP_LIST);
echo 'std-prop-list: ', ($row->getFlags() & ArrayIterator::STD_PROP_LIST) ? 'yes' : 'no', "\n";
echo 'array qty stays: ', $row['qty'], "\n";
Ожидаемый результат
qty: 2
array-as-props: yes
std-prop-list: yes
array qty stays: 2

Первый getFlags() подтвердил ARRAY_AS_PROPS. setFlags() заменил маску на STD_PROP_LIST; элемент массива при этом сохранился и читается через $row["qty"].

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

ArrayIterator::unserialize

(PHP 5 >= 5.3.0, PHP 7, PHP 8) ArrayIterator::unserialize — Unserialize

Description

public function ArrayIterator::unserialize(string $data): void

Unserialize.

WarningThis function is currently not documented; only its argument list is available.

Parameters

data

The serialized ArrayIterator object to be unserialized.

Return Values

No value is returned.

See Also

ArrayIterator::serialize() - Serialize

Связанные карточки: ArrayIterator::getArrayCopy, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayIterator::validArrayIterator::valid: проверить, указывает ли курсор на существующий элемент

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function ArrayIterator::valid(): bool

ArrayIterator::valid нужен, чтобы проверить, указывает ли курсор на существующий элемент. В этой задаче ArrayIterator помогает обходить и изменять массив через объект с явным курсором, сортировкой, позиционированием и ArrayAccess. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function ArrayIterator::valid(): bool
Результатbool: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияfalse означает отсутствие текущего элемента, а не ошибку бизнес-данных. Ошибки источника могут возникнуть отдельно.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

foreach сам вызывает пять методов Iterator. Этот пример раскрывает тот же порядок явно.

Показать протокол курсора без foreachСамостоятельный пример
<?php
declare(strict_types=1);

$rows = new ArrayIterator(['draft', 'paid']);
$rows->rewind();
while ($rows->valid()) {
    echo $rows->key(), '=', $rows->current(), "\n";
    $rows->next();
}
echo 'После конца valid: ', $rows->valid() ? 'yes' : 'no', "\n";
$rows->rewind();
echo 'После rewind: ', $rows->current(), "\n";
Ожидаемый результат
0=draft
1=paid
После конца valid: no
После rewind: draft

После rewind() valid() разрешает чтение. next() переводит курсор; после последней строки valid() становится false. Новый rewind() возвращает повторяемый ArrayIterator к первой строке.

Скачать самостоятельный пример с fixtures, результатом и README

Интерфейс хранит текущую позицию списка, а ключи товаров остаются строковыми артикулами.

Перейти ко второму товару каталогаСамостоятельный пример
<?php
declare(strict_types=1);

$catalog = new ArrayIterator([
    'sku-10' => 'Кисть',
    'sku-20' => 'Лак',
    'sku-30' => 'Валик',
]);
$catalog->seek(1);
echo $catalog->key(), ': ', $catalog->current(), "\n";
$catalog->next();
echo $catalog->key(), ': ', $catalog->current(), "\n";
Ожидаемый результат
sku-20: Лак
sku-30: Валик

seek(1) выбрал вторую позицию порядка обхода, хотя её ключ — sku-20. current() вернул название, key() — артикул, next() передвинул курсор на третью позицию.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

ArrayIterator::valid

(PHP 5, PHP 7, PHP 8) ArrayIterator::valid — Check whether array contains more entries

Description

public function ArrayIterator::valid(): bool

Checks if the array contains any more entries.

Parameters

This function has no parameters.

Return Values

Returns true if the iterator is valid, otherwise false

Связанные карточки: ArrayIterator::getArrayCopy, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayIterator::asortArrayIterator::asort: отсортировать значения, сохранив их ключи

PHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.0.0) · SPL

public function ArrayIterator::asort(int $flags = SORT_REGULAR): true

ArrayIterator::asort нужен, чтобы отсортировать значения, сохранив их ключи. В этой задаче ArrayIterator помогает обходить и изменять массив через объект с явным курсором, сортировкой, позиционированием и ArrayAccess. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
flagsБитовая маска режима. Оператор | объединяет совместимые константы; setFlags заменяет прежнюю маску целиком.
Часть контрактаЧто важно
Сигнатураpublic function ArrayIterator::asort(int $flags = SORT_REGULAR): true
Результатtrue: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения вложенного источника не скрываются. Особые значения, предупреждения и версии перечислены в полном официальном контракте ниже.
ВерсииPHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.0.0)

Таблица содержит собственные ключи. Перед сортировкой нужно решить: меняется порядок по цене или по артикулу.

Сравнить сортировку по значениям и по ключамСамостоятельный пример
<?php
declare(strict_types=1);

$byValue = new ArrayIterator(['b' => 10, 'a' => 20]);
$byValue->asort();
echo 'asort: ', json_encode($byValue->getArrayCopy()), "\n";
$byKey = new ArrayIterator(['b' => 10, 'a' => 20]);
$byKey->ksort();
echo 'ksort: ', json_encode($byKey->getArrayCopy()), "\n";
Ожидаемый результат
asort: {"b":10,"a":20}
ksort: {"a":20,"b":10}

asort() сравнил значения 10 и 20 и сохранил ключи. ksort() сравнил ключи a и b. Обе операции изменили порядок самого объекта.

Скачать самостоятельный пример с fixtures, результатом и README

Стандартного порядка недостаточно: остатки сортируют по числу, а артикулы — по длине ключа.

Задать бизнес-порядок значений и ключейСамостоятельный пример
<?php
declare(strict_types=1);

$byQty = new ArrayIterator(['brush' => 12, 'paint' => 3, 'roller' => 7]);
$byQty->uasort(fn(int $left, int $right): int => $left <=> $right);
echo 'qty: ', json_encode($byQty->getArrayCopy()), "\n";
$bySkuLength = new ArrayIterator(['long-sku' => 1, 'x' => 2, 'mid' => 3]);
$bySkuLength->uksort(fn(string $left, string $right): int => strlen($left) <=> strlen($right));
echo 'keys: ', implode(',', array_keys($bySkuLength->getArrayCopy())), "\n";
Ожидаемый результат
qty: {"paint":3,"roller":7,"brush":12}
keys: x,mid,long-sku

uasort() передавал callback два значения и сохранил ключи. uksort() передавал два ключа. Оператор <=> вернул отрицательное, ноль или положительное число; callback не изменял исходные элементы.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

ArrayIterator::asort

(PHP 5 >= 5.2.0, PHP 7, PHP 8) ArrayIterator::asort — Sort entries by values

Description

public function ArrayIterator::asort(int $flags = SORT_REGULAR): true

Sorts entries by their values.

Note:

If two members compare as equal, they retain their original order. Prior to PHP 8.0.0, their relative order in the sorted array was undefined.

Parameters

flags

The optional second parameter flags may be used to modify the sorting behavior using these values:

Sorting type flags:

SORT_REGULAR - compare items normally; the details are described in the comparison operators section

SORT_NUMERIC - compare items numerically

SORT_STRING - compare items as strings

SORT_LOCALE_STRING - compare items as strings, based on the current locale. It uses the locale, which can be changed using setlocale()

SORT_NATURAL - compare items as strings using "natural ordering" like natsort()

SORT_FLAG_CASE - can be combined (bitwise OR) with SORT_STRING or SORT_NATURAL to sort strings case-insensitively

Return Values

Always returns true.

Changelog

Version Description

8.2.0

The return type is true now; previously, it was bool.

See Also

ArrayIterator::ksort() - Sort entries by keys

ArrayIterator::natcasesort() - Sort entries naturally, case insensitive

ArrayIterator::natsort() - Sort entries naturally

ArrayIterator::uasort() - Sort with a user-defined comparison function and maintain index association

ArrayIterator::uksort() - Sort by keys using a user-defined comparison function

asort() - Sort an array in ascending order and maintain index association

Связанные карточки: ArrayIterator::getArrayCopy, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayIterator::ksortArrayIterator::ksort: отсортировать элементы по ключам

PHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.0.0) · SPL

public function ArrayIterator::ksort(int $flags = SORT_REGULAR): true

ArrayIterator::ksort нужен, чтобы отсортировать элементы по ключам. В этой задаче ArrayIterator помогает обходить и изменять массив через объект с явным курсором, сортировкой, позиционированием и ArrayAccess. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
flagsБитовая маска режима. Оператор | объединяет совместимые константы; setFlags заменяет прежнюю маску целиком.
Часть контрактаЧто важно
Сигнатураpublic function ArrayIterator::ksort(int $flags = SORT_REGULAR): true
Результатtrue: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения вложенного источника не скрываются. Особые значения, предупреждения и версии перечислены в полном официальном контракте ниже.
ВерсииPHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.0.0)

Таблица содержит собственные ключи. Перед сортировкой нужно решить: меняется порядок по цене или по артикулу.

Сравнить сортировку по значениям и по ключамСамостоятельный пример
<?php
declare(strict_types=1);

$byValue = new ArrayIterator(['b' => 10, 'a' => 20]);
$byValue->asort();
echo 'asort: ', json_encode($byValue->getArrayCopy()), "\n";
$byKey = new ArrayIterator(['b' => 10, 'a' => 20]);
$byKey->ksort();
echo 'ksort: ', json_encode($byKey->getArrayCopy()), "\n";
Ожидаемый результат
asort: {"b":10,"a":20}
ksort: {"a":20,"b":10}

asort() сравнил значения 10 и 20 и сохранил ключи. ksort() сравнил ключи a и b. Обе операции изменили порядок самого объекта.

Скачать самостоятельный пример с fixtures, результатом и README

Стандартного порядка недостаточно: остатки сортируют по числу, а артикулы — по длине ключа.

Задать бизнес-порядок значений и ключейСамостоятельный пример
<?php
declare(strict_types=1);

$byQty = new ArrayIterator(['brush' => 12, 'paint' => 3, 'roller' => 7]);
$byQty->uasort(fn(int $left, int $right): int => $left <=> $right);
echo 'qty: ', json_encode($byQty->getArrayCopy()), "\n";
$bySkuLength = new ArrayIterator(['long-sku' => 1, 'x' => 2, 'mid' => 3]);
$bySkuLength->uksort(fn(string $left, string $right): int => strlen($left) <=> strlen($right));
echo 'keys: ', implode(',', array_keys($bySkuLength->getArrayCopy())), "\n";
Ожидаемый результат
qty: {"paint":3,"roller":7,"brush":12}
keys: x,mid,long-sku

uasort() передавал callback два значения и сохранил ключи. uksort() передавал два ключа. Оператор <=> вернул отрицательное, ноль или положительное число; callback не изменял исходные элементы.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

ArrayIterator::ksort

(PHP 5 >= 5.2.0, PHP 7, PHP 8) ArrayIterator::ksort — Sort entries by keys

Description

public function ArrayIterator::ksort(int $flags = SORT_REGULAR): true

Sorts entries by their keys.

Note:

If two members compare as equal, they retain their original order. Prior to PHP 8.0.0, their relative order in the sorted array was undefined.

Parameters

flags

The optional second parameter flags may be used to modify the sorting behavior using these values:

Sorting type flags:

SORT_REGULAR - compare items normally; the details are described in the comparison operators section

SORT_NUMERIC - compare items numerically

SORT_STRING - compare items as strings

SORT_LOCALE_STRING - compare items as strings, based on the current locale. It uses the locale, which can be changed using setlocale()

SORT_NATURAL - compare items as strings using "natural ordering" like natsort()

SORT_FLAG_CASE - can be combined (bitwise OR) with SORT_STRING or SORT_NATURAL to sort strings case-insensitively

Return Values

Always returns true.

Changelog

Version Description

8.2.0

The return type is true now; previously, it was bool.

See Also

ArrayIterator::asort() - Sort entries by values

ArrayIterator::natcasesort() - Sort entries naturally, case insensitive

ArrayIterator::natsort() - Sort entries naturally

ArrayIterator::uasort() - Sort with a user-defined comparison function and maintain index association

ArrayIterator::uksort() - Sort by keys using a user-defined comparison function

ksort() - Sort an array by key in ascending order

Связанные карточки: ArrayIterator::getArrayCopy, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayIterator::natsortArrayIterator::natsort: отсортировать значения естественно с учётом регистра

PHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.0.0) · SPL

public function ArrayIterator::natsort(): true

ArrayIterator::natsort нужен, чтобы отсортировать значения естественно с учётом регистра. В этой задаче ArrayIterator помогает обходить и изменять массив через объект с явным курсором, сортировкой, позиционированием и ArrayAccess. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function ArrayIterator::natsort(): true
Результатtrue: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения вложенного источника не скрываются. Особые значения, предупреждения и версии перечислены в полном официальном контракте ниже.
ВерсииPHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.0.0)

Лексикографическая сортировка ставит file10 перед file2. Natural sort учитывает числовые части имени.

Отсортировать номера файлов по-человеческиСамостоятельный пример
<?php
declare(strict_types=1);

$sensitive = new ArrayIterator(['file10', 'file2', 'File1']);
$sensitive->natsort();
echo 'natsort: ', implode(',', $sensitive->getArrayCopy()), "\n";
$folded = new ArrayIterator(['file10', 'file2', 'File1']);
$folded->natcasesort();
echo 'natcasesort: ', implode(',', $folded->getArrayCopy()), "\n";
Ожидаемый результат
natsort: File1,file2,file10
natcasesort: File1,file2,file10

Обе операции сохранили исходные ключи, но implode показал новый порядок значений. natcasesort() дополнительно не учитывает регистр при сравнении.

Скачать самостоятельный пример с fixtures, результатом и README

Таблица содержит собственные ключи. Перед сортировкой нужно решить: меняется порядок по цене или по артикулу.

Сравнить сортировку по значениям и по ключамСамостоятельный пример
<?php
declare(strict_types=1);

$byValue = new ArrayIterator(['b' => 10, 'a' => 20]);
$byValue->asort();
echo 'asort: ', json_encode($byValue->getArrayCopy()), "\n";
$byKey = new ArrayIterator(['b' => 10, 'a' => 20]);
$byKey->ksort();
echo 'ksort: ', json_encode($byKey->getArrayCopy()), "\n";
Ожидаемый результат
asort: {"b":10,"a":20}
ksort: {"a":20,"b":10}

asort() сравнил значения 10 и 20 и сохранил ключи. ksort() сравнил ключи a и b. Обе операции изменили порядок самого объекта.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

ArrayIterator::natsort

(PHP 5 >= 5.2.0, PHP 7, PHP 8) ArrayIterator::natsort — Sort entries naturally

Description

public function ArrayIterator::natsort(): true

Sort the entries by values using a "natural order" algorithm.

Note:

If two members compare as equal, they retain their original order. Prior to PHP 8.0.0, their relative order in the sorted array was undefined.

Parameters

This function has no parameters.

Return Values

Always returns true.

Changelog

Version Description

8.2.0

The return type is true now; previously, it was bool.

See Also

ArrayIterator::asort() - Sort entries by values

ArrayIterator::ksort() - Sort entries by keys

ArrayIterator::natcasesort() - Sort entries naturally, case insensitive

ArrayIterator::uasort() - Sort with a user-defined comparison function and maintain index association

ArrayIterator::uksort() - Sort by keys using a user-defined comparison function

natsort() - Sort an array using a "natural order" algorithm

Связанные карточки: ArrayIterator::getArrayCopy, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayIterator::natcasesortArrayIterator::natcasesort: отсортировать значения естественно без учёта регистра

PHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.0.0) · SPL

public function ArrayIterator::natcasesort(): true

ArrayIterator::natcasesort нужен, чтобы отсортировать значения естественно без учёта регистра. В этой задаче ArrayIterator помогает обходить и изменять массив через объект с явным курсором, сортировкой, позиционированием и ArrayAccess. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function ArrayIterator::natcasesort(): true
Результатtrue: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения вложенного источника не скрываются. Особые значения, предупреждения и версии перечислены в полном официальном контракте ниже.
ВерсииPHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.0.0)

Лексикографическая сортировка ставит file10 перед file2. Natural sort учитывает числовые части имени.

Отсортировать номера файлов по-человеческиСамостоятельный пример
<?php
declare(strict_types=1);

$sensitive = new ArrayIterator(['file10', 'file2', 'File1']);
$sensitive->natsort();
echo 'natsort: ', implode(',', $sensitive->getArrayCopy()), "\n";
$folded = new ArrayIterator(['file10', 'file2', 'File1']);
$folded->natcasesort();
echo 'natcasesort: ', implode(',', $folded->getArrayCopy()), "\n";
Ожидаемый результат
natsort: File1,file2,file10
natcasesort: File1,file2,file10

Обе операции сохранили исходные ключи, но implode показал новый порядок значений. natcasesort() дополнительно не учитывает регистр при сравнении.

Скачать самостоятельный пример с fixtures, результатом и README

Таблица содержит собственные ключи. Перед сортировкой нужно решить: меняется порядок по цене или по артикулу.

Сравнить сортировку по значениям и по ключамСамостоятельный пример
<?php
declare(strict_types=1);

$byValue = new ArrayIterator(['b' => 10, 'a' => 20]);
$byValue->asort();
echo 'asort: ', json_encode($byValue->getArrayCopy()), "\n";
$byKey = new ArrayIterator(['b' => 10, 'a' => 20]);
$byKey->ksort();
echo 'ksort: ', json_encode($byKey->getArrayCopy()), "\n";
Ожидаемый результат
asort: {"b":10,"a":20}
ksort: {"a":20,"b":10}

asort() сравнил значения 10 и 20 и сохранил ключи. ksort() сравнил ключи a и b. Обе операции изменили порядок самого объекта.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

ArrayIterator::natcasesort

(PHP 5 >= 5.2.0, PHP 7, PHP 8) ArrayIterator::natcasesort — Sort entries naturally, case insensitive

Description

public function ArrayIterator::natcasesort(): true

Sort the entries by values using a case insensitive "natural order" algorithm.

Note:

If two members compare as equal, they retain their original order. Prior to PHP 8.0.0, their relative order in the sorted array was undefined.

Parameters

This function has no parameters.

Return Values

Always returns true.

Changelog

Version Description

8.2.0

The return type is true now; previously, it was bool.

See Also

ArrayIterator::asort() - Sort entries by values

ArrayIterator::ksort() - Sort entries by keys

ArrayIterator::natsort() - Sort entries naturally

ArrayIterator::uasort() - Sort with a user-defined comparison function and maintain index association

ArrayIterator::uksort() - Sort by keys using a user-defined comparison function

natcasesort() - Sort an array using a case insensitive "natural order" algorithm

Связанные карточки: ArrayIterator::getArrayCopy, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayIterator::uasortArrayIterator::uasort: отсортировать значения пользовательским сравнением, сохранив ключи

PHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.0.0) · SPL

public function ArrayIterator::uasort(callable $callback): true

ArrayIterator::uasort нужен, чтобы отсортировать значения пользовательским сравнением, сохранив ключи. В этой задаче ArrayIterator помогает обходить и изменять массив через объект с явным курсором, сортировкой, позиционированием и ArrayAccess. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
callbackФункция, которая получает текущие данные и возвращает true для принятия или false для исключения элемента.
Часть контрактаЧто важно
Сигнатураpublic function ArrayIterator::uasort(callable $callback): true
Результатtrue: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения вложенного источника не скрываются. Особые значения, предупреждения и версии перечислены в полном официальном контракте ниже.
ВерсииPHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.0.0)

Стандартного порядка недостаточно: остатки сортируют по числу, а артикулы — по длине ключа.

Задать бизнес-порядок значений и ключейСамостоятельный пример
<?php
declare(strict_types=1);

$byQty = new ArrayIterator(['brush' => 12, 'paint' => 3, 'roller' => 7]);
$byQty->uasort(fn(int $left, int $right): int => $left <=> $right);
echo 'qty: ', json_encode($byQty->getArrayCopy()), "\n";
$bySkuLength = new ArrayIterator(['long-sku' => 1, 'x' => 2, 'mid' => 3]);
$bySkuLength->uksort(fn(string $left, string $right): int => strlen($left) <=> strlen($right));
echo 'keys: ', implode(',', array_keys($bySkuLength->getArrayCopy())), "\n";
Ожидаемый результат
qty: {"paint":3,"roller":7,"brush":12}
keys: x,mid,long-sku

uasort() передавал callback два значения и сохранил ключи. uksort() передавал два ключа. Оператор <=> вернул отрицательное, ноль или положительное число; callback не изменял исходные элементы.

Скачать самостоятельный пример с fixtures, результатом и README

Таблица содержит собственные ключи. Перед сортировкой нужно решить: меняется порядок по цене или по артикулу.

Сравнить сортировку по значениям и по ключамСамостоятельный пример
<?php
declare(strict_types=1);

$byValue = new ArrayIterator(['b' => 10, 'a' => 20]);
$byValue->asort();
echo 'asort: ', json_encode($byValue->getArrayCopy()), "\n";
$byKey = new ArrayIterator(['b' => 10, 'a' => 20]);
$byKey->ksort();
echo 'ksort: ', json_encode($byKey->getArrayCopy()), "\n";
Ожидаемый результат
asort: {"b":10,"a":20}
ksort: {"a":20,"b":10}

asort() сравнил значения 10 и 20 и сохранил ключи. ksort() сравнил ключи a и b. Обе операции изменили порядок самого объекта.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

ArrayIterator::uasort

(PHP 5 >= 5.2.0, PHP 7, PHP 8) ArrayIterator::uasort — Sort with a user-defined comparison function and maintain index association

Description

public function ArrayIterator::uasort(callable $callback): true

This method sorts the elements such that indices maintain their correlation with the values they are associated with, using a user-defined comparison function.

Note:

If two members compare as equal, they retain their original order. Prior to PHP 8.0.0, their relative order in the sorted array was undefined.

Parameters

callback

The comparison function must return an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second.

function callback(mixed $a, mixed $b): int

Caution

Returning non-integer values from the comparison function, such as float, will result in an internal cast to int of the callback's return value. So values such as 0.99 and 0.1 will both be cast to an integer value of 0, which will compare such values as equal.

Return Values

Always returns true.

Changelog

Version Description

8.2.0

The return type is true now; previously, it was bool.

See Also

ArrayIterator::asort() - Sort entries by values

ArrayIterator::ksort() - Sort entries by keys

ArrayIterator::natcasesort() - Sort entries naturally, case insensitive

ArrayIterator::natsort() - Sort entries naturally

ArrayIterator::uksort() - Sort by keys using a user-defined comparison function

uasort() - Sort an array with a user-defined comparison function and maintain index association

Связанные карточки: ArrayIterator::getArrayCopy, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ArrayIterator::uksortArrayIterator::uksort: отсортировать ключи пользовательским сравнением

PHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.0.0) · SPL

public function ArrayIterator::uksort(callable $callback): true

ArrayIterator::uksort нужен, чтобы отсортировать ключи пользовательским сравнением. В этой задаче ArrayIterator помогает обходить и изменять массив через объект с явным курсором, сортировкой, позиционированием и ArrayAccess. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
callbackФункция, которая получает текущие данные и возвращает true для принятия или false для исключения элемента.
Часть контрактаЧто важно
Сигнатураpublic function ArrayIterator::uksort(callable $callback): true
Результатtrue: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения вложенного источника не скрываются. Особые значения, предупреждения и версии перечислены в полном официальном контракте ниже.
ВерсииPHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.0.0)

Стандартного порядка недостаточно: остатки сортируют по числу, а артикулы — по длине ключа.

Задать бизнес-порядок значений и ключейСамостоятельный пример
<?php
declare(strict_types=1);

$byQty = new ArrayIterator(['brush' => 12, 'paint' => 3, 'roller' => 7]);
$byQty->uasort(fn(int $left, int $right): int => $left <=> $right);
echo 'qty: ', json_encode($byQty->getArrayCopy()), "\n";
$bySkuLength = new ArrayIterator(['long-sku' => 1, 'x' => 2, 'mid' => 3]);
$bySkuLength->uksort(fn(string $left, string $right): int => strlen($left) <=> strlen($right));
echo 'keys: ', implode(',', array_keys($bySkuLength->getArrayCopy())), "\n";
Ожидаемый результат
qty: {"paint":3,"roller":7,"brush":12}
keys: x,mid,long-sku

uasort() передавал callback два значения и сохранил ключи. uksort() передавал два ключа. Оператор <=> вернул отрицательное, ноль или положительное число; callback не изменял исходные элементы.

Скачать самостоятельный пример с fixtures, результатом и README

Таблица содержит собственные ключи. Перед сортировкой нужно решить: меняется порядок по цене или по артикулу.

Сравнить сортировку по значениям и по ключамСамостоятельный пример
<?php
declare(strict_types=1);

$byValue = new ArrayIterator(['b' => 10, 'a' => 20]);
$byValue->asort();
echo 'asort: ', json_encode($byValue->getArrayCopy()), "\n";
$byKey = new ArrayIterator(['b' => 10, 'a' => 20]);
$byKey->ksort();
echo 'ksort: ', json_encode($byKey->getArrayCopy()), "\n";
Ожидаемый результат
asort: {"b":10,"a":20}
ksort: {"a":20,"b":10}

asort() сравнил значения 10 и 20 и сохранил ключи. ksort() сравнил ключи a и b. Обе операции изменили порядок самого объекта.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

ArrayIterator::uksort

(PHP 5 >= 5.2.0, PHP 7, PHP 8) ArrayIterator::uksort — Sort by keys using a user-defined comparison function

Description

public function ArrayIterator::uksort(callable $callback): true

This method sorts the elements by keys using a user-supplied comparison function.

Note:

If two members compare as equal, they retain their original order. Prior to PHP 8.0.0, their relative order in the sorted array was undefined.

Parameters

callback

The comparison function must return an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second.

function callback(mixed $a, mixed $b): int

Caution

Returning non-integer values from the comparison function, such as float, will result in an internal cast to int of the callback's return value. So values such as 0.99 and 0.1 will both be cast to an integer value of 0, which will compare such values as equal.

Return Values

Always returns true.

Changelog

Version Description

8.2.0

The return type is true now; previously, it was bool.

See Also

ArrayIterator::asort() - Sort entries by values

ArrayIterator::ksort() - Sort entries by keys

ArrayIterator::natcasesort() - Sort entries naturally, case insensitive

ArrayIterator::natsort() - Sort entries naturally

ArrayIterator::uasort() - Sort with a user-defined comparison function and maintain index association

uksort() - Sort an array by keys using a user-defined comparison function

Связанные карточки: ArrayIterator::getArrayCopy, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

EmptyIterator::currentEmptyIterator::current: получить текущее значение без продвижения курсора

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function EmptyIterator::current(): never

EmptyIterator::current нужен, чтобы получить текущее значение без продвижения курсора. В этой задаче EmptyIterator помогает передать гарантированно пустой Iterator в общий конвейер без отдельной ветки null. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function EmptyIterator::current(): never
Результатnever: нормальный возврат к следующему выражению отсутствует.
Ошибки и особые значенияЭтот метод всегда выбрасывает BadMethodCallException.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Общий отчёт ожидает Iterator даже тогда, когда фильтр заранее установил отсутствие строк.

Безопасно пройти пустой источникСамостоятельный пример
<?php
declare(strict_types=1);

$rows = new EmptyIterator();
$rows->rewind();
echo 'valid: ', $rows->valid() ? 'yes' : 'no', "\n";
$rows->next();
echo 'after next: ', $rows->valid() ? 'yes' : 'no', "\n";
foreach ($rows as $row) { echo 'unreachable', "\n"; }
echo "Обход завершён без строк\n";
Ожидаемый результат
valid: no
after next: no
Обход завершён без строк

rewind() и next() ничего не сделали, valid() всегда вернул false, поэтому foreach не вызвал тело. Это корректная пустота, а не ошибка чтения.

Скачать самостоятельный пример с fixtures, результатом и README

Пустой Iterator специально запрещает выдавать выдуманное текущее значение или ключ.

Не читать current и key без validСамостоятельный пример
<?php
declare(strict_types=1);

$rows = new EmptyIterator();
foreach (['current', 'key'] as $method) {
    try {
        $rows->$method();
    } catch (Exception $error) {
        echo $method, ': ', $error::class, "\n";
    }
}
echo 'valid: ', $rows->valid() ? 'yes' : 'no', "\n";
Ожидаемый результат
current: BadMethodCallException
key: BadMethodCallException
valid: no

current() и key() завершились BadMethodCallException, которое пример перехватил. valid() остаётся безопасной проверкой и возвращает false. Точный класс подтверждается запуском текущего runtime.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

EmptyIterator::current

(PHP 5 >= 5.1.0, PHP 7, PHP 8) EmptyIterator::current — The current() method

Description

public function EmptyIterator::current(): never

This function must not be called. It throws an exception upon access.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Errors/Exceptions

Throws an Exception if called.

Return Values

No value is returned.

Связанные карточки: EmptyIterator::valid, AppendIterator::append.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

EmptyIterator::keyEmptyIterator::key: получить ключ или позицию текущего элемента

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function EmptyIterator::key(): never

EmptyIterator::key нужен, чтобы получить ключ или позицию текущего элемента. В этой задаче EmptyIterator помогает передать гарантированно пустой Iterator в общий конвейер без отдельной ветки null. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function EmptyIterator::key(): never
Результатnever: нормальный возврат к следующему выражению отсутствует.
Ошибки и особые значенияЭтот метод всегда выбрасывает BadMethodCallException.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Общий отчёт ожидает Iterator даже тогда, когда фильтр заранее установил отсутствие строк.

Безопасно пройти пустой источникСамостоятельный пример
<?php
declare(strict_types=1);

$rows = new EmptyIterator();
$rows->rewind();
echo 'valid: ', $rows->valid() ? 'yes' : 'no', "\n";
$rows->next();
echo 'after next: ', $rows->valid() ? 'yes' : 'no', "\n";
foreach ($rows as $row) { echo 'unreachable', "\n"; }
echo "Обход завершён без строк\n";
Ожидаемый результат
valid: no
after next: no
Обход завершён без строк

rewind() и next() ничего не сделали, valid() всегда вернул false, поэтому foreach не вызвал тело. Это корректная пустота, а не ошибка чтения.

Скачать самостоятельный пример с fixtures, результатом и README

Пустой Iterator специально запрещает выдавать выдуманное текущее значение или ключ.

Не читать current и key без validСамостоятельный пример
<?php
declare(strict_types=1);

$rows = new EmptyIterator();
foreach (['current', 'key'] as $method) {
    try {
        $rows->$method();
    } catch (Exception $error) {
        echo $method, ': ', $error::class, "\n";
    }
}
echo 'valid: ', $rows->valid() ? 'yes' : 'no', "\n";
Ожидаемый результат
current: BadMethodCallException
key: BadMethodCallException
valid: no

current() и key() завершились BadMethodCallException, которое пример перехватил. valid() остаётся безопасной проверкой и возвращает false. Точный класс подтверждается запуском текущего runtime.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

EmptyIterator::key

(PHP 5 >= 5.1.0, PHP 7, PHP 8) EmptyIterator::key — The key() method

Description

public function EmptyIterator::key(): never

This function must not be called. It throws an exception upon access.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Errors/Exceptions

Throws an Exception if called.

Return Values

No value is returned.

Связанные карточки: EmptyIterator::valid, AppendIterator::append.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

EmptyIterator::nextEmptyIterator::next: перевести курсор к следующему элементу

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function EmptyIterator::next(): void

EmptyIterator::next нужен, чтобы перевести курсор к следующему элементу. В этой задаче EmptyIterator помогает передать гарантированно пустой Iterator в общий конвейер без отдельной ветки null. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function EmptyIterator::next(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияМетод не выбрасывает ошибку и не создаёт элемент; valid() всё равно false.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Общий отчёт ожидает Iterator даже тогда, когда фильтр заранее установил отсутствие строк.

Безопасно пройти пустой источникСамостоятельный пример
<?php
declare(strict_types=1);

$rows = new EmptyIterator();
$rows->rewind();
echo 'valid: ', $rows->valid() ? 'yes' : 'no', "\n";
$rows->next();
echo 'after next: ', $rows->valid() ? 'yes' : 'no', "\n";
foreach ($rows as $row) { echo 'unreachable', "\n"; }
echo "Обход завершён без строк\n";
Ожидаемый результат
valid: no
after next: no
Обход завершён без строк

rewind() и next() ничего не сделали, valid() всегда вернул false, поэтому foreach не вызвал тело. Это корректная пустота, а не ошибка чтения.

Скачать самостоятельный пример с fixtures, результатом и README

Пустой Iterator специально запрещает выдавать выдуманное текущее значение или ключ.

Не читать current и key без validСамостоятельный пример
<?php
declare(strict_types=1);

$rows = new EmptyIterator();
foreach (['current', 'key'] as $method) {
    try {
        $rows->$method();
    } catch (Exception $error) {
        echo $method, ': ', $error::class, "\n";
    }
}
echo 'valid: ', $rows->valid() ? 'yes' : 'no', "\n";
Ожидаемый результат
current: BadMethodCallException
key: BadMethodCallException
valid: no

current() и key() завершились BadMethodCallException, которое пример перехватил. valid() остаётся безопасной проверкой и возвращает false. Точный класс подтверждается запуском текущего runtime.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

EmptyIterator::next

(PHP 5 >= 5.1.0, PHP 7, PHP 8) EmptyIterator::next — The next() method

Description

public function EmptyIterator::next(): void

No operation, nothing to do.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

No value is returned.

Связанные карточки: EmptyIterator::valid, AppendIterator::append.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

EmptyIterator::rewindEmptyIterator::rewind: попытаться установить курсор на первый элемент

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function EmptyIterator::rewind(): void

EmptyIterator::rewind нужен, чтобы попытаться установить курсор на первый элемент. В этой задаче EmptyIterator помогает передать гарантированно пустой Iterator в общий конвейер без отдельной ветки null. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function EmptyIterator::rewind(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияМетод не выбрасывает ошибку и не создаёт элемент; valid() всё равно false.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Общий отчёт ожидает Iterator даже тогда, когда фильтр заранее установил отсутствие строк.

Безопасно пройти пустой источникСамостоятельный пример
<?php
declare(strict_types=1);

$rows = new EmptyIterator();
$rows->rewind();
echo 'valid: ', $rows->valid() ? 'yes' : 'no', "\n";
$rows->next();
echo 'after next: ', $rows->valid() ? 'yes' : 'no', "\n";
foreach ($rows as $row) { echo 'unreachable', "\n"; }
echo "Обход завершён без строк\n";
Ожидаемый результат
valid: no
after next: no
Обход завершён без строк

rewind() и next() ничего не сделали, valid() всегда вернул false, поэтому foreach не вызвал тело. Это корректная пустота, а не ошибка чтения.

Скачать самостоятельный пример с fixtures, результатом и README

Пустой Iterator специально запрещает выдавать выдуманное текущее значение или ключ.

Не читать current и key без validСамостоятельный пример
<?php
declare(strict_types=1);

$rows = new EmptyIterator();
foreach (['current', 'key'] as $method) {
    try {
        $rows->$method();
    } catch (Exception $error) {
        echo $method, ': ', $error::class, "\n";
    }
}
echo 'valid: ', $rows->valid() ? 'yes' : 'no', "\n";
Ожидаемый результат
current: BadMethodCallException
key: BadMethodCallException
valid: no

current() и key() завершились BadMethodCallException, которое пример перехватил. valid() остаётся безопасной проверкой и возвращает false. Точный класс подтверждается запуском текущего runtime.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

EmptyIterator::rewind

(PHP 5 >= 5.1.0, PHP 7, PHP 8) EmptyIterator::rewind — The rewind() method

Description

public function EmptyIterator::rewind(): void

No operation, nothing to do.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

No value is returned.

Связанные карточки: EmptyIterator::valid, AppendIterator::append.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

EmptyIterator::validEmptyIterator::valid: проверить, указывает ли курсор на существующий элемент

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function EmptyIterator::valid(): false

EmptyIterator::valid нужен, чтобы проверить, указывает ли курсор на существующий элемент. В этой задаче EmptyIterator помогает передать гарантированно пустой Iterator в общий конвейер без отдельной ветки null. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function EmptyIterator::valid(): false
Результатfalse: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияМетод не выбрасывает ошибку и не создаёт элемент; valid() всё равно false.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Общий отчёт ожидает Iterator даже тогда, когда фильтр заранее установил отсутствие строк.

Безопасно пройти пустой источникСамостоятельный пример
<?php
declare(strict_types=1);

$rows = new EmptyIterator();
$rows->rewind();
echo 'valid: ', $rows->valid() ? 'yes' : 'no', "\n";
$rows->next();
echo 'after next: ', $rows->valid() ? 'yes' : 'no', "\n";
foreach ($rows as $row) { echo 'unreachable', "\n"; }
echo "Обход завершён без строк\n";
Ожидаемый результат
valid: no
after next: no
Обход завершён без строк

rewind() и next() ничего не сделали, valid() всегда вернул false, поэтому foreach не вызвал тело. Это корректная пустота, а не ошибка чтения.

Скачать самостоятельный пример с fixtures, результатом и README

Пустой Iterator специально запрещает выдавать выдуманное текущее значение или ключ.

Не читать current и key без validСамостоятельный пример
<?php
declare(strict_types=1);

$rows = new EmptyIterator();
foreach (['current', 'key'] as $method) {
    try {
        $rows->$method();
    } catch (Exception $error) {
        echo $method, ': ', $error::class, "\n";
    }
}
echo 'valid: ', $rows->valid() ? 'yes' : 'no', "\n";
Ожидаемый результат
current: BadMethodCallException
key: BadMethodCallException
valid: no

current() и key() завершились BadMethodCallException, которое пример перехватил. valid() остаётся безопасной проверкой и возвращает false. Точный класс подтверждается запуском текущего runtime.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

EmptyIterator::valid

(PHP 5 >= 5.1.0, PHP 7, PHP 8) EmptyIterator::valid — Checks whether the current element is valid

Description

public function EmptyIterator::valid(): false

Checks whether the current element is valid.

Note:

The EmptyIterator is always empty and will never have a valid value. The return value is always false.

Parameters

This function has no parameters.

Return Values

false

Связанные карточки: EmptyIterator::valid, AppendIterator::append.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

InfiniteIterator::__constructInfiniteIterator::__construct: создать и настроить объект для дальнейшего обхода

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function InfiniteIterator::__construct(Iterator $iterator)

InfiniteIterator::__construct нужен, чтобы создать и настроить объект для дальнейшего обхода. В этой задаче InfiniteIterator помогает циклически повторять конечный набор значений, когда внешний код задаёт точное ограничение. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
iteratorИсходный Iterator или Traversable указанного сигнатурой типа. Объект не копируется: декоратор читает тот же курсор.
Часть контрактаЧто важно
Сигнатураpublic function InfiniteIterator::__construct(Iterator $iterator)
РезультатКонструктор не возвращает прикладное значение; выражение new создаёт объект, который затем сохраняется в переменной.
Ошибки и особые значенияНеподходящий тип аргумента приводит к TypeError; несовместимые флаги, маска или путь имеют отдельные ValueError/RuntimeException либо файловые предупреждения согласно полному контракту.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Конечный список дежурных нужно повторять, но расписание содержит ровно пять смен.

Назначить пять смен двум дежурнымСамостоятельный пример
<?php
declare(strict_types=1);

$rotation = new InfiniteIterator(new ArrayIterator(['Анна', 'Борис']));
$fiveShifts = new LimitIterator($rotation, 0, 5);
$shift = 1;
foreach ($fiveShifts as $person) {
    echo $shift, ': ', $person, "\n";
    $shift++;
}
Ожидаемый результат
1: Анна
2: Борис
3: Анна
4: Борис
5: Анна

InfiniteIterator после Бориса снова начал внутренний ArrayIterator с Анны. Его исходные ключи тоже повторяются, поэтому отдельный счётчик $shift нумерует итоговое расписание. Внешний LimitIterator остановил обход после пяти значений; без него foreach не завершился бы.

Скачать самостоятельный пример с fixtures, результатом и README

Учебный план повтора использует цикл 1–2–5 секунд, но число попыток обязано быть конечным.

Повторить ограниченную схему задержекСамостоятельный пример
<?php
declare(strict_types=1);

$delays = new InfiniteIterator(new ArrayIterator([1, 2, 5]));
$attempts = new LimitIterator($delays, 0, 7);
$attempt = 1;
foreach ($attempts as $seconds) {
    echo 'Попытка ', $attempt, ': пауза ', $seconds, " сек.\n";
    $attempt++;
}
Ожидаемый результат
Попытка 1: пауза 1 сек.
Попытка 2: пауза 2 сек.
Попытка 3: пауза 5 сек.
Попытка 4: пауза 1 сек.
Попытка 5: пауза 2 сек.
Попытка 6: пауза 5 сек.
Попытка 7: пауза 1 сек.

next() InfiniteIterator сам перемотал внутренний источник после третьего значения. Ключи внутреннего массива повторяются, поэтому номер попытки хранится отдельно. Пример только печатает план: он не вызывает sleep() и не отправляет запросы. Семь попыток ограничены явно.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

InfiniteIterator::__construct

(PHP 5 >= 5.1.0, PHP 7, PHP 8) InfiniteIterator::__construct — Constructs an InfiniteIterator

Description

public function InfiniteIterator::__construct(Iterator $iterator)

Constructs an InfiniteIterator from an Iterator.

Parameters

iterator

The iterator to infinitely iterate over.

See Also

InfiniteIterator::next() - Moves the inner Iterator forward or rewinds it

Связанные карточки: LimitIterator::__construct, NoRewindIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

InfiniteIterator::nextInfiniteIterator::next: перевести курсор к следующему элементу

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function InfiniteIterator::next(): void

InfiniteIterator::next нужен, чтобы перевести курсор к следующему элементу. В этой задаче InfiniteIterator помогает циклически повторять конечный набор значений, когда внешний код задаёт точное ограничение. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function InfiniteIterator::next(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияПродвижение одноразового источника нельзя отменить. Исключение из вложенного источника передаётся вызывающему коду.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Конечный список дежурных нужно повторять, но расписание содержит ровно пять смен.

Назначить пять смен двум дежурнымСамостоятельный пример
<?php
declare(strict_types=1);

$rotation = new InfiniteIterator(new ArrayIterator(['Анна', 'Борис']));
$fiveShifts = new LimitIterator($rotation, 0, 5);
$shift = 1;
foreach ($fiveShifts as $person) {
    echo $shift, ': ', $person, "\n";
    $shift++;
}
Ожидаемый результат
1: Анна
2: Борис
3: Анна
4: Борис
5: Анна

InfiniteIterator после Бориса снова начал внутренний ArrayIterator с Анны. Его исходные ключи тоже повторяются, поэтому отдельный счётчик $shift нумерует итоговое расписание. Внешний LimitIterator остановил обход после пяти значений; без него foreach не завершился бы.

Скачать самостоятельный пример с fixtures, результатом и README

Учебный план повтора использует цикл 1–2–5 секунд, но число попыток обязано быть конечным.

Повторить ограниченную схему задержекСамостоятельный пример
<?php
declare(strict_types=1);

$delays = new InfiniteIterator(new ArrayIterator([1, 2, 5]));
$attempts = new LimitIterator($delays, 0, 7);
$attempt = 1;
foreach ($attempts as $seconds) {
    echo 'Попытка ', $attempt, ': пауза ', $seconds, " сек.\n";
    $attempt++;
}
Ожидаемый результат
Попытка 1: пауза 1 сек.
Попытка 2: пауза 2 сек.
Попытка 3: пауза 5 сек.
Попытка 4: пауза 1 сек.
Попытка 5: пауза 2 сек.
Попытка 6: пауза 5 сек.
Попытка 7: пауза 1 сек.

next() InfiniteIterator сам перемотал внутренний источник после третьего значения. Ключи внутреннего массива повторяются, поэтому номер попытки хранится отдельно. Пример только печатает план: он не вызывает sleep() и не отправляет запросы. Семь попыток ограничены явно.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

InfiniteIterator::next

(PHP 5 >= 5.1.0, PHP 7, PHP 8) InfiniteIterator::next — Moves the inner Iterator forward or rewinds it

Description

public function InfiniteIterator::next(): void

Moves the inner Iterator forward to its next element if there is one, otherwise rewinds the inner Iterator back to the beginning.

Note:

Even an InfiniteIterator stops if its inner Iterator is empty.

Parameters

This function has no parameters.

Return Values

No value is returned.

See Also

InfiniteIterator::__construct() - Constructs an InfiniteIterator

Связанные карточки: LimitIterator::__construct, NoRewindIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

IteratorIterator::__constructIteratorIterator::__construct: создать и настроить объект для дальнейшего обхода

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function IteratorIterator::__construct(Traversable $iterator, ?string $class = null)

IteratorIterator::__construct нужен, чтобы создать и настроить объект для дальнейшего обхода. В этой задаче IteratorIterator помогает обернуть Traversable, который ещё не является Iterator, и затем подключить фильтр или другой декоратор. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
iteratorИсходный Iterator или Traversable указанного сигнатурой типа. Объект не копируется: декоратор читает тот же курсор.
classЗначение параметра связано с текущей операцией; допустимый тип и значение по умолчанию видны в сигнатуре, а фактическая роль показана перед примером.
Часть контрактаЧто важно
Сигнатураpublic function IteratorIterator::__construct(Traversable $iterator, ?string $class = null)
РезультатКонструктор не возвращает прикладное значение; выражение new создаёт объект, который затем сохраняется в переменной.
Ошибки и особые значенияНеподходящий тип аргумента приводит к TypeError; несовместимые флаги, маска или путь имеют отдельные ValueError/RuntimeException либо файловые предупреждения согласно полному контракту.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

DatePeriod реализует Traversable, но не обычный Iterator. Декоратор нужен, когда следующий компонент требует именно Iterator.

Обойти фиксированный DatePeriod как IteratorСамостоятельный пример
<?php
declare(strict_types=1);

$period = new DatePeriod(
    new DateTimeImmutable('2026-10-12'),
    new DateInterval('P1D'),
    new DateTimeImmutable('2026-10-15')
);
$days = new IteratorIterator($period);
foreach ($days as $day) {
    echo $day->format('Y-m-d'), "\n";
}
echo 'inner: ', $days->getInnerIterator()::class, "\n";
Ожидаемый результат
2026-10-12
2026-10-13
2026-10-14
inner: InternalIterator

IteratorIterator передал foreach три даты до исключительной конечной даты. Поскольку DatePeriod — Traversable, но не Iterator, PHP показывает внутренний адаптер InternalIterator; getInnerIterator() возвращает именно активный Iterator-слой, а не массив-копию и не обязуется вернуть исходный DatePeriod.

Скачать самостоятельный пример с fixtures, результатом и README

Чтобы понять декоратор, полезно один раз вызвать протокол вручную.

Увидеть делегирование пяти операций курсораСамостоятельный пример
<?php
declare(strict_types=1);

$inner = new ArrayIterator(['new', 'paid']);
$outer = new IteratorIterator($inner);
$outer->rewind();
while ($outer->valid()) {
    echo $outer->key(), '=', $outer->current(), "\n";
    $outer->next();
}
$outer->rewind();
echo 'again: ', $outer->current(), "\n";
Ожидаемый результат
0=new
1=paid
again: new

Каждый outer-метод делегировал действие inner ArrayIterator. После конца rewind() снова перемотал повторяемый источник; обёртка не создала второго набора данных.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

IteratorIterator::__construct

(PHP 5 >= 5.1.0, PHP 7, PHP 8) IteratorIterator::__construct — Create an iterator from anything that is traversable

Description

public function IteratorIterator::__construct(Traversable $iterator, ?string $class = null)

Creates an iterator from anything that is traversable.

Parameters

iterator

The traversable iterator.

class

The class name to use for the inner iterator. It allows to specify a different iterator class to wrap the provided iterator. By default, it will use the IteratorIterator class itself.

See Also

Traversable

Связанные карточки: CallbackFilterIterator::__construct, RecursiveIteratorIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

IteratorIterator::currentIteratorIterator::current: получить текущее значение без продвижения курсора

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function IteratorIterator::current(): mixed

IteratorIterator::current нужен, чтобы получить текущее значение без продвижения курсора. В этой задаче IteratorIterator помогает обернуть Traversable, который ещё не является Iterator, и затем подключить фильтр или другой декоратор. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function IteratorIterator::current(): mixed
Результатmixed: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияСначала вызывайте valid(). На недействительном курсоре особое значение зависит от класса и не должно смешиваться с настоящим null.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

DatePeriod реализует Traversable, но не обычный Iterator. Декоратор нужен, когда следующий компонент требует именно Iterator.

Обойти фиксированный DatePeriod как IteratorСамостоятельный пример
<?php
declare(strict_types=1);

$period = new DatePeriod(
    new DateTimeImmutable('2026-10-12'),
    new DateInterval('P1D'),
    new DateTimeImmutable('2026-10-15')
);
$days = new IteratorIterator($period);
foreach ($days as $day) {
    echo $day->format('Y-m-d'), "\n";
}
echo 'inner: ', $days->getInnerIterator()::class, "\n";
Ожидаемый результат
2026-10-12
2026-10-13
2026-10-14
inner: InternalIterator

IteratorIterator передал foreach три даты до исключительной конечной даты. Поскольку DatePeriod — Traversable, но не Iterator, PHP показывает внутренний адаптер InternalIterator; getInnerIterator() возвращает именно активный Iterator-слой, а не массив-копию и не обязуется вернуть исходный DatePeriod.

Скачать самостоятельный пример с fixtures, результатом и README

Чтобы понять декоратор, полезно один раз вызвать протокол вручную.

Увидеть делегирование пяти операций курсораСамостоятельный пример
<?php
declare(strict_types=1);

$inner = new ArrayIterator(['new', 'paid']);
$outer = new IteratorIterator($inner);
$outer->rewind();
while ($outer->valid()) {
    echo $outer->key(), '=', $outer->current(), "\n";
    $outer->next();
}
$outer->rewind();
echo 'again: ', $outer->current(), "\n";
Ожидаемый результат
0=new
1=paid
again: new

Каждый outer-метод делегировал действие inner ArrayIterator. После конца rewind() снова перемотал повторяемый источник; обёртка не создала второго набора данных.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

IteratorIterator::current

(PHP 5 >= 5.1.0, PHP 7, PHP 8) IteratorIterator::current — Get the current value

Description

public function IteratorIterator::current(): mixed

Get the value of the current element.

Parameters

This function has no parameters.

Return Values

The value of the current element.

See Also

IteratorIterator::key() - Get the key of the current element

Связанные карточки: CallbackFilterIterator::__construct, RecursiveIteratorIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

IteratorIterator::getInnerIteratorIteratorIterator::getInnerIterator: получить непосредственно обёрнутый итератор текущего уровня

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function IteratorIterator::getInnerIterator(): ?Iterator

IteratorIterator::getInnerIterator нужен, чтобы получить непосредственно обёрнутый итератор текущего уровня. В этой задаче IteratorIterator помогает обернуть Traversable, который ещё не является Iterator, и затем подключить фильтр или другой декоратор. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function IteratorIterator::getInnerIterator(): ?Iterator
Результат?Iterator: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения вложенного источника не скрываются. Особые значения, предупреждения и версии перечислены в полном официальном контракте ниже.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

DatePeriod реализует Traversable, но не обычный Iterator. Декоратор нужен, когда следующий компонент требует именно Iterator.

Обойти фиксированный DatePeriod как IteratorСамостоятельный пример
<?php
declare(strict_types=1);

$period = new DatePeriod(
    new DateTimeImmutable('2026-10-12'),
    new DateInterval('P1D'),
    new DateTimeImmutable('2026-10-15')
);
$days = new IteratorIterator($period);
foreach ($days as $day) {
    echo $day->format('Y-m-d'), "\n";
}
echo 'inner: ', $days->getInnerIterator()::class, "\n";
Ожидаемый результат
2026-10-12
2026-10-13
2026-10-14
inner: InternalIterator

IteratorIterator передал foreach три даты до исключительной конечной даты. Поскольку DatePeriod — Traversable, но не Iterator, PHP показывает внутренний адаптер InternalIterator; getInnerIterator() возвращает именно активный Iterator-слой, а не массив-копию и не обязуется вернуть исходный DatePeriod.

Скачать самостоятельный пример с fixtures, результатом и README

Чтобы понять декоратор, полезно один раз вызвать протокол вручную.

Увидеть делегирование пяти операций курсораСамостоятельный пример
<?php
declare(strict_types=1);

$inner = new ArrayIterator(['new', 'paid']);
$outer = new IteratorIterator($inner);
$outer->rewind();
while ($outer->valid()) {
    echo $outer->key(), '=', $outer->current(), "\n";
    $outer->next();
}
$outer->rewind();
echo 'again: ', $outer->current(), "\n";
Ожидаемый результат
0=new
1=paid
again: new

Каждый outer-метод делегировал действие inner ArrayIterator. После конца rewind() снова перемотал повторяемый источник; обёртка не создала второго набора данных.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

IteratorIterator::getInnerIterator

(PHP 5 >= 5.1.0, PHP 7, PHP 8) IteratorIterator::getInnerIterator — Get the inner iterator

Description

public function IteratorIterator::getInnerIterator(): ?Iterator

Get the inner iterator.

Parameters

This function has no parameters.

Return Values

The inner iterator as passed to IteratorIterator::__construct(), or null when there is no inner iterator.

See Also

Iterator

OuterIterator

Связанные карточки: CallbackFilterIterator::__construct, RecursiveIteratorIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

IteratorIterator::keyIteratorIterator::key: получить ключ или позицию текущего элемента

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function IteratorIterator::key(): mixed

IteratorIterator::key нужен, чтобы получить ключ или позицию текущего элемента. В этой задаче IteratorIterator помогает обернуть Traversable, который ещё не является Iterator, и затем подключить фильтр или другой декоратор. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function IteratorIterator::key(): mixed
Результатmixed: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияСначала вызывайте valid(). Ключ может быть int, string или составным массивом и не обязан быть бизнес-идентификатором.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

DatePeriod реализует Traversable, но не обычный Iterator. Декоратор нужен, когда следующий компонент требует именно Iterator.

Обойти фиксированный DatePeriod как IteratorСамостоятельный пример
<?php
declare(strict_types=1);

$period = new DatePeriod(
    new DateTimeImmutable('2026-10-12'),
    new DateInterval('P1D'),
    new DateTimeImmutable('2026-10-15')
);
$days = new IteratorIterator($period);
foreach ($days as $day) {
    echo $day->format('Y-m-d'), "\n";
}
echo 'inner: ', $days->getInnerIterator()::class, "\n";
Ожидаемый результат
2026-10-12
2026-10-13
2026-10-14
inner: InternalIterator

IteratorIterator передал foreach три даты до исключительной конечной даты. Поскольку DatePeriod — Traversable, но не Iterator, PHP показывает внутренний адаптер InternalIterator; getInnerIterator() возвращает именно активный Iterator-слой, а не массив-копию и не обязуется вернуть исходный DatePeriod.

Скачать самостоятельный пример с fixtures, результатом и README

Чтобы понять декоратор, полезно один раз вызвать протокол вручную.

Увидеть делегирование пяти операций курсораСамостоятельный пример
<?php
declare(strict_types=1);

$inner = new ArrayIterator(['new', 'paid']);
$outer = new IteratorIterator($inner);
$outer->rewind();
while ($outer->valid()) {
    echo $outer->key(), '=', $outer->current(), "\n";
    $outer->next();
}
$outer->rewind();
echo 'again: ', $outer->current(), "\n";
Ожидаемый результат
0=new
1=paid
again: new

Каждый outer-метод делегировал действие inner ArrayIterator. После конца rewind() снова перемотал повторяемый источник; обёртка не создала второго набора данных.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

IteratorIterator::key

(PHP 5 >= 5.1.0, PHP 7, PHP 8) IteratorIterator::key — Get the key of the current element

Description

public function IteratorIterator::key(): mixed

Get the key of the current element.

Parameters

This function has no parameters.

Return Values

The key of the current element.

See Also

IteratorIterator::current() - Get the current value

Связанные карточки: CallbackFilterIterator::__construct, RecursiveIteratorIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

IteratorIterator::nextIteratorIterator::next: перевести курсор к следующему элементу

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function IteratorIterator::next(): void

IteratorIterator::next нужен, чтобы перевести курсор к следующему элементу. В этой задаче IteratorIterator помогает обернуть Traversable, который ещё не является Iterator, и затем подключить фильтр или другой декоратор. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function IteratorIterator::next(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияПродвижение одноразового источника нельзя отменить. Исключение из вложенного источника передаётся вызывающему коду.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

DatePeriod реализует Traversable, но не обычный Iterator. Декоратор нужен, когда следующий компонент требует именно Iterator.

Обойти фиксированный DatePeriod как IteratorСамостоятельный пример
<?php
declare(strict_types=1);

$period = new DatePeriod(
    new DateTimeImmutable('2026-10-12'),
    new DateInterval('P1D'),
    new DateTimeImmutable('2026-10-15')
);
$days = new IteratorIterator($period);
foreach ($days as $day) {
    echo $day->format('Y-m-d'), "\n";
}
echo 'inner: ', $days->getInnerIterator()::class, "\n";
Ожидаемый результат
2026-10-12
2026-10-13
2026-10-14
inner: InternalIterator

IteratorIterator передал foreach три даты до исключительной конечной даты. Поскольку DatePeriod — Traversable, но не Iterator, PHP показывает внутренний адаптер InternalIterator; getInnerIterator() возвращает именно активный Iterator-слой, а не массив-копию и не обязуется вернуть исходный DatePeriod.

Скачать самостоятельный пример с fixtures, результатом и README

Чтобы понять декоратор, полезно один раз вызвать протокол вручную.

Увидеть делегирование пяти операций курсораСамостоятельный пример
<?php
declare(strict_types=1);

$inner = new ArrayIterator(['new', 'paid']);
$outer = new IteratorIterator($inner);
$outer->rewind();
while ($outer->valid()) {
    echo $outer->key(), '=', $outer->current(), "\n";
    $outer->next();
}
$outer->rewind();
echo 'again: ', $outer->current(), "\n";
Ожидаемый результат
0=new
1=paid
again: new

Каждый outer-метод делегировал действие inner ArrayIterator. После конца rewind() снова перемотал повторяемый источник; обёртка не создала второго набора данных.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

IteratorIterator::next

(PHP 5 >= 5.1.0, PHP 7, PHP 8) IteratorIterator::next — Forward to the next element

Description

public function IteratorIterator::next(): void

Forward to the next element.

Parameters

This function has no parameters.

Return Values

No value is returned.

See Also

IteratorIterator::rewind() - Rewind to the first element

IteratorIterator::valid() - Checks if the current element is valid

Связанные карточки: CallbackFilterIterator::__construct, RecursiveIteratorIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

IteratorIterator::rewindIteratorIterator::rewind: попытаться установить курсор на первый элемент

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function IteratorIterator::rewind(): void

IteratorIterator::rewind нужен, чтобы попытаться установить курсор на первый элемент. В этой задаче IteratorIterator помогает обернуть Traversable, который ещё не является Iterator, и затем подключить фильтр или другой декоратор. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function IteratorIterator::rewind(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияНе каждый Traversable можно повторить. NoRewindIterator намеренно игнорирует повторную перемотку, а Generator после завершения может выбросить исключение.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

DatePeriod реализует Traversable, но не обычный Iterator. Декоратор нужен, когда следующий компонент требует именно Iterator.

Обойти фиксированный DatePeriod как IteratorСамостоятельный пример
<?php
declare(strict_types=1);

$period = new DatePeriod(
    new DateTimeImmutable('2026-10-12'),
    new DateInterval('P1D'),
    new DateTimeImmutable('2026-10-15')
);
$days = new IteratorIterator($period);
foreach ($days as $day) {
    echo $day->format('Y-m-d'), "\n";
}
echo 'inner: ', $days->getInnerIterator()::class, "\n";
Ожидаемый результат
2026-10-12
2026-10-13
2026-10-14
inner: InternalIterator

IteratorIterator передал foreach три даты до исключительной конечной даты. Поскольку DatePeriod — Traversable, но не Iterator, PHP показывает внутренний адаптер InternalIterator; getInnerIterator() возвращает именно активный Iterator-слой, а не массив-копию и не обязуется вернуть исходный DatePeriod.

Скачать самостоятельный пример с fixtures, результатом и README

Чтобы понять декоратор, полезно один раз вызвать протокол вручную.

Увидеть делегирование пяти операций курсораСамостоятельный пример
<?php
declare(strict_types=1);

$inner = new ArrayIterator(['new', 'paid']);
$outer = new IteratorIterator($inner);
$outer->rewind();
while ($outer->valid()) {
    echo $outer->key(), '=', $outer->current(), "\n";
    $outer->next();
}
$outer->rewind();
echo 'again: ', $outer->current(), "\n";
Ожидаемый результат
0=new
1=paid
again: new

Каждый outer-метод делегировал действие inner ArrayIterator. После конца rewind() снова перемотал повторяемый источник; обёртка не создала второго набора данных.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

IteratorIterator::rewind

(PHP 5 >= 5.1.0, PHP 7, PHP 8) IteratorIterator::rewind — Rewind to the first element

Description

public function IteratorIterator::rewind(): void

Rewinds to the first element.

Parameters

This function has no parameters.

Return Values

No value is returned.

See Also

IteratorIterator::next() - Forward to the next element

IteratorIterator::valid() - Checks if the current element is valid

Связанные карточки: CallbackFilterIterator::__construct, RecursiveIteratorIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

IteratorIterator::validIteratorIterator::valid: проверить, указывает ли курсор на существующий элемент

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function IteratorIterator::valid(): bool

IteratorIterator::valid нужен, чтобы проверить, указывает ли курсор на существующий элемент. В этой задаче IteratorIterator помогает обернуть Traversable, который ещё не является Iterator, и затем подключить фильтр или другой декоратор. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function IteratorIterator::valid(): bool
Результатbool: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияfalse означает отсутствие текущего элемента, а не ошибку бизнес-данных. Ошибки источника могут возникнуть отдельно.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

DatePeriod реализует Traversable, но не обычный Iterator. Декоратор нужен, когда следующий компонент требует именно Iterator.

Обойти фиксированный DatePeriod как IteratorСамостоятельный пример
<?php
declare(strict_types=1);

$period = new DatePeriod(
    new DateTimeImmutable('2026-10-12'),
    new DateInterval('P1D'),
    new DateTimeImmutable('2026-10-15')
);
$days = new IteratorIterator($period);
foreach ($days as $day) {
    echo $day->format('Y-m-d'), "\n";
}
echo 'inner: ', $days->getInnerIterator()::class, "\n";
Ожидаемый результат
2026-10-12
2026-10-13
2026-10-14
inner: InternalIterator

IteratorIterator передал foreach три даты до исключительной конечной даты. Поскольку DatePeriod — Traversable, но не Iterator, PHP показывает внутренний адаптер InternalIterator; getInnerIterator() возвращает именно активный Iterator-слой, а не массив-копию и не обязуется вернуть исходный DatePeriod.

Скачать самостоятельный пример с fixtures, результатом и README

Чтобы понять декоратор, полезно один раз вызвать протокол вручную.

Увидеть делегирование пяти операций курсораСамостоятельный пример
<?php
declare(strict_types=1);

$inner = new ArrayIterator(['new', 'paid']);
$outer = new IteratorIterator($inner);
$outer->rewind();
while ($outer->valid()) {
    echo $outer->key(), '=', $outer->current(), "\n";
    $outer->next();
}
$outer->rewind();
echo 'again: ', $outer->current(), "\n";
Ожидаемый результат
0=new
1=paid
again: new

Каждый outer-метод делегировал действие inner ArrayIterator. После конца rewind() снова перемотал повторяемый источник; обёртка не создала второго набора данных.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

IteratorIterator::valid

(PHP 5 >= 5.1.0, PHP 7, PHP 8) IteratorIterator::valid — Checks if the current element is valid

Description

public function IteratorIterator::valid(): bool

Checks whether the current element is valid.

Parameters

This function has no parameters.

Return Values

Returns true if the current element is valid, otherwise false

See Also

iterator_count() - Count the elements in an iterator

IteratorIterator::current() - Get the current value

Связанные карточки: CallbackFilterIterator::__construct, RecursiveIteratorIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

LimitIterator::__constructLimitIterator::__construct: создать и настроить объект для дальнейшего обхода

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function LimitIterator::__construct(Iterator $iterator, int $offset = 0, int $limit = -1)

LimitIterator::__construct нужен, чтобы создать и настроить объект для дальнейшего обхода. В этой задаче LimitIterator помогает взять окно из большого обхода: страницу каталога, первые N результатов или ограниченное число повторов. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
iteratorИсходный Iterator или Traversable указанного сигнатурой типа. Объект не копируется: декоратор читает тот же курсор.
offsetПозиция от нуля. Это место в порядке обхода, а не бизнес-ID записи.
limitЗначение параметра связано с текущей операцией; допустимый тип и значение по умолчанию видны в сигнатуре, а фактическая роль показана перед примером.
Часть контрактаЧто важно
Сигнатураpublic function LimitIterator::__construct(Iterator $iterator, int $offset = 0, int $limit = -1)
РезультатКонструктор не возвращает прикладное значение; выражение new создаёт объект, который затем сохраняется в переменной.
Ошибки и особые значенияНеподходящий тип аргумента приводит к TypeError; несовместимые флаги, маска или путь имеют отдельные ValueError/RuntimeException либо файловые предупреждения согласно полному контракту.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

В памяти пять товаров, а интерфейс показывает окно из двух значений, начиная с позиции 2.

Показать вторую страницу каталогаСамостоятельный пример
<?php
declare(strict_types=1);

$catalog = new ArrayIterator(['A', 'B', 'C', 'D', 'E']);
$page = new LimitIterator($catalog, 2, 2);
foreach ($page as $key => $item) {
    echo 'source=', $page->getPosition(), '; key=', $key, '; item=', $item, "\n";
}
$page->seek(3);
echo 'seek result: ', $page->current(), "\n";
Ожидаемый результат
source=2; key=2; item=C
source=3; key=3; item=D
seek result: D

Конструктор ограничил видимый диапазон C–D. getPosition() показал абсолютную позицию внутреннего источника. seek(3) допустим внутри окна и выбрал D.

Скачать самостоятельный пример с fixtures, результатом и README

InfiniteIterator сам не остановится. Смещение пропускает первый day, лимит разрешает четыре следующих значения.

Остановить циклический источник после четырёх значенийСамостоятельный пример
<?php
declare(strict_types=1);

$cycle = new InfiniteIterator(new ArrayIterator(['day', 'night']));
$limited = new LimitIterator($cycle, 1, 4);
$limited->rewind();
$position = 1;
while ($limited->valid()) {
    echo $position, ':', $limited->current(), "\n";
    $position++;
    $limited->next();
}
Ожидаемый результат
1:night
2:day
3:night
4:day

rewind() LimitIterator позиционировал внутренний цикл на offset 1. Ключи InfiniteIterator повторяют ключи day/night, поэтому итоговую позицию считает отдельная переменная. valid() стал false после четырёх элементов, хотя сам InfiniteIterator оставался способен продолжаться.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

LimitIterator::__construct

(PHP 5 >= 5.1.0, PHP 7, PHP 8) LimitIterator::__construct — Construct a LimitIterator

Description

public function LimitIterator::__construct(Iterator $iterator, int $offset = 0, int $limit = -1)

Constructs a new LimitIterator from an iterator with a given starting offset and maximum limit.

Parameters

iterator

The Iterator to limit.

offset

Optional offset of the limit.

limit

Optional count of the limit.

Errors/Exceptions

Throws a ValueError if the offset is less than 0 or the limit is less than -1.

Changelog

Version Description

8.0.0

Now throws a ValueError if offset is less than 0; previously it threw a RuntimeException.

8.0.0

Now throws a ValueError if limit is less than -1; previously it threw a RuntimeException.

See Also

LimitIterator examples

Связанные карточки: InfiniteIterator::__construct, ArrayIterator::seek.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

LimitIterator::currentLimitIterator::current: получить текущее значение без продвижения курсора

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function LimitIterator::current(): mixed

LimitIterator::current нужен, чтобы получить текущее значение без продвижения курсора. В этой задаче LimitIterator помогает взять окно из большого обхода: страницу каталога, первые N результатов или ограниченное число повторов. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function LimitIterator::current(): mixed
Результатmixed: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияСначала вызывайте valid(). На недействительном курсоре особое значение зависит от класса и не должно смешиваться с настоящим null.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

В памяти пять товаров, а интерфейс показывает окно из двух значений, начиная с позиции 2.

Показать вторую страницу каталогаСамостоятельный пример
<?php
declare(strict_types=1);

$catalog = new ArrayIterator(['A', 'B', 'C', 'D', 'E']);
$page = new LimitIterator($catalog, 2, 2);
foreach ($page as $key => $item) {
    echo 'source=', $page->getPosition(), '; key=', $key, '; item=', $item, "\n";
}
$page->seek(3);
echo 'seek result: ', $page->current(), "\n";
Ожидаемый результат
source=2; key=2; item=C
source=3; key=3; item=D
seek result: D

Конструктор ограничил видимый диапазон C–D. getPosition() показал абсолютную позицию внутреннего источника. seek(3) допустим внутри окна и выбрал D.

Скачать самостоятельный пример с fixtures, результатом и README

InfiniteIterator сам не остановится. Смещение пропускает первый day, лимит разрешает четыре следующих значения.

Остановить циклический источник после четырёх значенийСамостоятельный пример
<?php
declare(strict_types=1);

$cycle = new InfiniteIterator(new ArrayIterator(['day', 'night']));
$limited = new LimitIterator($cycle, 1, 4);
$limited->rewind();
$position = 1;
while ($limited->valid()) {
    echo $position, ':', $limited->current(), "\n";
    $position++;
    $limited->next();
}
Ожидаемый результат
1:night
2:day
3:night
4:day

rewind() LimitIterator позиционировал внутренний цикл на offset 1. Ключи InfiniteIterator повторяют ключи day/night, поэтому итоговую позицию считает отдельная переменная. valid() стал false после четырёх элементов, хотя сам InfiniteIterator оставался способен продолжаться.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

LimitIterator::current

(PHP 5 >= 5.1.0, PHP 7, PHP 8) LimitIterator::current — Get current element

Description

public function LimitIterator::current(): mixed

Gets the current element of the inner Iterator.

Parameters

This function has no parameters.

Return Values

Returns the current element or null if there is none.

See Also

LimitIterator::key() - Get current key

LimitIterator::next() - Move the iterator forward

LimitIterator::rewind() - Rewind the iterator to the specified starting offset

LimitIterator::seek() - Seek to the given position

LimitIterator::valid() - Check whether the current element is valid

Связанные карточки: InfiniteIterator::__construct, ArrayIterator::seek.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

LimitIterator::getPositionLimitIterator::getPosition: получить позицию внутри окна LimitIterator

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function LimitIterator::getPosition(): int

LimitIterator::getPosition нужен, чтобы получить позицию внутри окна LimitIterator. В этой задаче LimitIterator помогает взять окно из большого обхода: страницу каталога, первые N результатов или ограниченное число повторов. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function LimitIterator::getPosition(): int
Результатint: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения вложенного источника не скрываются. Особые значения, предупреждения и версии перечислены в полном официальном контракте ниже.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

В памяти пять товаров, а интерфейс показывает окно из двух значений, начиная с позиции 2.

Показать вторую страницу каталогаСамостоятельный пример
<?php
declare(strict_types=1);

$catalog = new ArrayIterator(['A', 'B', 'C', 'D', 'E']);
$page = new LimitIterator($catalog, 2, 2);
foreach ($page as $key => $item) {
    echo 'source=', $page->getPosition(), '; key=', $key, '; item=', $item, "\n";
}
$page->seek(3);
echo 'seek result: ', $page->current(), "\n";
Ожидаемый результат
source=2; key=2; item=C
source=3; key=3; item=D
seek result: D

Конструктор ограничил видимый диапазон C–D. getPosition() показал абсолютную позицию внутреннего источника. seek(3) допустим внутри окна и выбрал D.

Скачать самостоятельный пример с fixtures, результатом и README

InfiniteIterator сам не остановится. Смещение пропускает первый day, лимит разрешает четыре следующих значения.

Остановить циклический источник после четырёх значенийСамостоятельный пример
<?php
declare(strict_types=1);

$cycle = new InfiniteIterator(new ArrayIterator(['day', 'night']));
$limited = new LimitIterator($cycle, 1, 4);
$limited->rewind();
$position = 1;
while ($limited->valid()) {
    echo $position, ':', $limited->current(), "\n";
    $position++;
    $limited->next();
}
Ожидаемый результат
1:night
2:day
3:night
4:day

rewind() LimitIterator позиционировал внутренний цикл на offset 1. Ключи InfiniteIterator повторяют ключи day/night, поэтому итоговую позицию считает отдельная переменная. valid() стал false после четырёх элементов, хотя сам InfiniteIterator оставался способен продолжаться.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

LimitIterator::getPosition

(PHP 5 >= 5.1.0, PHP 7, PHP 8) LimitIterator::getPosition — Return the current position

Description

public function LimitIterator::getPosition(): int

Gets the current zero-based position of the inner Iterator.

Parameters

This function has no parameters.

Return Values

The current position.

See Also

FilterIterator::key() - Get the current key

Связанные карточки: InfiniteIterator::__construct, ArrayIterator::seek.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

LimitIterator::keyLimitIterator::key: получить ключ или позицию текущего элемента

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function LimitIterator::key(): mixed

LimitIterator::key нужен, чтобы получить ключ или позицию текущего элемента. В этой задаче LimitIterator помогает взять окно из большого обхода: страницу каталога, первые N результатов или ограниченное число повторов. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function LimitIterator::key(): mixed
Результатmixed: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияСначала вызывайте valid(). Ключ может быть int, string или составным массивом и не обязан быть бизнес-идентификатором.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

В памяти пять товаров, а интерфейс показывает окно из двух значений, начиная с позиции 2.

Показать вторую страницу каталогаСамостоятельный пример
<?php
declare(strict_types=1);

$catalog = new ArrayIterator(['A', 'B', 'C', 'D', 'E']);
$page = new LimitIterator($catalog, 2, 2);
foreach ($page as $key => $item) {
    echo 'source=', $page->getPosition(), '; key=', $key, '; item=', $item, "\n";
}
$page->seek(3);
echo 'seek result: ', $page->current(), "\n";
Ожидаемый результат
source=2; key=2; item=C
source=3; key=3; item=D
seek result: D

Конструктор ограничил видимый диапазон C–D. getPosition() показал абсолютную позицию внутреннего источника. seek(3) допустим внутри окна и выбрал D.

Скачать самостоятельный пример с fixtures, результатом и README

InfiniteIterator сам не остановится. Смещение пропускает первый day, лимит разрешает четыре следующих значения.

Остановить циклический источник после четырёх значенийСамостоятельный пример
<?php
declare(strict_types=1);

$cycle = new InfiniteIterator(new ArrayIterator(['day', 'night']));
$limited = new LimitIterator($cycle, 1, 4);
$limited->rewind();
$position = 1;
while ($limited->valid()) {
    echo $position, ':', $limited->current(), "\n";
    $position++;
    $limited->next();
}
Ожидаемый результат
1:night
2:day
3:night
4:day

rewind() LimitIterator позиционировал внутренний цикл на offset 1. Ключи InfiniteIterator повторяют ключи day/night, поэтому итоговую позицию считает отдельная переменная. valid() стал false после четырёх элементов, хотя сам InfiniteIterator оставался способен продолжаться.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

LimitIterator::key

(PHP 5 >= 5.1.0, PHP 7, PHP 8) LimitIterator::key — Get current key

Description

public function LimitIterator::key(): mixed

Gets the key for the current item in the inner Iterator.

Parameters

This function has no parameters.

Return Values

Returns the key for the current item.

See Also

LimitIterator::getPosition() - Return the current position

LimitIterator::current() - Get current element

LimitIterator::next() - Move the iterator forward

LimitIterator::rewind() - Rewind the iterator to the specified starting offset

LimitIterator::seek() - Seek to the given position

LimitIterator::valid() - Check whether the current element is valid

Связанные карточки: InfiniteIterator::__construct, ArrayIterator::seek.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

LimitIterator::nextLimitIterator::next: перевести курсор к следующему элементу

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function LimitIterator::next(): void

LimitIterator::next нужен, чтобы перевести курсор к следующему элементу. В этой задаче LimitIterator помогает взять окно из большого обхода: страницу каталога, первые N результатов или ограниченное число повторов. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function LimitIterator::next(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияПродвижение одноразового источника нельзя отменить. Исключение из вложенного источника передаётся вызывающему коду.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

В памяти пять товаров, а интерфейс показывает окно из двух значений, начиная с позиции 2.

Показать вторую страницу каталогаСамостоятельный пример
<?php
declare(strict_types=1);

$catalog = new ArrayIterator(['A', 'B', 'C', 'D', 'E']);
$page = new LimitIterator($catalog, 2, 2);
foreach ($page as $key => $item) {
    echo 'source=', $page->getPosition(), '; key=', $key, '; item=', $item, "\n";
}
$page->seek(3);
echo 'seek result: ', $page->current(), "\n";
Ожидаемый результат
source=2; key=2; item=C
source=3; key=3; item=D
seek result: D

Конструктор ограничил видимый диапазон C–D. getPosition() показал абсолютную позицию внутреннего источника. seek(3) допустим внутри окна и выбрал D.

Скачать самостоятельный пример с fixtures, результатом и README

InfiniteIterator сам не остановится. Смещение пропускает первый day, лимит разрешает четыре следующих значения.

Остановить циклический источник после четырёх значенийСамостоятельный пример
<?php
declare(strict_types=1);

$cycle = new InfiniteIterator(new ArrayIterator(['day', 'night']));
$limited = new LimitIterator($cycle, 1, 4);
$limited->rewind();
$position = 1;
while ($limited->valid()) {
    echo $position, ':', $limited->current(), "\n";
    $position++;
    $limited->next();
}
Ожидаемый результат
1:night
2:day
3:night
4:day

rewind() LimitIterator позиционировал внутренний цикл на offset 1. Ключи InfiniteIterator повторяют ключи day/night, поэтому итоговую позицию считает отдельная переменная. valid() стал false после четырёх элементов, хотя сам InfiniteIterator оставался способен продолжаться.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

LimitIterator::next

(PHP 5 >= 5.1.0, PHP 7, PHP 8) LimitIterator::next — Move the iterator forward

Description

public function LimitIterator::next(): void

Moves the iterator forward.

Parameters

This function has no parameters.

Return Values

No value is returned.

See Also

LimitIterator::current() - Get current element

LimitIterator::key() - Get current key

LimitIterator::rewind() - Rewind the iterator to the specified starting offset

LimitIterator::seek() - Seek to the given position

LimitIterator::valid() - Check whether the current element is valid

Связанные карточки: InfiniteIterator::__construct, ArrayIterator::seek.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

LimitIterator::rewindLimitIterator::rewind: попытаться установить курсор на первый элемент

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function LimitIterator::rewind(): void

LimitIterator::rewind нужен, чтобы попытаться установить курсор на первый элемент. В этой задаче LimitIterator помогает взять окно из большого обхода: страницу каталога, первые N результатов или ограниченное число повторов. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function LimitIterator::rewind(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияНе каждый Traversable можно повторить. NoRewindIterator намеренно игнорирует повторную перемотку, а Generator после завершения может выбросить исключение.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

В памяти пять товаров, а интерфейс показывает окно из двух значений, начиная с позиции 2.

Показать вторую страницу каталогаСамостоятельный пример
<?php
declare(strict_types=1);

$catalog = new ArrayIterator(['A', 'B', 'C', 'D', 'E']);
$page = new LimitIterator($catalog, 2, 2);
foreach ($page as $key => $item) {
    echo 'source=', $page->getPosition(), '; key=', $key, '; item=', $item, "\n";
}
$page->seek(3);
echo 'seek result: ', $page->current(), "\n";
Ожидаемый результат
source=2; key=2; item=C
source=3; key=3; item=D
seek result: D

Конструктор ограничил видимый диапазон C–D. getPosition() показал абсолютную позицию внутреннего источника. seek(3) допустим внутри окна и выбрал D.

Скачать самостоятельный пример с fixtures, результатом и README

InfiniteIterator сам не остановится. Смещение пропускает первый day, лимит разрешает четыре следующих значения.

Остановить циклический источник после четырёх значенийСамостоятельный пример
<?php
declare(strict_types=1);

$cycle = new InfiniteIterator(new ArrayIterator(['day', 'night']));
$limited = new LimitIterator($cycle, 1, 4);
$limited->rewind();
$position = 1;
while ($limited->valid()) {
    echo $position, ':', $limited->current(), "\n";
    $position++;
    $limited->next();
}
Ожидаемый результат
1:night
2:day
3:night
4:day

rewind() LimitIterator позиционировал внутренний цикл на offset 1. Ключи InfiniteIterator повторяют ключи day/night, поэтому итоговую позицию считает отдельная переменная. valid() стал false после четырёх элементов, хотя сам InfiniteIterator оставался способен продолжаться.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

LimitIterator::rewind

(PHP 5 >= 5.1.0, PHP 7, PHP 8) LimitIterator::rewind — Rewind the iterator to the specified starting offset

Description

public function LimitIterator::rewind(): void

Rewinds the iterator to the starting offset specified in LimitIterator::__construct().

Parameters

This function has no parameters.

Return Values

No value is returned.

See Also

LimitIterator::current() - Get current element

LimitIterator::key() - Get current key

LimitIterator::next() - Move the iterator forward

LimitIterator::seek() - Seek to the given position

LimitIterator::valid() - Check whether the current element is valid

Связанные карточки: InfiniteIterator::__construct, ArrayIterator::seek.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

LimitIterator::seekLimitIterator::seek: перейти к заданной позиции обхода

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function LimitIterator::seek(int $offset): int

LimitIterator::seek нужен, чтобы перейти к заданной позиции обхода. В этой задаче LimitIterator помогает взять окно из большого обхода: страницу каталога, первые N результатов или ограниченное число повторов. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
offsetПозиция от нуля. Это место в порядке обхода, а не бизнес-ID записи.
Часть контрактаЧто важно
Сигнатураpublic function LimitIterator::seek(int $offset): int
Результатint: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияНедоступная позиция вызывает OutOfBoundsException. Позиции считаются в порядке данного итератора, а не по ключам исходных данных.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

В памяти пять товаров, а интерфейс показывает окно из двух значений, начиная с позиции 2.

Показать вторую страницу каталогаСамостоятельный пример
<?php
declare(strict_types=1);

$catalog = new ArrayIterator(['A', 'B', 'C', 'D', 'E']);
$page = new LimitIterator($catalog, 2, 2);
foreach ($page as $key => $item) {
    echo 'source=', $page->getPosition(), '; key=', $key, '; item=', $item, "\n";
}
$page->seek(3);
echo 'seek result: ', $page->current(), "\n";
Ожидаемый результат
source=2; key=2; item=C
source=3; key=3; item=D
seek result: D

Конструктор ограничил видимый диапазон C–D. getPosition() показал абсолютную позицию внутреннего источника. seek(3) допустим внутри окна и выбрал D.

Скачать самостоятельный пример с fixtures, результатом и README

InfiniteIterator сам не остановится. Смещение пропускает первый day, лимит разрешает четыре следующих значения.

Остановить циклический источник после четырёх значенийСамостоятельный пример
<?php
declare(strict_types=1);

$cycle = new InfiniteIterator(new ArrayIterator(['day', 'night']));
$limited = new LimitIterator($cycle, 1, 4);
$limited->rewind();
$position = 1;
while ($limited->valid()) {
    echo $position, ':', $limited->current(), "\n";
    $position++;
    $limited->next();
}
Ожидаемый результат
1:night
2:day
3:night
4:day

rewind() LimitIterator позиционировал внутренний цикл на offset 1. Ключи InfiniteIterator повторяют ключи day/night, поэтому итоговую позицию считает отдельная переменная. valid() стал false после четырёх элементов, хотя сам InfiniteIterator оставался способен продолжаться.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

LimitIterator::seek

(PHP 5 >= 5.1.0, PHP 7, PHP 8) LimitIterator::seek — Seek to the given position

Description

public function LimitIterator::seek(int $offset): int

Moves the iterator to the offset specified by offset.

Parameters

offset

The position to seek to.

Return Values

Returns the offset position after seeking.

Errors/Exceptions

Throws an OutOfBoundsException if the position is outside of the limits specified in LimitIterator::__construct().

See Also

LimitIterator::current() - Get current element

LimitIterator::key() - Get current key

LimitIterator::rewind() - Rewind the iterator to the specified starting offset

LimitIterator::next() - Move the iterator forward

LimitIterator::valid() - Check whether the current element is valid

Связанные карточки: InfiniteIterator::__construct, ArrayIterator::seek.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

LimitIterator::validLimitIterator::valid: проверить, указывает ли курсор на существующий элемент

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function LimitIterator::valid(): bool

LimitIterator::valid нужен, чтобы проверить, указывает ли курсор на существующий элемент. В этой задаче LimitIterator помогает взять окно из большого обхода: страницу каталога, первые N результатов или ограниченное число повторов. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function LimitIterator::valid(): bool
Результатbool: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияfalse означает отсутствие текущего элемента, а не ошибку бизнес-данных. Ошибки источника могут возникнуть отдельно.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

В памяти пять товаров, а интерфейс показывает окно из двух значений, начиная с позиции 2.

Показать вторую страницу каталогаСамостоятельный пример
<?php
declare(strict_types=1);

$catalog = new ArrayIterator(['A', 'B', 'C', 'D', 'E']);
$page = new LimitIterator($catalog, 2, 2);
foreach ($page as $key => $item) {
    echo 'source=', $page->getPosition(), '; key=', $key, '; item=', $item, "\n";
}
$page->seek(3);
echo 'seek result: ', $page->current(), "\n";
Ожидаемый результат
source=2; key=2; item=C
source=3; key=3; item=D
seek result: D

Конструктор ограничил видимый диапазон C–D. getPosition() показал абсолютную позицию внутреннего источника. seek(3) допустим внутри окна и выбрал D.

Скачать самостоятельный пример с fixtures, результатом и README

InfiniteIterator сам не остановится. Смещение пропускает первый day, лимит разрешает четыре следующих значения.

Остановить циклический источник после четырёх значенийСамостоятельный пример
<?php
declare(strict_types=1);

$cycle = new InfiniteIterator(new ArrayIterator(['day', 'night']));
$limited = new LimitIterator($cycle, 1, 4);
$limited->rewind();
$position = 1;
while ($limited->valid()) {
    echo $position, ':', $limited->current(), "\n";
    $position++;
    $limited->next();
}
Ожидаемый результат
1:night
2:day
3:night
4:day

rewind() LimitIterator позиционировал внутренний цикл на offset 1. Ключи InfiniteIterator повторяют ключи day/night, поэтому итоговую позицию считает отдельная переменная. valid() стал false после четырёх элементов, хотя сам InfiniteIterator оставался способен продолжаться.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

LimitIterator::valid

(PHP 5 >= 5.1.0, PHP 7, PHP 8) LimitIterator::valid — Check whether the current element is valid

Description

public function LimitIterator::valid(): bool

Checks whether the current element is valid.

Parameters

This function has no parameters.

Return Values

Returns true on success or false on failure.

See Also

LimitIterator::current() - Get current element

LimitIterator::key() - Get current key

LimitIterator::rewind() - Rewind the iterator to the specified starting offset

LimitIterator::next() - Move the iterator forward

LimitIterator::seek() - Seek to the given position

Связанные карточки: InfiniteIterator::__construct, ArrayIterator::seek.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

MultipleIterator::attachIteratorMultipleIterator::attachIterator: подключить ещё один синхронно читаемый итератор

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function MultipleIterator::attachIterator(Iterator $iterator, string|int|null $info = null): void

MultipleIterator::attachIterator нужен, чтобы подключить ещё один синхронно читаемый итератор. В этой задаче MultipleIterator помогает синхронно читать несколько итераторов по одной позиции, например товары и цены. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
iteratorИсходный Iterator или Traversable указанного сигнатурой типа. Объект не копируется: декоратор читает тот же курсор.
infoНеобязательное связанное значение для прикрепляемого итератора MultipleIterator.
Часть контрактаЧто важно
Сигнатураpublic function MultipleIterator::attachIterator(Iterator $iterator, string|int|null $info = null): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияПовторное имя или несовместимая политика ключей может вызвать InvalidArgumentException; длины источников сверяются выбранными флагами.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Две колонки уже упорядочены одинаково. Нужно читать пару значений на каждом шаге без ручного управления двумя курсорами.

Собрать товар и остаток по одной позицииСамостоятельный пример
<?php
declare(strict_types=1);

$names = new ArrayIterator(['brush', 'paint']);
$qty = new ArrayIterator([2, 0]);
$rows = new MultipleIterator(MultipleIterator::MIT_NEED_ALL | MultipleIterator::MIT_KEYS_ASSOC);
$rows->attachIterator($names, 'name');
$rows->attachIterator($qty, 'qty');
foreach ($rows as $keys => $row) {
    echo $keys['name'], ':', $row['name'], '=', $row['qty'], "\n";
}
Ожидаемый результат
0:brush=2
1:paint=0

attachIterator() закрепил имена name и qty. current() сформировал ассоциативную пару, key() — ассоциативную пару исходных ключей. MIT_NEED_ALL потребовал наличие обеих колонок.

Скачать самостоятельный пример с fixtures, результатом и README

Источники имеют разную длину. Для отчёта допустима строка с null после окончания короткой колонки.

Проверить, перенастроить и отключить источникСамостоятельный пример
<?php
declare(strict_types=1);

$left = new ArrayIterator(['A']);
$right = new ArrayIterator([10, 20]);
$rows = new MultipleIterator();
$rows->attachIterator($left);
$rows->attachIterator($right);
echo 'count: ', $rows->countIterators(), "\n";
echo 'contains left: ', $rows->containsIterator($left) ? 'yes' : 'no', "\n";
$rows->setFlags(MultipleIterator::MIT_NEED_ANY | MultipleIterator::MIT_KEYS_NUMERIC);
echo 'need-any: ', (($rows->getFlags() & MultipleIterator::MIT_NEED_ALL) === MultipleIterator::MIT_NEED_ANY) ? 'yes' : 'no', "\n";
foreach ($rows as $row) { echo json_encode($row), "\n"; }
$rows->detachIterator($left);
echo 'after detach: ', $rows->countIterators(), "\n";
Ожидаемый результат
count: 2
contains left: yes
need-any: yes
["A",10]
[null,20]
after detach: 1

MIT_NEED_ANY разрешил второй ряд; отсутствующее значение стало null. Эта константа равна нулевому варианту битовой группы, поэтому режим проверяется сравнением замаскированной группы, а не обычным truthy-тестом. containsIterator() проверил идентичность объекта. detachIterator() отключил именно $left, и countIterators() уменьшился до одного.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

MultipleIterator::attachIterator

(PHP 5 >= 5.3.0, PHP 7, PHP 8) MultipleIterator::attachIterator — Attaches iterator information

Description

public function MultipleIterator::attachIterator(Iterator $iterator, string|int|null $info = null): void

Attaches iterator information.

WarningThis function is currently not documented; only its argument list is available.

Parameters

iterator

The new iterator to attach.

info

The associative information for the Iterator, which must be an int, a string, or null.

Return Values

Description...

Errors/Exceptions

An IllegalValueException if the iterator parameter is invalid, or if info is already associated information.

See Also

MultipleIterator::__construct() - Constructs a new MultipleIterator

Связанные карточки: AppendIterator::append, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

MultipleIterator::__constructMultipleIterator::__construct: создать и настроить объект для дальнейшего обхода

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function MultipleIterator::__construct(int $flags = 1)

MultipleIterator::__construct нужен, чтобы создать и настроить объект для дальнейшего обхода. В этой задаче MultipleIterator помогает синхронно читать несколько итераторов по одной позиции, например товары и цены. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
flagsБитовая маска режима. Оператор | объединяет совместимые константы; setFlags заменяет прежнюю маску целиком.
Часть контрактаЧто важно
Сигнатураpublic function MultipleIterator::__construct(int $flags = 1)
РезультатКонструктор не возвращает прикладное значение; выражение new создаёт объект, который затем сохраняется в переменной.
Ошибки и особые значенияНеподходящий тип аргумента приводит к TypeError; несовместимые флаги, маска или путь имеют отдельные ValueError/RuntimeException либо файловые предупреждения согласно полному контракту.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Две колонки уже упорядочены одинаково. Нужно читать пару значений на каждом шаге без ручного управления двумя курсорами.

Собрать товар и остаток по одной позицииСамостоятельный пример
<?php
declare(strict_types=1);

$names = new ArrayIterator(['brush', 'paint']);
$qty = new ArrayIterator([2, 0]);
$rows = new MultipleIterator(MultipleIterator::MIT_NEED_ALL | MultipleIterator::MIT_KEYS_ASSOC);
$rows->attachIterator($names, 'name');
$rows->attachIterator($qty, 'qty');
foreach ($rows as $keys => $row) {
    echo $keys['name'], ':', $row['name'], '=', $row['qty'], "\n";
}
Ожидаемый результат
0:brush=2
1:paint=0

attachIterator() закрепил имена name и qty. current() сформировал ассоциативную пару, key() — ассоциативную пару исходных ключей. MIT_NEED_ALL потребовал наличие обеих колонок.

Скачать самостоятельный пример с fixtures, результатом и README

Этот пример раскрывает общий Iterator-протокол для двух синхронных источников.

Пройти составной итератор вручнуюСамостоятельный пример
<?php
declare(strict_types=1);

$rows = new MultipleIterator();
$rows->attachIterator(new ArrayIterator(['x', 'y']));
$rows->attachIterator(new ArrayIterator([1, 2]));
$rows->rewind();
while ($rows->valid()) {
    echo json_encode($rows->key()), '=', json_encode($rows->current()), "\n";
    $rows->next();
}
$rows->rewind();
echo 'again: ', json_encode($rows->current()), "\n";
Ожидаемый результат
[0,0]=["x",1]
[1,1]=["y",2]
again: ["x",1]

rewind()/next()/valid() управляли обоими внутренними курсорами. key() и current() вернули составные массивы. Повторный rewind() сработал, потому что оба ArrayIterator повторяемы.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

MultipleIterator::__construct

(PHP 5 >= 5.3.0, PHP 7, PHP 8) MultipleIterator::__construct — Constructs a new MultipleIterator

Description

public function MultipleIterator::__construct(int $flags = MultipleIterator::MIT_NEED_ALL | MultipleIterator::MIT_KEYS_NUMERIC)

Construct a new MultipleIterator.

Parameters

flags

The flags to set, according to the Flag Constants.

MultipleIterator::MIT_NEED_ALL or MultipleIterator::MIT_NEED_ANY

MultipleIterator::MIT_KEYS_NUMERIC or MultipleIterator::MIT_KEYS_ASSOC

Defaults to MultipleIterator::MIT_NEED_ALL|MultipleIterator::MIT_KEYS_NUMERIC.

See Also

Flag Constants

MultipleIterator::valid() - Checks the validity of sub iterators

Связанные карточки: AppendIterator::append, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

MultipleIterator::containsIteratorMultipleIterator::containsIterator: проверить, подключён ли конкретный объект-итератор

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function MultipleIterator::containsIterator(Iterator $iterator): bool

MultipleIterator::containsIterator нужен, чтобы проверить, подключён ли конкретный объект-итератор. В этой задаче MultipleIterator помогает синхронно читать несколько итераторов по одной позиции, например товары и цены. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
iteratorИсходный Iterator или Traversable указанного сигнатурой типа. Объект не копируется: декоратор читает тот же курсор.
Часть контрактаЧто важно
Сигнатураpublic function MultipleIterator::containsIterator(Iterator $iterator): bool
Результатbool: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения вложенного источника не скрываются. Особые значения, предупреждения и версии перечислены в полном официальном контракте ниже.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Источники имеют разную длину. Для отчёта допустима строка с null после окончания короткой колонки.

Проверить, перенастроить и отключить источникСамостоятельный пример
<?php
declare(strict_types=1);

$left = new ArrayIterator(['A']);
$right = new ArrayIterator([10, 20]);
$rows = new MultipleIterator();
$rows->attachIterator($left);
$rows->attachIterator($right);
echo 'count: ', $rows->countIterators(), "\n";
echo 'contains left: ', $rows->containsIterator($left) ? 'yes' : 'no', "\n";
$rows->setFlags(MultipleIterator::MIT_NEED_ANY | MultipleIterator::MIT_KEYS_NUMERIC);
echo 'need-any: ', (($rows->getFlags() & MultipleIterator::MIT_NEED_ALL) === MultipleIterator::MIT_NEED_ANY) ? 'yes' : 'no', "\n";
foreach ($rows as $row) { echo json_encode($row), "\n"; }
$rows->detachIterator($left);
echo 'after detach: ', $rows->countIterators(), "\n";
Ожидаемый результат
count: 2
contains left: yes
need-any: yes
["A",10]
[null,20]
after detach: 1

MIT_NEED_ANY разрешил второй ряд; отсутствующее значение стало null. Эта константа равна нулевому варианту битовой группы, поэтому режим проверяется сравнением замаскированной группы, а не обычным truthy-тестом. containsIterator() проверил идентичность объекта. detachIterator() отключил именно $left, и countIterators() уменьшился до одного.

Скачать самостоятельный пример с fixtures, результатом и README

Две колонки уже упорядочены одинаково. Нужно читать пару значений на каждом шаге без ручного управления двумя курсорами.

Собрать товар и остаток по одной позицииСамостоятельный пример
<?php
declare(strict_types=1);

$names = new ArrayIterator(['brush', 'paint']);
$qty = new ArrayIterator([2, 0]);
$rows = new MultipleIterator(MultipleIterator::MIT_NEED_ALL | MultipleIterator::MIT_KEYS_ASSOC);
$rows->attachIterator($names, 'name');
$rows->attachIterator($qty, 'qty');
foreach ($rows as $keys => $row) {
    echo $keys['name'], ':', $row['name'], '=', $row['qty'], "\n";
}
Ожидаемый результат
0:brush=2
1:paint=0

attachIterator() закрепил имена name и qty. current() сформировал ассоциативную пару, key() — ассоциативную пару исходных ключей. MIT_NEED_ALL потребовал наличие обеих колонок.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

MultipleIterator::containsIterator

(PHP 5 >= 5.3.0, PHP 7, PHP 8) MultipleIterator::containsIterator — Checks if an iterator is attached

Description

public function MultipleIterator::containsIterator(Iterator $iterator): bool

Checks if an iterator is attached or not.

WarningThis function is currently not documented; only its argument list is available.

Parameters

iterator

The iterator to check.

Return Values

Returns true on success or false on failure.

See Also

MultipleIterator::valid() - Checks the validity of sub iterators

Связанные карточки: AppendIterator::append, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

MultipleIterator::countIteratorsMultipleIterator::countIterators: получить число подключённых синхронных источников

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function MultipleIterator::countIterators(): int

MultipleIterator::countIterators нужен, чтобы получить число подключённых синхронных источников. В этой задаче MultipleIterator помогает синхронно читать несколько итераторов по одной позиции, например товары и цены. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function MultipleIterator::countIterators(): int
Результатint: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения вложенного источника не скрываются. Особые значения, предупреждения и версии перечислены в полном официальном контракте ниже.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Источники имеют разную длину. Для отчёта допустима строка с null после окончания короткой колонки.

Проверить, перенастроить и отключить источникСамостоятельный пример
<?php
declare(strict_types=1);

$left = new ArrayIterator(['A']);
$right = new ArrayIterator([10, 20]);
$rows = new MultipleIterator();
$rows->attachIterator($left);
$rows->attachIterator($right);
echo 'count: ', $rows->countIterators(), "\n";
echo 'contains left: ', $rows->containsIterator($left) ? 'yes' : 'no', "\n";
$rows->setFlags(MultipleIterator::MIT_NEED_ANY | MultipleIterator::MIT_KEYS_NUMERIC);
echo 'need-any: ', (($rows->getFlags() & MultipleIterator::MIT_NEED_ALL) === MultipleIterator::MIT_NEED_ANY) ? 'yes' : 'no', "\n";
foreach ($rows as $row) { echo json_encode($row), "\n"; }
$rows->detachIterator($left);
echo 'after detach: ', $rows->countIterators(), "\n";
Ожидаемый результат
count: 2
contains left: yes
need-any: yes
["A",10]
[null,20]
after detach: 1

MIT_NEED_ANY разрешил второй ряд; отсутствующее значение стало null. Эта константа равна нулевому варианту битовой группы, поэтому режим проверяется сравнением замаскированной группы, а не обычным truthy-тестом. containsIterator() проверил идентичность объекта. detachIterator() отключил именно $left, и countIterators() уменьшился до одного.

Скачать самостоятельный пример с fixtures, результатом и README

Две колонки уже упорядочены одинаково. Нужно читать пару значений на каждом шаге без ручного управления двумя курсорами.

Собрать товар и остаток по одной позицииСамостоятельный пример
<?php
declare(strict_types=1);

$names = new ArrayIterator(['brush', 'paint']);
$qty = new ArrayIterator([2, 0]);
$rows = new MultipleIterator(MultipleIterator::MIT_NEED_ALL | MultipleIterator::MIT_KEYS_ASSOC);
$rows->attachIterator($names, 'name');
$rows->attachIterator($qty, 'qty');
foreach ($rows as $keys => $row) {
    echo $keys['name'], ':', $row['name'], '=', $row['qty'], "\n";
}
Ожидаемый результат
0:brush=2
1:paint=0

attachIterator() закрепил имена name и qty. current() сформировал ассоциативную пару, key() — ассоциативную пару исходных ключей. MIT_NEED_ALL потребовал наличие обеих колонок.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

MultipleIterator::countIterators

(PHP 5 >= 5.3.0, PHP 7, PHP 8) MultipleIterator::countIterators — Gets the number of attached iterator instances

Description

public function MultipleIterator::countIterators(): int

Gets the number of attached iterator instances.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

The number of attached iterator instances (as an int).

See Also

MultipleIterator::containsIterator() - Checks if an iterator is attached

Связанные карточки: AppendIterator::append, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

MultipleIterator::currentMultipleIterator::current: получить текущее значение без продвижения курсора

PHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.1.0) · SPL

public function MultipleIterator::current(): array

MultipleIterator::current нужен, чтобы получить текущее значение без продвижения курсора. В этой задаче MultipleIterator помогает синхронно читать несколько итераторов по одной позиции, например товары и цены. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function MultipleIterator::current(): array
Результатarray: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияСначала вызывайте valid(). На недействительном курсоре особое значение зависит от класса и не должно смешиваться с настоящим null.
ВерсииPHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.1.0)

Две колонки уже упорядочены одинаково. Нужно читать пару значений на каждом шаге без ручного управления двумя курсорами.

Собрать товар и остаток по одной позицииСамостоятельный пример
<?php
declare(strict_types=1);

$names = new ArrayIterator(['brush', 'paint']);
$qty = new ArrayIterator([2, 0]);
$rows = new MultipleIterator(MultipleIterator::MIT_NEED_ALL | MultipleIterator::MIT_KEYS_ASSOC);
$rows->attachIterator($names, 'name');
$rows->attachIterator($qty, 'qty');
foreach ($rows as $keys => $row) {
    echo $keys['name'], ':', $row['name'], '=', $row['qty'], "\n";
}
Ожидаемый результат
0:brush=2
1:paint=0

attachIterator() закрепил имена name и qty. current() сформировал ассоциативную пару, key() — ассоциативную пару исходных ключей. MIT_NEED_ALL потребовал наличие обеих колонок.

Скачать самостоятельный пример с fixtures, результатом и README

Этот пример раскрывает общий Iterator-протокол для двух синхронных источников.

Пройти составной итератор вручнуюСамостоятельный пример
<?php
declare(strict_types=1);

$rows = new MultipleIterator();
$rows->attachIterator(new ArrayIterator(['x', 'y']));
$rows->attachIterator(new ArrayIterator([1, 2]));
$rows->rewind();
while ($rows->valid()) {
    echo json_encode($rows->key()), '=', json_encode($rows->current()), "\n";
    $rows->next();
}
$rows->rewind();
echo 'again: ', json_encode($rows->current()), "\n";
Ожидаемый результат
[0,0]=["x",1]
[1,1]=["y",2]
again: ["x",1]

rewind()/next()/valid() управляли обоими внутренними курсорами. key() и current() вернули составные массивы. Повторный rewind() сработал, потому что оба ArrayIterator повторяемы.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

MultipleIterator::current

(PHP 5 >= 5.3.0, PHP 7, PHP 8) MultipleIterator::current — Gets the registered iterator instances

Description

public function MultipleIterator::current(): array

Get the registered iterator instances current() result.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

An array containing the current values of each attached iterator.

Errors/Exceptions

A RuntimeException if the iterator is invalid (as of PHP 8.1.0), or mode MIT_NEED_ALL is set and at least one attached iterator is not valid. Or an IllegalValueException if a key is null and MIT_KEYS_ASSOC is set.

Changelog

Version Description

8.1.0

A RuntimeException is now thrown if MultipleIterator::current() is called on an invalid iterator. Previously, false was returned.

See Also

MultipleIterator::valid() - Checks the validity of sub iterators

Связанные карточки: AppendIterator::append, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

MultipleIterator::detachIteratorMultipleIterator::detachIterator: отключить конкретный итератор от синхронного обхода

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function MultipleIterator::detachIterator(Iterator $iterator): void

MultipleIterator::detachIterator нужен, чтобы отключить конкретный итератор от синхронного обхода. В этой задаче MultipleIterator помогает синхронно читать несколько итераторов по одной позиции, например товары и цены. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
iteratorИсходный Iterator или Traversable указанного сигнатурой типа. Объект не копируется: декоратор читает тот же курсор.
Часть контрактаЧто важно
Сигнатураpublic function MultipleIterator::detachIterator(Iterator $iterator): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияОтключается тот же объект Iterator, а не новый объект с равными данными.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Источники имеют разную длину. Для отчёта допустима строка с null после окончания короткой колонки.

Проверить, перенастроить и отключить источникСамостоятельный пример
<?php
declare(strict_types=1);

$left = new ArrayIterator(['A']);
$right = new ArrayIterator([10, 20]);
$rows = new MultipleIterator();
$rows->attachIterator($left);
$rows->attachIterator($right);
echo 'count: ', $rows->countIterators(), "\n";
echo 'contains left: ', $rows->containsIterator($left) ? 'yes' : 'no', "\n";
$rows->setFlags(MultipleIterator::MIT_NEED_ANY | MultipleIterator::MIT_KEYS_NUMERIC);
echo 'need-any: ', (($rows->getFlags() & MultipleIterator::MIT_NEED_ALL) === MultipleIterator::MIT_NEED_ANY) ? 'yes' : 'no', "\n";
foreach ($rows as $row) { echo json_encode($row), "\n"; }
$rows->detachIterator($left);
echo 'after detach: ', $rows->countIterators(), "\n";
Ожидаемый результат
count: 2
contains left: yes
need-any: yes
["A",10]
[null,20]
after detach: 1

MIT_NEED_ANY разрешил второй ряд; отсутствующее значение стало null. Эта константа равна нулевому варианту битовой группы, поэтому режим проверяется сравнением замаскированной группы, а не обычным truthy-тестом. containsIterator() проверил идентичность объекта. detachIterator() отключил именно $left, и countIterators() уменьшился до одного.

Скачать самостоятельный пример с fixtures, результатом и README

Две колонки уже упорядочены одинаково. Нужно читать пару значений на каждом шаге без ручного управления двумя курсорами.

Собрать товар и остаток по одной позицииСамостоятельный пример
<?php
declare(strict_types=1);

$names = new ArrayIterator(['brush', 'paint']);
$qty = new ArrayIterator([2, 0]);
$rows = new MultipleIterator(MultipleIterator::MIT_NEED_ALL | MultipleIterator::MIT_KEYS_ASSOC);
$rows->attachIterator($names, 'name');
$rows->attachIterator($qty, 'qty');
foreach ($rows as $keys => $row) {
    echo $keys['name'], ':', $row['name'], '=', $row['qty'], "\n";
}
Ожидаемый результат
0:brush=2
1:paint=0

attachIterator() закрепил имена name и qty. current() сформировал ассоциативную пару, key() — ассоциативную пару исходных ключей. MIT_NEED_ALL потребовал наличие обеих колонок.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

MultipleIterator::detachIterator

(PHP 5 >= 5.3.0, PHP 7, PHP 8) MultipleIterator::detachIterator — Detaches an iterator

Description

public function MultipleIterator::detachIterator(Iterator $iterator): void

Detaches an iterator.

WarningThis function is currently not documented; only its argument list is available.

Parameters

iterator

The iterator to detach.

Return Values

No value is returned.

See Also

MultipleIterator::attachIterator() - Attaches iterator information

Связанные карточки: AppendIterator::append, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

MultipleIterator::getFlagsMultipleIterator::getFlags: прочитать действующую битовую маску режима объекта

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function MultipleIterator::getFlags(): int

MultipleIterator::getFlags нужен, чтобы прочитать действующую битовую маску режима объекта. В этой задаче MultipleIterator помогает синхронно читать несколько итераторов по одной позиции, например товары и цены. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function MultipleIterator::getFlags(): int
Результатint: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения вложенного источника не скрываются. Особые значения, предупреждения и версии перечислены в полном официальном контракте ниже.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Источники имеют разную длину. Для отчёта допустима строка с null после окончания короткой колонки.

Проверить, перенастроить и отключить источникСамостоятельный пример
<?php
declare(strict_types=1);

$left = new ArrayIterator(['A']);
$right = new ArrayIterator([10, 20]);
$rows = new MultipleIterator();
$rows->attachIterator($left);
$rows->attachIterator($right);
echo 'count: ', $rows->countIterators(), "\n";
echo 'contains left: ', $rows->containsIterator($left) ? 'yes' : 'no', "\n";
$rows->setFlags(MultipleIterator::MIT_NEED_ANY | MultipleIterator::MIT_KEYS_NUMERIC);
echo 'need-any: ', (($rows->getFlags() & MultipleIterator::MIT_NEED_ALL) === MultipleIterator::MIT_NEED_ANY) ? 'yes' : 'no', "\n";
foreach ($rows as $row) { echo json_encode($row), "\n"; }
$rows->detachIterator($left);
echo 'after detach: ', $rows->countIterators(), "\n";
Ожидаемый результат
count: 2
contains left: yes
need-any: yes
["A",10]
[null,20]
after detach: 1

MIT_NEED_ANY разрешил второй ряд; отсутствующее значение стало null. Эта константа равна нулевому варианту битовой группы, поэтому режим проверяется сравнением замаскированной группы, а не обычным truthy-тестом. containsIterator() проверил идентичность объекта. detachIterator() отключил именно $left, и countIterators() уменьшился до одного.

Скачать самостоятельный пример с fixtures, результатом и README

Две колонки уже упорядочены одинаково. Нужно читать пару значений на каждом шаге без ручного управления двумя курсорами.

Собрать товар и остаток по одной позицииСамостоятельный пример
<?php
declare(strict_types=1);

$names = new ArrayIterator(['brush', 'paint']);
$qty = new ArrayIterator([2, 0]);
$rows = new MultipleIterator(MultipleIterator::MIT_NEED_ALL | MultipleIterator::MIT_KEYS_ASSOC);
$rows->attachIterator($names, 'name');
$rows->attachIterator($qty, 'qty');
foreach ($rows as $keys => $row) {
    echo $keys['name'], ':', $row['name'], '=', $row['qty'], "\n";
}
Ожидаемый результат
0:brush=2
1:paint=0

attachIterator() закрепил имена name и qty. current() сформировал ассоциативную пару, key() — ассоциативную пару исходных ключей. MIT_NEED_ALL потребовал наличие обеих колонок.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

MultipleIterator::getFlags

(PHP 5 >= 5.3.0, PHP 7, PHP 8) MultipleIterator::getFlags — Gets the flag information

Description

public function MultipleIterator::getFlags(): int

Gets information about the flags.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

Information about the flags, as an int.

See Also

Flag Constants

MultipleIterator::__construct() - Constructs a new MultipleIterator

MultipleIterator::setFlags() - Sets flags

Связанные карточки: AppendIterator::append, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

MultipleIterator::keyMultipleIterator::key: получить ключ или позицию текущего элемента

PHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.1.0) · SPL

public function MultipleIterator::key(): array

MultipleIterator::key нужен, чтобы получить ключ или позицию текущего элемента. В этой задаче MultipleIterator помогает синхронно читать несколько итераторов по одной позиции, например товары и цены. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function MultipleIterator::key(): array
Результатarray: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияСначала вызывайте valid(). Ключ может быть int, string или составным массивом и не обязан быть бизнес-идентификатором.
ВерсииPHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.1.0)

Две колонки уже упорядочены одинаково. Нужно читать пару значений на каждом шаге без ручного управления двумя курсорами.

Собрать товар и остаток по одной позицииСамостоятельный пример
<?php
declare(strict_types=1);

$names = new ArrayIterator(['brush', 'paint']);
$qty = new ArrayIterator([2, 0]);
$rows = new MultipleIterator(MultipleIterator::MIT_NEED_ALL | MultipleIterator::MIT_KEYS_ASSOC);
$rows->attachIterator($names, 'name');
$rows->attachIterator($qty, 'qty');
foreach ($rows as $keys => $row) {
    echo $keys['name'], ':', $row['name'], '=', $row['qty'], "\n";
}
Ожидаемый результат
0:brush=2
1:paint=0

attachIterator() закрепил имена name и qty. current() сформировал ассоциативную пару, key() — ассоциативную пару исходных ключей. MIT_NEED_ALL потребовал наличие обеих колонок.

Скачать самостоятельный пример с fixtures, результатом и README

Этот пример раскрывает общий Iterator-протокол для двух синхронных источников.

Пройти составной итератор вручнуюСамостоятельный пример
<?php
declare(strict_types=1);

$rows = new MultipleIterator();
$rows->attachIterator(new ArrayIterator(['x', 'y']));
$rows->attachIterator(new ArrayIterator([1, 2]));
$rows->rewind();
while ($rows->valid()) {
    echo json_encode($rows->key()), '=', json_encode($rows->current()), "\n";
    $rows->next();
}
$rows->rewind();
echo 'again: ', json_encode($rows->current()), "\n";
Ожидаемый результат
[0,0]=["x",1]
[1,1]=["y",2]
again: ["x",1]

rewind()/next()/valid() управляли обоими внутренними курсорами. key() и current() вернули составные массивы. Повторный rewind() сработал, потому что оба ArrayIterator повторяемы.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

MultipleIterator::key

(PHP 5 >= 5.3.0, PHP 7, PHP 8) MultipleIterator::key — Gets the registered iterator instances

Description

public function MultipleIterator::key(): array

Get the registered iterator instances key() result.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

An array of all registered iterator instances.

Errors/Exceptions

A RuntimeException if the iterator is invalid (as of PHP 8.1.0), or mode MIT_NEED_ALL is set, and at least one attached iterator is not valid.

Calling this method from foreach triggers warning "Illegal type returned".

Changelog

Version Description

8.1.0

A RuntimeException is now thrown if MultipleIterator::key() is called on an invalid iterator. Previously, false was returned.

See Also

MultipleIterator::current() - Gets the registered iterator instances

Связанные карточки: AppendIterator::append, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

MultipleIterator::nextMultipleIterator::next: перевести курсор к следующему элементу

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function MultipleIterator::next(): void

MultipleIterator::next нужен, чтобы перевести курсор к следующему элементу. В этой задаче MultipleIterator помогает синхронно читать несколько итераторов по одной позиции, например товары и цены. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function MultipleIterator::next(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияПродвижение одноразового источника нельзя отменить. Исключение из вложенного источника передаётся вызывающему коду.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Этот пример раскрывает общий Iterator-протокол для двух синхронных источников.

Пройти составной итератор вручнуюСамостоятельный пример
<?php
declare(strict_types=1);

$rows = new MultipleIterator();
$rows->attachIterator(new ArrayIterator(['x', 'y']));
$rows->attachIterator(new ArrayIterator([1, 2]));
$rows->rewind();
while ($rows->valid()) {
    echo json_encode($rows->key()), '=', json_encode($rows->current()), "\n";
    $rows->next();
}
$rows->rewind();
echo 'again: ', json_encode($rows->current()), "\n";
Ожидаемый результат
[0,0]=["x",1]
[1,1]=["y",2]
again: ["x",1]

rewind()/next()/valid() управляли обоими внутренними курсорами. key() и current() вернули составные массивы. Повторный rewind() сработал, потому что оба ArrayIterator повторяемы.

Скачать самостоятельный пример с fixtures, результатом и README

Две колонки уже упорядочены одинаково. Нужно читать пару значений на каждом шаге без ручного управления двумя курсорами.

Собрать товар и остаток по одной позицииСамостоятельный пример
<?php
declare(strict_types=1);

$names = new ArrayIterator(['brush', 'paint']);
$qty = new ArrayIterator([2, 0]);
$rows = new MultipleIterator(MultipleIterator::MIT_NEED_ALL | MultipleIterator::MIT_KEYS_ASSOC);
$rows->attachIterator($names, 'name');
$rows->attachIterator($qty, 'qty');
foreach ($rows as $keys => $row) {
    echo $keys['name'], ':', $row['name'], '=', $row['qty'], "\n";
}
Ожидаемый результат
0:brush=2
1:paint=0

attachIterator() закрепил имена name и qty. current() сформировал ассоциативную пару, key() — ассоциативную пару исходных ключей. MIT_NEED_ALL потребовал наличие обеих колонок.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

MultipleIterator::next

(PHP 5 >= 5.3.0, PHP 7, PHP 8) MultipleIterator::next — Moves all attached iterator instances forward

Description

public function MultipleIterator::next(): void

Moves all attached iterator instances forward.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

No value is returned.

See Also

MultipleIterator::rewind() - Rewinds all attached iterator instances

Связанные карточки: AppendIterator::append, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

MultipleIterator::rewindMultipleIterator::rewind: попытаться установить курсор на первый элемент

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function MultipleIterator::rewind(): void

MultipleIterator::rewind нужен, чтобы попытаться установить курсор на первый элемент. В этой задаче MultipleIterator помогает синхронно читать несколько итераторов по одной позиции, например товары и цены. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function MultipleIterator::rewind(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияНе каждый Traversable можно повторить. NoRewindIterator намеренно игнорирует повторную перемотку, а Generator после завершения может выбросить исключение.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Этот пример раскрывает общий Iterator-протокол для двух синхронных источников.

Пройти составной итератор вручнуюСамостоятельный пример
<?php
declare(strict_types=1);

$rows = new MultipleIterator();
$rows->attachIterator(new ArrayIterator(['x', 'y']));
$rows->attachIterator(new ArrayIterator([1, 2]));
$rows->rewind();
while ($rows->valid()) {
    echo json_encode($rows->key()), '=', json_encode($rows->current()), "\n";
    $rows->next();
}
$rows->rewind();
echo 'again: ', json_encode($rows->current()), "\n";
Ожидаемый результат
[0,0]=["x",1]
[1,1]=["y",2]
again: ["x",1]

rewind()/next()/valid() управляли обоими внутренними курсорами. key() и current() вернули составные массивы. Повторный rewind() сработал, потому что оба ArrayIterator повторяемы.

Скачать самостоятельный пример с fixtures, результатом и README

Две колонки уже упорядочены одинаково. Нужно читать пару значений на каждом шаге без ручного управления двумя курсорами.

Собрать товар и остаток по одной позицииСамостоятельный пример
<?php
declare(strict_types=1);

$names = new ArrayIterator(['brush', 'paint']);
$qty = new ArrayIterator([2, 0]);
$rows = new MultipleIterator(MultipleIterator::MIT_NEED_ALL | MultipleIterator::MIT_KEYS_ASSOC);
$rows->attachIterator($names, 'name');
$rows->attachIterator($qty, 'qty');
foreach ($rows as $keys => $row) {
    echo $keys['name'], ':', $row['name'], '=', $row['qty'], "\n";
}
Ожидаемый результат
0:brush=2
1:paint=0

attachIterator() закрепил имена name и qty. current() сформировал ассоциативную пару, key() — ассоциативную пару исходных ключей. MIT_NEED_ALL потребовал наличие обеих колонок.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

MultipleIterator::rewind

(PHP 5 >= 5.3.0, PHP 7, PHP 8) MultipleIterator::rewind — Rewinds all attached iterator instances

Description

public function MultipleIterator::rewind(): void

Rewinds all attached iterator instances.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

No value is returned.

See Also

MultipleIterator::next() - Moves all attached iterator instances forward

Связанные карточки: AppendIterator::append, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

MultipleIterator::setFlagsMultipleIterator::setFlags: заменить действующую битовую маску режима

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function MultipleIterator::setFlags(int $flags): void

MultipleIterator::setFlags нужен, чтобы заменить действующую битовую маску режима. В этой задаче MultipleIterator помогает синхронно читать несколько итераторов по одной позиции, например товары и цены. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
flagsБитовая маска режима. Оператор | объединяет совместимые константы; setFlags заменяет прежнюю маску целиком.
Часть контрактаЧто важно
Сигнатураpublic function MultipleIterator::setFlags(int $flags): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияНеверная комбинация констант может дать ValueError либо неожиданную форму current/key; проверяйте полный контракт.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Источники имеют разную длину. Для отчёта допустима строка с null после окончания короткой колонки.

Проверить, перенастроить и отключить источникСамостоятельный пример
<?php
declare(strict_types=1);

$left = new ArrayIterator(['A']);
$right = new ArrayIterator([10, 20]);
$rows = new MultipleIterator();
$rows->attachIterator($left);
$rows->attachIterator($right);
echo 'count: ', $rows->countIterators(), "\n";
echo 'contains left: ', $rows->containsIterator($left) ? 'yes' : 'no', "\n";
$rows->setFlags(MultipleIterator::MIT_NEED_ANY | MultipleIterator::MIT_KEYS_NUMERIC);
echo 'need-any: ', (($rows->getFlags() & MultipleIterator::MIT_NEED_ALL) === MultipleIterator::MIT_NEED_ANY) ? 'yes' : 'no', "\n";
foreach ($rows as $row) { echo json_encode($row), "\n"; }
$rows->detachIterator($left);
echo 'after detach: ', $rows->countIterators(), "\n";
Ожидаемый результат
count: 2
contains left: yes
need-any: yes
["A",10]
[null,20]
after detach: 1

MIT_NEED_ANY разрешил второй ряд; отсутствующее значение стало null. Эта константа равна нулевому варианту битовой группы, поэтому режим проверяется сравнением замаскированной группы, а не обычным truthy-тестом. containsIterator() проверил идентичность объекта. detachIterator() отключил именно $left, и countIterators() уменьшился до одного.

Скачать самостоятельный пример с fixtures, результатом и README

Две колонки уже упорядочены одинаково. Нужно читать пару значений на каждом шаге без ручного управления двумя курсорами.

Собрать товар и остаток по одной позицииСамостоятельный пример
<?php
declare(strict_types=1);

$names = new ArrayIterator(['brush', 'paint']);
$qty = new ArrayIterator([2, 0]);
$rows = new MultipleIterator(MultipleIterator::MIT_NEED_ALL | MultipleIterator::MIT_KEYS_ASSOC);
$rows->attachIterator($names, 'name');
$rows->attachIterator($qty, 'qty');
foreach ($rows as $keys => $row) {
    echo $keys['name'], ':', $row['name'], '=', $row['qty'], "\n";
}
Ожидаемый результат
0:brush=2
1:paint=0

attachIterator() закрепил имена name и qty. current() сформировал ассоциативную пару, key() — ассоциативную пару исходных ключей. MIT_NEED_ALL потребовал наличие обеих колонок.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

MultipleIterator::setFlags

(PHP 5 >= 5.3.0, PHP 7, PHP 8) MultipleIterator::setFlags — Sets flags

Description

public function MultipleIterator::setFlags(int $flags): void

Sets flags.

WarningThis function is currently not documented; only its argument list is available.

Parameters

flags

The flags to set, according to the Flag Constants

Return Values

No value is returned.

See Also

Flag Constants

MultipleIterator::__construct() - Constructs a new MultipleIterator

MultipleIterator::getFlags() - Gets the flag information

Связанные карточки: AppendIterator::append, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

MultipleIterator::validMultipleIterator::valid: проверить, указывает ли курсор на существующий элемент

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function MultipleIterator::valid(): bool

MultipleIterator::valid нужен, чтобы проверить, указывает ли курсор на существующий элемент. В этой задаче MultipleIterator помогает синхронно читать несколько итераторов по одной позиции, например товары и цены. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function MultipleIterator::valid(): bool
Результатbool: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияfalse означает отсутствие текущего элемента, а не ошибку бизнес-данных. Ошибки источника могут возникнуть отдельно.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Этот пример раскрывает общий Iterator-протокол для двух синхронных источников.

Пройти составной итератор вручнуюСамостоятельный пример
<?php
declare(strict_types=1);

$rows = new MultipleIterator();
$rows->attachIterator(new ArrayIterator(['x', 'y']));
$rows->attachIterator(new ArrayIterator([1, 2]));
$rows->rewind();
while ($rows->valid()) {
    echo json_encode($rows->key()), '=', json_encode($rows->current()), "\n";
    $rows->next();
}
$rows->rewind();
echo 'again: ', json_encode($rows->current()), "\n";
Ожидаемый результат
[0,0]=["x",1]
[1,1]=["y",2]
again: ["x",1]

rewind()/next()/valid() управляли обоими внутренними курсорами. key() и current() вернули составные массивы. Повторный rewind() сработал, потому что оба ArrayIterator повторяемы.

Скачать самостоятельный пример с fixtures, результатом и README

Источники имеют разную длину. Для отчёта допустима строка с null после окончания короткой колонки.

Проверить, перенастроить и отключить источникСамостоятельный пример
<?php
declare(strict_types=1);

$left = new ArrayIterator(['A']);
$right = new ArrayIterator([10, 20]);
$rows = new MultipleIterator();
$rows->attachIterator($left);
$rows->attachIterator($right);
echo 'count: ', $rows->countIterators(), "\n";
echo 'contains left: ', $rows->containsIterator($left) ? 'yes' : 'no', "\n";
$rows->setFlags(MultipleIterator::MIT_NEED_ANY | MultipleIterator::MIT_KEYS_NUMERIC);
echo 'need-any: ', (($rows->getFlags() & MultipleIterator::MIT_NEED_ALL) === MultipleIterator::MIT_NEED_ANY) ? 'yes' : 'no', "\n";
foreach ($rows as $row) { echo json_encode($row), "\n"; }
$rows->detachIterator($left);
echo 'after detach: ', $rows->countIterators(), "\n";
Ожидаемый результат
count: 2
contains left: yes
need-any: yes
["A",10]
[null,20]
after detach: 1

MIT_NEED_ANY разрешил второй ряд; отсутствующее значение стало null. Эта константа равна нулевому варианту битовой группы, поэтому режим проверяется сравнением замаскированной группы, а не обычным truthy-тестом. containsIterator() проверил идентичность объекта. detachIterator() отключил именно $left, и countIterators() уменьшился до одного.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

MultipleIterator::valid

(PHP 5 >= 5.3.0, PHP 7, PHP 8) MultipleIterator::valid — Checks the validity of sub iterators

Description

public function MultipleIterator::valid(): bool

Checks the validity of sub iterators.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

Returns true if one or all sub iterators are valid depending on flags, otherwise false

See Also

MultipleIterator::__construct() - Constructs a new MultipleIterator

Связанные карточки: AppendIterator::append, LimitIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

NoRewindIterator::__constructNoRewindIterator::__construct: создать и настроить объект для дальнейшего обхода

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function NoRewindIterator::__construct(Iterator $iterator)

NoRewindIterator::__construct нужен, чтобы создать и настроить объект для дальнейшего обхода. В этой задаче NoRewindIterator помогает не позволить второму foreach вернуть одноразовый поток к началу. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
iteratorИсходный Iterator или Traversable указанного сигнатурой типа. Объект не копируется: декоратор читает тот же курсор.
Часть контрактаЧто важно
Сигнатураpublic function NoRewindIterator::__construct(Iterator $iterator)
РезультатКонструктор не возвращает прикладное значение; выражение new создаёт объект, который затем сохраняется в переменной.
Ошибки и особые значенияНеподходящий тип аргумента приводит к TypeError; несовместимые флаги, маска или путь имеют отдельные ValueError/RuntimeException либо файловые предупреждения согласно полному контракту.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Первый обработчик остановился на B. Второй foreach не должен незаметно вернуться к A.

Передать остаток одноразового потока второму обработчикуСамостоятельный пример
<?php
declare(strict_types=1);

$stream = new NoRewindIterator(new ArrayIterator(['A', 'B', 'C']));
foreach ($stream as $value) {
    echo 'first: ', $value, "\n";
    if ($value === 'B') { break; }
}
foreach ($stream as $value) {
    echo 'second: ', $value, "\n";
}
Ожидаемый результат
first: A
first: B
second: B
second: C

После break курсор всё ещё указывал на B. Второй foreach вызвал rewind(), но NoRewindIterator его проигнорировал, поэтому B был прочитан повторно, затем next() перевёл курсор к C. Класс защищает от перемотки, но не от повторного чтения current().

Скачать самостоятельный пример с fixtures, результатом и README

Явный протокол показывает, что rewind() после продвижения ничего не меняет.

Управлять оставшимся курсором явноСамостоятельный пример
<?php
declare(strict_types=1);

$stream = new NoRewindIterator(new ArrayIterator(['header', 'body']));
$stream->rewind();
echo $stream->key(), ':', $stream->current(), "\n";
$stream->next();
$stream->rewind();
echo $stream->key(), ':', $stream->current(), "\n";
$stream->next();
echo 'valid: ', $stream->valid() ? 'yes' : 'no', "\n";
Ожидаемый результат
0:header
1:body
valid: no

Первый rewind() позволил начать с header. После next() курсор был на body; второй rewind() сохранил эту позицию. Ещё один next() закончил источник, valid() вернул false.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

NoRewindIterator::__construct

(PHP 5 >= 5.1.0, PHP 7, PHP 8) NoRewindIterator::__construct — Construct a NoRewindIterator

Description

public function NoRewindIterator::__construct(Iterator $iterator)

Constructs a NoRewindIterator.

Parameters

iterator

The iterator being used.

See Also

NoRewindIterator::valid() - Validates the iterator

Связанные карточки: IteratorIterator::__construct, CachingIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

NoRewindIterator::currentNoRewindIterator::current: получить текущее значение без продвижения курсора

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function NoRewindIterator::current(): mixed

NoRewindIterator::current нужен, чтобы получить текущее значение без продвижения курсора. В этой задаче NoRewindIterator помогает не позволить второму foreach вернуть одноразовый поток к началу. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function NoRewindIterator::current(): mixed
Результатmixed: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияСначала вызывайте valid(). На недействительном курсоре особое значение зависит от класса и не должно смешиваться с настоящим null.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Первый обработчик остановился на B. Второй foreach не должен незаметно вернуться к A.

Передать остаток одноразового потока второму обработчикуСамостоятельный пример
<?php
declare(strict_types=1);

$stream = new NoRewindIterator(new ArrayIterator(['A', 'B', 'C']));
foreach ($stream as $value) {
    echo 'first: ', $value, "\n";
    if ($value === 'B') { break; }
}
foreach ($stream as $value) {
    echo 'second: ', $value, "\n";
}
Ожидаемый результат
first: A
first: B
second: B
second: C

После break курсор всё ещё указывал на B. Второй foreach вызвал rewind(), но NoRewindIterator его проигнорировал, поэтому B был прочитан повторно, затем next() перевёл курсор к C. Класс защищает от перемотки, но не от повторного чтения current().

Скачать самостоятельный пример с fixtures, результатом и README

Явный протокол показывает, что rewind() после продвижения ничего не меняет.

Управлять оставшимся курсором явноСамостоятельный пример
<?php
declare(strict_types=1);

$stream = new NoRewindIterator(new ArrayIterator(['header', 'body']));
$stream->rewind();
echo $stream->key(), ':', $stream->current(), "\n";
$stream->next();
$stream->rewind();
echo $stream->key(), ':', $stream->current(), "\n";
$stream->next();
echo 'valid: ', $stream->valid() ? 'yes' : 'no', "\n";
Ожидаемый результат
0:header
1:body
valid: no

Первый rewind() позволил начать с header. После next() курсор был на body; второй rewind() сохранил эту позицию. Ещё один next() закончил источник, valid() вернул false.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

NoRewindIterator::current

(PHP 5 >= 5.1.0, PHP 7, PHP 8) NoRewindIterator::current — Get the current value

Description

public function NoRewindIterator::current(): mixed

Gets the current value.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

The current value.

See Also

NoRewindIterator::key() - Get the current key

Связанные карточки: IteratorIterator::__construct, CachingIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

NoRewindIterator::keyNoRewindIterator::key: получить ключ или позицию текущего элемента

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function NoRewindIterator::key(): mixed

NoRewindIterator::key нужен, чтобы получить ключ или позицию текущего элемента. В этой задаче NoRewindIterator помогает не позволить второму foreach вернуть одноразовый поток к началу. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function NoRewindIterator::key(): mixed
Результатmixed: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияСначала вызывайте valid(). Ключ может быть int, string или составным массивом и не обязан быть бизнес-идентификатором.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Первый обработчик остановился на B. Второй foreach не должен незаметно вернуться к A.

Передать остаток одноразового потока второму обработчикуСамостоятельный пример
<?php
declare(strict_types=1);

$stream = new NoRewindIterator(new ArrayIterator(['A', 'B', 'C']));
foreach ($stream as $value) {
    echo 'first: ', $value, "\n";
    if ($value === 'B') { break; }
}
foreach ($stream as $value) {
    echo 'second: ', $value, "\n";
}
Ожидаемый результат
first: A
first: B
second: B
second: C

После break курсор всё ещё указывал на B. Второй foreach вызвал rewind(), но NoRewindIterator его проигнорировал, поэтому B был прочитан повторно, затем next() перевёл курсор к C. Класс защищает от перемотки, но не от повторного чтения current().

Скачать самостоятельный пример с fixtures, результатом и README

Явный протокол показывает, что rewind() после продвижения ничего не меняет.

Управлять оставшимся курсором явноСамостоятельный пример
<?php
declare(strict_types=1);

$stream = new NoRewindIterator(new ArrayIterator(['header', 'body']));
$stream->rewind();
echo $stream->key(), ':', $stream->current(), "\n";
$stream->next();
$stream->rewind();
echo $stream->key(), ':', $stream->current(), "\n";
$stream->next();
echo 'valid: ', $stream->valid() ? 'yes' : 'no', "\n";
Ожидаемый результат
0:header
1:body
valid: no

Первый rewind() позволил начать с header. После next() курсор был на body; второй rewind() сохранил эту позицию. Ещё один next() закончил источник, valid() вернул false.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

NoRewindIterator::key

(PHP 5 >= 5.1.0, PHP 7, PHP 8) NoRewindIterator::key — Get the current key

Description

public function NoRewindIterator::key(): mixed

Gets the current key.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

The current key.

See Also

NoRewindIterator::next() - Forward to the next element

Связанные карточки: IteratorIterator::__construct, CachingIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

NoRewindIterator::nextNoRewindIterator::next: перевести курсор к следующему элементу

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function NoRewindIterator::next(): void

NoRewindIterator::next нужен, чтобы перевести курсор к следующему элементу. В этой задаче NoRewindIterator помогает не позволить второму foreach вернуть одноразовый поток к началу. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function NoRewindIterator::next(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияПродвижение одноразового источника нельзя отменить. Исключение из вложенного источника передаётся вызывающему коду.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Первый обработчик остановился на B. Второй foreach не должен незаметно вернуться к A.

Передать остаток одноразового потока второму обработчикуСамостоятельный пример
<?php
declare(strict_types=1);

$stream = new NoRewindIterator(new ArrayIterator(['A', 'B', 'C']));
foreach ($stream as $value) {
    echo 'first: ', $value, "\n";
    if ($value === 'B') { break; }
}
foreach ($stream as $value) {
    echo 'second: ', $value, "\n";
}
Ожидаемый результат
first: A
first: B
second: B
second: C

После break курсор всё ещё указывал на B. Второй foreach вызвал rewind(), но NoRewindIterator его проигнорировал, поэтому B был прочитан повторно, затем next() перевёл курсор к C. Класс защищает от перемотки, но не от повторного чтения current().

Скачать самостоятельный пример с fixtures, результатом и README

Явный протокол показывает, что rewind() после продвижения ничего не меняет.

Управлять оставшимся курсором явноСамостоятельный пример
<?php
declare(strict_types=1);

$stream = new NoRewindIterator(new ArrayIterator(['header', 'body']));
$stream->rewind();
echo $stream->key(), ':', $stream->current(), "\n";
$stream->next();
$stream->rewind();
echo $stream->key(), ':', $stream->current(), "\n";
$stream->next();
echo 'valid: ', $stream->valid() ? 'yes' : 'no', "\n";
Ожидаемый результат
0:header
1:body
valid: no

Первый rewind() позволил начать с header. После next() курсор был на body; второй rewind() сохранил эту позицию. Ещё один next() закончил источник, valid() вернул false.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

NoRewindIterator::next

(PHP 5 >= 5.1.0, PHP 7, PHP 8) NoRewindIterator::next — Forward to the next element

Description

public function NoRewindIterator::next(): void

Forwards to the next element.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

No value is returned.

See Also

NoRewindIterator::rewind() - Prevents the rewind operation on the inner iterator

Связанные карточки: IteratorIterator::__construct, CachingIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

NoRewindIterator::rewindNoRewindIterator::rewind: попытаться установить курсор на первый элемент

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function NoRewindIterator::rewind(): void

NoRewindIterator::rewind нужен, чтобы попытаться установить курсор на первый элемент. В этой задаче NoRewindIterator помогает не позволить второму foreach вернуть одноразовый поток к началу. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function NoRewindIterator::rewind(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияНе каждый Traversable можно повторить. NoRewindIterator намеренно игнорирует повторную перемотку, а Generator после завершения может выбросить исключение.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Первый обработчик остановился на B. Второй foreach не должен незаметно вернуться к A.

Передать остаток одноразового потока второму обработчикуСамостоятельный пример
<?php
declare(strict_types=1);

$stream = new NoRewindIterator(new ArrayIterator(['A', 'B', 'C']));
foreach ($stream as $value) {
    echo 'first: ', $value, "\n";
    if ($value === 'B') { break; }
}
foreach ($stream as $value) {
    echo 'second: ', $value, "\n";
}
Ожидаемый результат
first: A
first: B
second: B
second: C

После break курсор всё ещё указывал на B. Второй foreach вызвал rewind(), но NoRewindIterator его проигнорировал, поэтому B был прочитан повторно, затем next() перевёл курсор к C. Класс защищает от перемотки, но не от повторного чтения current().

Скачать самостоятельный пример с fixtures, результатом и README

Явный протокол показывает, что rewind() после продвижения ничего не меняет.

Управлять оставшимся курсором явноСамостоятельный пример
<?php
declare(strict_types=1);

$stream = new NoRewindIterator(new ArrayIterator(['header', 'body']));
$stream->rewind();
echo $stream->key(), ':', $stream->current(), "\n";
$stream->next();
$stream->rewind();
echo $stream->key(), ':', $stream->current(), "\n";
$stream->next();
echo 'valid: ', $stream->valid() ? 'yes' : 'no', "\n";
Ожидаемый результат
0:header
1:body
valid: no

Первый rewind() позволил начать с header. После next() курсор был на body; второй rewind() сохранил эту позицию. Ещё один next() закончил источник, valid() вернул false.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

NoRewindIterator::rewind

(PHP 5 >= 5.1.0, PHP 7, PHP 8) NoRewindIterator::rewind — Prevents the rewind operation on the inner iterator

Description

public function NoRewindIterator::rewind(): void

Prevents the rewind operation on the inner iterator.

Parameters

This function has no parameters.

Return Values

No value is returned.

Связанные карточки: IteratorIterator::__construct, CachingIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

NoRewindIterator::validNoRewindIterator::valid: проверить, указывает ли курсор на существующий элемент

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function NoRewindIterator::valid(): bool

NoRewindIterator::valid нужен, чтобы проверить, указывает ли курсор на существующий элемент. В этой задаче NoRewindIterator помогает не позволить второму foreach вернуть одноразовый поток к началу. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function NoRewindIterator::valid(): bool
Результатbool: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияfalse означает отсутствие текущего элемента, а не ошибку бизнес-данных. Ошибки источника могут возникнуть отдельно.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Первый обработчик остановился на B. Второй foreach не должен незаметно вернуться к A.

Передать остаток одноразового потока второму обработчикуСамостоятельный пример
<?php
declare(strict_types=1);

$stream = new NoRewindIterator(new ArrayIterator(['A', 'B', 'C']));
foreach ($stream as $value) {
    echo 'first: ', $value, "\n";
    if ($value === 'B') { break; }
}
foreach ($stream as $value) {
    echo 'second: ', $value, "\n";
}
Ожидаемый результат
first: A
first: B
second: B
second: C

После break курсор всё ещё указывал на B. Второй foreach вызвал rewind(), но NoRewindIterator его проигнорировал, поэтому B был прочитан повторно, затем next() перевёл курсор к C. Класс защищает от перемотки, но не от повторного чтения current().

Скачать самостоятельный пример с fixtures, результатом и README

Явный протокол показывает, что rewind() после продвижения ничего не меняет.

Управлять оставшимся курсором явноСамостоятельный пример
<?php
declare(strict_types=1);

$stream = new NoRewindIterator(new ArrayIterator(['header', 'body']));
$stream->rewind();
echo $stream->key(), ':', $stream->current(), "\n";
$stream->next();
$stream->rewind();
echo $stream->key(), ':', $stream->current(), "\n";
$stream->next();
echo 'valid: ', $stream->valid() ? 'yes' : 'no', "\n";
Ожидаемый результат
0:header
1:body
valid: no

Первый rewind() позволил начать с header. После next() курсор был на body; второй rewind() сохранил эту позицию. Ещё один next() закончил источник, valid() вернул false.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

NoRewindIterator::valid

(PHP 5 >= 5.1.0, PHP 7, PHP 8) NoRewindIterator::valid — Validates the iterator

Description

public function NoRewindIterator::valid(): bool

Checks whether the iterator is valid.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

Returns true on success or false on failure.

See Also

NoRewindIterator::getInnerIterator()

Связанные карточки: IteratorIterator::__construct, CachingIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

CachingIterator::__constructСоздать декоратор с look-ahead, строковым режимом и необязательным полным кешем

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function CachingIterator::__construct(Iterator $iterator, int $flags = CachingIterator::CALL_TOSTRING)

__construct() оборачивает уже существующий Iterator. Второй аргумент — полная битовая маска: по умолчанию действует CALL_TOSTRING; FULL_CACHE отдельно включает накопление пройденных пар ключ/значение.

ПараметрЧто означает в задаче
iteratorГотовый Iterator; CachingIterator не копирует его и двигает тот же курсор.
flagsБитовая маска CALL_TOSTRING/TOSTRING_USE_* и независимо FULL_CACHE; оператор | объединяет флаги.
Часть контрактаЧто важно
Сигнатураpublic function CachingIterator::__construct(Iterator $iterator, int $flags = CachingIterator::CALL_TOSTRING)
РезультатКонструктор не возвращает прикладное значение; new создаёт объект, который использует тот же внутренний курсор.
Ошибки и особые значенияНе-Iterator вызывает TypeError. Недопустимое сочетание строковых флагов вызывает InvalidArgumentException. Массив как значение при CALL_TOSTRING даёт предупреждение при продвижении.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Интерфейс показывает цепочку этапов. После последнего этапа стрелка не нужна, но обычный foreach сам по себе не сообщает, есть ли сосед справа.

Поставить разделитель только между этапами заказаСамостоятельный пример
<?php
declare(strict_types=1);

$steps = new CachingIterator(
    new ArrayIterator(['received', 'paid', 'shipped'])
);

foreach ($steps as $step) {
    echo $steps->key(), ':', (string) $steps;
    echo $steps->hasNext() ? ' -> ' : "\n";
}
Ожидаемый результат
0:received -> 1:paid -> 2:shipped

foreach вызвал rewind(), valid(), current() и next(). На каждой позиции hasNext() заглянул на один шаг вперёд, не потребляя соседний элемент. Поэтому разделитель появился только между значениями. __toString() безопасен здесь, потому что значения — строки и действует стандартный CALL_TOSTRING.

Скачать самостоятельный пример с fixtures, результатом и README

Импорт заказов читается постепенно. Для диагностики нужно посмотреть только реально пройденные записи и временно пометить одну из них, не изменяя исходный ArrayIterator.

Увидеть только уже прочитанную часть потокаСамостоятельный пример
<?php
declare(strict_types=1);

$orders = new CachingIterator(
    new ArrayIterator([
        'order-101' => 'new',
        'order-102' => 'paid',
        'order-103' => 'sent',
    ]),
    CachingIterator::FULL_CACHE
);

$orders->rewind();
echo 'key=', $orders->key(), '; full-cache=',
    ($orders->getFlags() & CachingIterator::FULL_CACHE) !== 0 ? 'yes' : 'no',
    "\n";
echo json_encode($orders->getCache()), "\n";

$orders->next();
echo json_encode($orders->getCache()), "\n";
echo 'count=', count($orders),
    '; exists=', isset($orders['order-102']) ? 'yes' : 'no',
    '; value=', $orders['order-102'], "\n";

$orders['review'] = 'manual';
echo json_encode($orders->getCache()), "\n";
unset($orders['review']);
echo json_encode($orders->getCache()), "\n";
Ожидаемый результат
key=order-101; full-cache=yes
{"order-101":"new"}
{"order-101":"new","order-102":"paid"}
count=2; exists=yes; value=paid
{"order-101":"new","order-102":"paid","review":"manual"}
{"order-101":"new","order-102":"paid"}

FULL_CACHE добавил текущую запись при rewind() и следующую при next(). getCache(), count() и ArrayAccess работают с накопленным кешем: непрочитанный order-103 ещё отсутствует. Запись review появилась только в кеше и была удалена; это не команда изменить исходный источник.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

CachingIterator::__construct

(PHP 5, PHP 7, PHP 8) CachingIterator::__construct — Construct a new CachingIterator object for the iterator

Description

public function CachingIterator::__construct(Iterator $iterator, int $flags = CachingIterator::CALL_TOSTRING)

WarningThis function is currently not documented; only its argument list is available.

Parameters

iterator

Iterator to cache

flags

Bitmask of flags.

Связанные карточки: CachingIterator::getFlags, CachingIterator::getCache.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

CachingIterator::countПосчитать накопленные элементы полного кеша, а не весь источник

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function CachingIterator::count(): int

count() относится к уже наполненному FULL_CACHE. После двух позиций он возвращает 2, даже если во внутреннем Iterator есть третья непрочитанная запись.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function CachingIterator::count(): int
Результатint: число элементов именно в массиве кеша на момент вызова.
Ошибки и особые значенияБез FULL_CACHE метод выбрасывает BadMethodCallException; это не означает «ноль элементов».
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Импорт заказов читается постепенно. Для диагностики нужно посмотреть только реально пройденные записи и временно пометить одну из них, не изменяя исходный ArrayIterator.

Увидеть только уже прочитанную часть потокаСамостоятельный пример
<?php
declare(strict_types=1);

$orders = new CachingIterator(
    new ArrayIterator([
        'order-101' => 'new',
        'order-102' => 'paid',
        'order-103' => 'sent',
    ]),
    CachingIterator::FULL_CACHE
);

$orders->rewind();
echo 'key=', $orders->key(), '; full-cache=',
    ($orders->getFlags() & CachingIterator::FULL_CACHE) !== 0 ? 'yes' : 'no',
    "\n";
echo json_encode($orders->getCache()), "\n";

$orders->next();
echo json_encode($orders->getCache()), "\n";
echo 'count=', count($orders),
    '; exists=', isset($orders['order-102']) ? 'yes' : 'no',
    '; value=', $orders['order-102'], "\n";

$orders['review'] = 'manual';
echo json_encode($orders->getCache()), "\n";
unset($orders['review']);
echo json_encode($orders->getCache()), "\n";
Ожидаемый результат
key=order-101; full-cache=yes
{"order-101":"new"}
{"order-101":"new","order-102":"paid"}
count=2; exists=yes; value=paid
{"order-101":"new","order-102":"paid","review":"manual"}
{"order-101":"new","order-102":"paid"}

FULL_CACHE добавил текущую запись при rewind() и следующую при next(). getCache(), count() и ArrayAccess работают с накопленным кешем: непрочитанный order-103 ещё отсутствует. Запись review появилась только в кеше и была удалена; это не команда изменить исходный источник.

Скачать самостоятельный пример с fixtures, результатом и README

Разработчик создал CachingIterator без полного кеша, а позднее попытался читать его как массив. Пример делает отказ видимым и затем включает нужный режим явно.

Распознать операции, которым обязательно нужен FULL_CACHEСамостоятельный пример
<?php
declare(strict_types=1);

$plain = new CachingIterator(new ArrayIterator(['A']), 0);
$plain->rewind();

$operations = [
    'getCache' => fn() => $plain->getCache(),
    'count' => fn() => count($plain),
    'offsetExists' => fn() => isset($plain['missing']),
    'offsetGet' => fn() => $plain['missing'],
];

foreach ($operations as $name => $operation) {
    try {
        $operation();
        echo "$name: no error\n";
    } catch (BadMethodCallException) {
        echo "$name: FULL_CACHE required\n";
    }
}

$plain->setFlags(CachingIterator::FULL_CACHE);
$plain->rewind();
echo 'after setFlags: ', count($plain), "\n";
Ожидаемый результат
getCache: FULL_CACHE required
count: FULL_CACHE required
offsetExists: FULL_CACHE required
offsetGet: FULL_CACHE required
after setFlags: 1

Флаг 0 разрешает обычный обход, но getCache(), Countable и ArrayAccess выбрасывают BadMethodCallException. После setFlags(FULL_CACHE) и нового rewind() текущий элемент попал в кеш, поэтому count() вернул 1. Не скрывайте такую ошибку оператором @.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

CachingIterator::count

(PHP 5 >= 5.2.2, PHP 7, PHP 8) CachingIterator::count — The number of elements in the iterator

Description

public function CachingIterator::count(): int

WarningThis function is currently not documented; only its argument list is available.

May return the number of elements in the iterator.

Parameters

This function has no parameters.

Return Values

The count of the elements iterated over.

Связанные карточки: CachingIterator::getCache, CachingIterator::next.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

CachingIterator::currentПолучить текущее исходное значение без продвижения

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function CachingIterator::current(): mixed

current() возвращает значение внутреннего Iterator на принятой позиции. __toString() может показывать другое представление, но current() остаётся исходным значением.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function CachingIterator::current(): mixed
Результатmixed: текущая строка, число, массив или объект источника; тип не меняется из-за строкового флага.
Ошибки и особые значенияНа недействительном курсоре результат нельзя считать бизнес-данными; сначала проверяйте valid(). Ошибка внутреннего Iterator передаётся наружу.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Интерфейс показывает цепочку этапов. После последнего этапа стрелка не нужна, но обычный foreach сам по себе не сообщает, есть ли сосед справа.

Поставить разделитель только между этапами заказаСамостоятельный пример
<?php
declare(strict_types=1);

$steps = new CachingIterator(
    new ArrayIterator(['received', 'paid', 'shipped'])
);

foreach ($steps as $step) {
    echo $steps->key(), ':', (string) $steps;
    echo $steps->hasNext() ? ' -> ' : "\n";
}
Ожидаемый результат
0:received -> 1:paid -> 2:shipped

foreach вызвал rewind(), valid(), current() и next(). На каждой позиции hasNext() заглянул на один шаг вперёд, не потребляя соседний элемент. Поэтому разделитель появился только между значениями. __toString() безопасен здесь, потому что значения — строки и действует стандартный CALL_TOSTRING.

Скачать самостоятельный пример с fixtures, результатом и README

Один диагностический экран должен сначала показывать артикул, а затем название товара. Источник и курсор остаются прежними; меняется только правило __toString().

Переключить строковое представление с ключа на значениеСамостоятельный пример
<?php
declare(strict_types=1);

function cachingFlagNames(int $flags): string
{
    $names = [];
    foreach (['TOSTRING_USE_KEY', 'TOSTRING_USE_CURRENT', 'FULL_CACHE'] as $name) {
        $value = constant("CachingIterator::$name");
        if (($flags & $value) === $value) {
            $names[] = $name;
        }
    }
    return implode('|', $names);
}

$items = new CachingIterator(
    new ArrayIterator(['SKU-1' => 'Brush', 'SKU-2' => 'Paint']),
    CachingIterator::FULL_CACHE | CachingIterator::TOSTRING_USE_KEY
);

$items->rewind();
echo cachingFlagNames($items->getFlags()), ':', (string) $items,
    '; next=', $items->hasNext() ? 'yes' : 'no', "\n";

$items->setFlags(
    CachingIterator::FULL_CACHE | CachingIterator::TOSTRING_USE_CURRENT
);
echo cachingFlagNames($items->getFlags()), ':', (string) $items, "\n";

$items->next();
echo cachingFlagNames($items->getFlags()), ':', (string) $items,
    '; next=', $items->hasNext() ? 'yes' : 'no', "\n";
Ожидаемый результат
TOSTRING_USE_KEY|FULL_CACHE:SKU-1; next=yes
TOSTRING_USE_CURRENT|FULL_CACHE:Brush
TOSTRING_USE_CURRENT|FULL_CACHE:Paint; next=no

getFlags() вернул битовую маску. Оператор & проверил отдельные биты, а | объединил режимы. setFlags() заменил всю маску, поэтому FULL_CACHE включён повторно вместе с новым TOSTRING_USE_CURRENT. hasNext() подтвердил сосед только на первой позиции.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

CachingIterator::current

(PHP 5, PHP 7, PHP 8) CachingIterator::current — Return the current element

Description

public function CachingIterator::current(): mixed

WarningThis function is currently not documented; only its argument list is available.

May return the current element in the iteration.

Parameters

This function has no parameters.

Return Values

Mixed

See Also

Iterator::current() - Return the current element

Связанные карточки: CachingIterator::__toString, CachingIterator::valid.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

CachingIterator::getCacheПолучить снимок уже накопленных пар ключ/значение

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function CachingIterator::getCache(): array

getCache() возвращает обычный массив FULL_CACHE. При rewind() там появляется первая позиция, при next() — следующая; ещё не прочитанные элементы не материализуются.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function CachingIterator::getCache(): array
Результатarray: текущий снимок кеша, включая записи, добавленные через offsetSet().
Ошибки и особые значенияБез FULL_CACHE выбрасывается BadMethodCallException. Исключения источника во время наполнения не превращаются в неполный «успешный» кеш.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Импорт заказов читается постепенно. Для диагностики нужно посмотреть только реально пройденные записи и временно пометить одну из них, не изменяя исходный ArrayIterator.

Увидеть только уже прочитанную часть потокаСамостоятельный пример
<?php
declare(strict_types=1);

$orders = new CachingIterator(
    new ArrayIterator([
        'order-101' => 'new',
        'order-102' => 'paid',
        'order-103' => 'sent',
    ]),
    CachingIterator::FULL_CACHE
);

$orders->rewind();
echo 'key=', $orders->key(), '; full-cache=',
    ($orders->getFlags() & CachingIterator::FULL_CACHE) !== 0 ? 'yes' : 'no',
    "\n";
echo json_encode($orders->getCache()), "\n";

$orders->next();
echo json_encode($orders->getCache()), "\n";
echo 'count=', count($orders),
    '; exists=', isset($orders['order-102']) ? 'yes' : 'no',
    '; value=', $orders['order-102'], "\n";

$orders['review'] = 'manual';
echo json_encode($orders->getCache()), "\n";
unset($orders['review']);
echo json_encode($orders->getCache()), "\n";
Ожидаемый результат
key=order-101; full-cache=yes
{"order-101":"new"}
{"order-101":"new","order-102":"paid"}
count=2; exists=yes; value=paid
{"order-101":"new","order-102":"paid","review":"manual"}
{"order-101":"new","order-102":"paid"}

FULL_CACHE добавил текущую запись при rewind() и следующую при next(). getCache(), count() и ArrayAccess работают с накопленным кешем: непрочитанный order-103 ещё отсутствует. Запись review появилась только в кеше и была удалена; это не команда изменить исходный источник.

Скачать самостоятельный пример с fixtures, результатом и README

Разработчик создал CachingIterator без полного кеша, а позднее попытался читать его как массив. Пример делает отказ видимым и затем включает нужный режим явно.

Распознать операции, которым обязательно нужен FULL_CACHEСамостоятельный пример
<?php
declare(strict_types=1);

$plain = new CachingIterator(new ArrayIterator(['A']), 0);
$plain->rewind();

$operations = [
    'getCache' => fn() => $plain->getCache(),
    'count' => fn() => count($plain),
    'offsetExists' => fn() => isset($plain['missing']),
    'offsetGet' => fn() => $plain['missing'],
];

foreach ($operations as $name => $operation) {
    try {
        $operation();
        echo "$name: no error\n";
    } catch (BadMethodCallException) {
        echo "$name: FULL_CACHE required\n";
    }
}

$plain->setFlags(CachingIterator::FULL_CACHE);
$plain->rewind();
echo 'after setFlags: ', count($plain), "\n";
Ожидаемый результат
getCache: FULL_CACHE required
count: FULL_CACHE required
offsetExists: FULL_CACHE required
offsetGet: FULL_CACHE required
after setFlags: 1

Флаг 0 разрешает обычный обход, но getCache(), Countable и ArrayAccess выбрасывают BadMethodCallException. После setFlags(FULL_CACHE) и нового rewind() текущий элемент попал в кеш, поэтому count() вернул 1. Не скрывайте такую ошибку оператором @.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

CachingIterator::getCache

(PHP 5 >= 5.2.0, PHP 7, PHP 8) CachingIterator::getCache — Retrieve the contents of the cache

Description

public function CachingIterator::getCache(): array

Retrieve the contents of the cache.

Note:

The CachingIterator::FULL_CACHE flag must be being used.

Parameters

This function has no parameters.

Return Values

An array containing the cache items.

Errors/Exceptions

Throws a BadMethodCallException when the CachingIterator::FULL_CACHE flag is not being used.

Связанные карточки: CachingIterator::count, CachingIterator::offsetGet.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

CachingIterator::getFlagsПрочитать действующую битовую маску кеша и строкового представления

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function CachingIterator::getFlags(): int

getFlags() возвращает одно целое число, в котором отдельные биты обозначают FULL_CACHE и выбранный TOSTRING-режим. Наличие бита проверяют через ($flags & CONSTANT) !== 0.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function CachingIterator::getFlags(): int
Результатint: действующая маска всех флагов объекта.
Ошибки и особые значенияМетод не проверяет, подходит ли режим вашим данным; CALL_TOSTRING с массивами проявится предупреждением при продвижении.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Импорт заказов читается постепенно. Для диагностики нужно посмотреть только реально пройденные записи и временно пометить одну из них, не изменяя исходный ArrayIterator.

Увидеть только уже прочитанную часть потокаСамостоятельный пример
<?php
declare(strict_types=1);

$orders = new CachingIterator(
    new ArrayIterator([
        'order-101' => 'new',
        'order-102' => 'paid',
        'order-103' => 'sent',
    ]),
    CachingIterator::FULL_CACHE
);

$orders->rewind();
echo 'key=', $orders->key(), '; full-cache=',
    ($orders->getFlags() & CachingIterator::FULL_CACHE) !== 0 ? 'yes' : 'no',
    "\n";
echo json_encode($orders->getCache()), "\n";

$orders->next();
echo json_encode($orders->getCache()), "\n";
echo 'count=', count($orders),
    '; exists=', isset($orders['order-102']) ? 'yes' : 'no',
    '; value=', $orders['order-102'], "\n";

$orders['review'] = 'manual';
echo json_encode($orders->getCache()), "\n";
unset($orders['review']);
echo json_encode($orders->getCache()), "\n";
Ожидаемый результат
key=order-101; full-cache=yes
{"order-101":"new"}
{"order-101":"new","order-102":"paid"}
count=2; exists=yes; value=paid
{"order-101":"new","order-102":"paid","review":"manual"}
{"order-101":"new","order-102":"paid"}

FULL_CACHE добавил текущую запись при rewind() и следующую при next(). getCache(), count() и ArrayAccess работают с накопленным кешем: непрочитанный order-103 ещё отсутствует. Запись review появилась только в кеше и была удалена; это не команда изменить исходный источник.

Скачать самостоятельный пример с fixtures, результатом и README

Один диагностический экран должен сначала показывать артикул, а затем название товара. Источник и курсор остаются прежними; меняется только правило __toString().

Переключить строковое представление с ключа на значениеСамостоятельный пример
<?php
declare(strict_types=1);

function cachingFlagNames(int $flags): string
{
    $names = [];
    foreach (['TOSTRING_USE_KEY', 'TOSTRING_USE_CURRENT', 'FULL_CACHE'] as $name) {
        $value = constant("CachingIterator::$name");
        if (($flags & $value) === $value) {
            $names[] = $name;
        }
    }
    return implode('|', $names);
}

$items = new CachingIterator(
    new ArrayIterator(['SKU-1' => 'Brush', 'SKU-2' => 'Paint']),
    CachingIterator::FULL_CACHE | CachingIterator::TOSTRING_USE_KEY
);

$items->rewind();
echo cachingFlagNames($items->getFlags()), ':', (string) $items,
    '; next=', $items->hasNext() ? 'yes' : 'no', "\n";

$items->setFlags(
    CachingIterator::FULL_CACHE | CachingIterator::TOSTRING_USE_CURRENT
);
echo cachingFlagNames($items->getFlags()), ':', (string) $items, "\n";

$items->next();
echo cachingFlagNames($items->getFlags()), ':', (string) $items,
    '; next=', $items->hasNext() ? 'yes' : 'no', "\n";
Ожидаемый результат
TOSTRING_USE_KEY|FULL_CACHE:SKU-1; next=yes
TOSTRING_USE_CURRENT|FULL_CACHE:Brush
TOSTRING_USE_CURRENT|FULL_CACHE:Paint; next=no

getFlags() вернул битовую маску. Оператор & проверил отдельные биты, а | объединил режимы. setFlags() заменил всю маску, поэтому FULL_CACHE включён повторно вместе с новым TOSTRING_USE_CURRENT. hasNext() подтвердил сосед только на первой позиции.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

CachingIterator::getFlags

(PHP 5 >= 5.2.0, PHP 7, PHP 8) CachingIterator::getFlags — Get flags used

Description

public function CachingIterator::getFlags(): int

WarningThis function is currently not documented; only its argument list is available.

Get the bitmask of the flags used for this CachingIterator instance.

Parameters

This function has no parameters.

Return Values

Description...

Связанные карточки: CachingIterator::setFlags, CachingIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

CachingIterator::hasNextПроверить соседа справа, не отдавая его текущему потребителю

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function CachingIterator::hasNext(): bool

hasNext() отвечает, есть ли у внутреннего Iterator валидный следующий элемент. Он полезен для разделителя, соединительной линии или подписи «продолжение».

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function CachingIterator::hasNext(): bool
Результатbool: true, если после текущей позиции доступен следующий элемент; false на последней позиции.
Ошибки и особые значенияИсключение внутреннего Iterator при заглядывании не скрывается. До rewind() и после конца не предполагайте валидную текущую позицию.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Интерфейс показывает цепочку этапов. После последнего этапа стрелка не нужна, но обычный foreach сам по себе не сообщает, есть ли сосед справа.

Поставить разделитель только между этапами заказаСамостоятельный пример
<?php
declare(strict_types=1);

$steps = new CachingIterator(
    new ArrayIterator(['received', 'paid', 'shipped'])
);

foreach ($steps as $step) {
    echo $steps->key(), ':', (string) $steps;
    echo $steps->hasNext() ? ' -> ' : "\n";
}
Ожидаемый результат
0:received -> 1:paid -> 2:shipped

foreach вызвал rewind(), valid(), current() и next(). На каждой позиции hasNext() заглянул на один шаг вперёд, не потребляя соседний элемент. Поэтому разделитель появился только между значениями. __toString() безопасен здесь, потому что значения — строки и действует стандартный CALL_TOSTRING.

Скачать самостоятельный пример с fixtures, результатом и README

Один диагностический экран должен сначала показывать артикул, а затем название товара. Источник и курсор остаются прежними; меняется только правило __toString().

Переключить строковое представление с ключа на значениеСамостоятельный пример
<?php
declare(strict_types=1);

function cachingFlagNames(int $flags): string
{
    $names = [];
    foreach (['TOSTRING_USE_KEY', 'TOSTRING_USE_CURRENT', 'FULL_CACHE'] as $name) {
        $value = constant("CachingIterator::$name");
        if (($flags & $value) === $value) {
            $names[] = $name;
        }
    }
    return implode('|', $names);
}

$items = new CachingIterator(
    new ArrayIterator(['SKU-1' => 'Brush', 'SKU-2' => 'Paint']),
    CachingIterator::FULL_CACHE | CachingIterator::TOSTRING_USE_KEY
);

$items->rewind();
echo cachingFlagNames($items->getFlags()), ':', (string) $items,
    '; next=', $items->hasNext() ? 'yes' : 'no', "\n";

$items->setFlags(
    CachingIterator::FULL_CACHE | CachingIterator::TOSTRING_USE_CURRENT
);
echo cachingFlagNames($items->getFlags()), ':', (string) $items, "\n";

$items->next();
echo cachingFlagNames($items->getFlags()), ':', (string) $items,
    '; next=', $items->hasNext() ? 'yes' : 'no', "\n";
Ожидаемый результат
TOSTRING_USE_KEY|FULL_CACHE:SKU-1; next=yes
TOSTRING_USE_CURRENT|FULL_CACHE:Brush
TOSTRING_USE_CURRENT|FULL_CACHE:Paint; next=no

getFlags() вернул битовую маску. Оператор & проверил отдельные биты, а | объединил режимы. setFlags() заменил всю маску, поэтому FULL_CACHE включён повторно вместе с новым TOSTRING_USE_CURRENT. hasNext() подтвердил сосед только на первой позиции.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

CachingIterator::hasNext

(PHP 5, PHP 7, PHP 8) CachingIterator::hasNext — Check whether the inner iterator has a valid next element

Description

public function CachingIterator::hasNext(): bool

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

Returns true on success or false on failure.

Связанные карточки: CachingIterator::next, CachingIterator::valid.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

CachingIterator::keyПрочитать исходный ключ текущего элемента

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function CachingIterator::key(): mixed

key() делегирует ключ внутреннему Iterator. В полном кеше тот же ключ используется для накопленной записи, пока вы отдельно не добавите собственный offset.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function CachingIterator::key(): mixed
Результатmixed: текущий ключ источника; в примерах это int-позиция либо строка order-101.
Ошибки и особые значенияНа недействительном курсоре ключ не является надёжным значением. Дублирующиеся ключи при накоплении могут перезаписать прежнее значение кеша согласно поведению массива.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Интерфейс показывает цепочку этапов. После последнего этапа стрелка не нужна, но обычный foreach сам по себе не сообщает, есть ли сосед справа.

Поставить разделитель только между этапами заказаСамостоятельный пример
<?php
declare(strict_types=1);

$steps = new CachingIterator(
    new ArrayIterator(['received', 'paid', 'shipped'])
);

foreach ($steps as $step) {
    echo $steps->key(), ':', (string) $steps;
    echo $steps->hasNext() ? ' -> ' : "\n";
}
Ожидаемый результат
0:received -> 1:paid -> 2:shipped

foreach вызвал rewind(), valid(), current() и next(). На каждой позиции hasNext() заглянул на один шаг вперёд, не потребляя соседний элемент. Поэтому разделитель появился только между значениями. __toString() безопасен здесь, потому что значения — строки и действует стандартный CALL_TOSTRING.

Скачать самостоятельный пример с fixtures, результатом и README

Импорт заказов читается постепенно. Для диагностики нужно посмотреть только реально пройденные записи и временно пометить одну из них, не изменяя исходный ArrayIterator.

Увидеть только уже прочитанную часть потокаСамостоятельный пример
<?php
declare(strict_types=1);

$orders = new CachingIterator(
    new ArrayIterator([
        'order-101' => 'new',
        'order-102' => 'paid',
        'order-103' => 'sent',
    ]),
    CachingIterator::FULL_CACHE
);

$orders->rewind();
echo 'key=', $orders->key(), '; full-cache=',
    ($orders->getFlags() & CachingIterator::FULL_CACHE) !== 0 ? 'yes' : 'no',
    "\n";
echo json_encode($orders->getCache()), "\n";

$orders->next();
echo json_encode($orders->getCache()), "\n";
echo 'count=', count($orders),
    '; exists=', isset($orders['order-102']) ? 'yes' : 'no',
    '; value=', $orders['order-102'], "\n";

$orders['review'] = 'manual';
echo json_encode($orders->getCache()), "\n";
unset($orders['review']);
echo json_encode($orders->getCache()), "\n";
Ожидаемый результат
key=order-101; full-cache=yes
{"order-101":"new"}
{"order-101":"new","order-102":"paid"}
count=2; exists=yes; value=paid
{"order-101":"new","order-102":"paid","review":"manual"}
{"order-101":"new","order-102":"paid"}

FULL_CACHE добавил текущую запись при rewind() и следующую при next(). getCache(), count() и ArrayAccess работают с накопленным кешем: непрочитанный order-103 ещё отсутствует. Запись review появилась только в кеше и была удалена; это не команда изменить исходный источник.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

CachingIterator::key

(PHP 5, PHP 7, PHP 8) CachingIterator::key — Return the key for the current element

Description

public function CachingIterator::key(): scalar

WarningThis function is currently not documented; only its argument list is available.

This method may return a key for the current element.

Parameters

This function has no parameters.

Связанные карточки: CachingIterator::current, CachingIterator::offsetExists.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

CachingIterator::nextПродвинуть внутренний курсор и обновить look-ahead/кеш

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function CachingIterator::next(): void

next() переводит обёрнутый Iterator на следующую позицию. При FULL_CACHE новая текущая пара добавляется в кеш; строковый режим готовит новое значение для __toString().

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function CachingIterator::next(): void
Результатvoid: полезного значения на месте вызова нет; новое состояние читают current(), key(), hasNext() и getCache().
Ошибки и особые значенияОшибка продвижения внутреннего Iterator передаётся наружу. CALL_TOSTRING может выдать предупреждение при непреобразуемом значении.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Импорт заказов читается постепенно. Для диагностики нужно посмотреть только реально пройденные записи и временно пометить одну из них, не изменяя исходный ArrayIterator.

Увидеть только уже прочитанную часть потокаСамостоятельный пример
<?php
declare(strict_types=1);

$orders = new CachingIterator(
    new ArrayIterator([
        'order-101' => 'new',
        'order-102' => 'paid',
        'order-103' => 'sent',
    ]),
    CachingIterator::FULL_CACHE
);

$orders->rewind();
echo 'key=', $orders->key(), '; full-cache=',
    ($orders->getFlags() & CachingIterator::FULL_CACHE) !== 0 ? 'yes' : 'no',
    "\n";
echo json_encode($orders->getCache()), "\n";

$orders->next();
echo json_encode($orders->getCache()), "\n";
echo 'count=', count($orders),
    '; exists=', isset($orders['order-102']) ? 'yes' : 'no',
    '; value=', $orders['order-102'], "\n";

$orders['review'] = 'manual';
echo json_encode($orders->getCache()), "\n";
unset($orders['review']);
echo json_encode($orders->getCache()), "\n";
Ожидаемый результат
key=order-101; full-cache=yes
{"order-101":"new"}
{"order-101":"new","order-102":"paid"}
count=2; exists=yes; value=paid
{"order-101":"new","order-102":"paid","review":"manual"}
{"order-101":"new","order-102":"paid"}

FULL_CACHE добавил текущую запись при rewind() и следующую при next(). getCache(), count() и ArrayAccess работают с накопленным кешем: непрочитанный order-103 ещё отсутствует. Запись review появилась только в кеше и была удалена; это не команда изменить исходный источник.

Скачать самостоятельный пример с fixtures, результатом и README

Один диагностический экран должен сначала показывать артикул, а затем название товара. Источник и курсор остаются прежними; меняется только правило __toString().

Переключить строковое представление с ключа на значениеСамостоятельный пример
<?php
declare(strict_types=1);

function cachingFlagNames(int $flags): string
{
    $names = [];
    foreach (['TOSTRING_USE_KEY', 'TOSTRING_USE_CURRENT', 'FULL_CACHE'] as $name) {
        $value = constant("CachingIterator::$name");
        if (($flags & $value) === $value) {
            $names[] = $name;
        }
    }
    return implode('|', $names);
}

$items = new CachingIterator(
    new ArrayIterator(['SKU-1' => 'Brush', 'SKU-2' => 'Paint']),
    CachingIterator::FULL_CACHE | CachingIterator::TOSTRING_USE_KEY
);

$items->rewind();
echo cachingFlagNames($items->getFlags()), ':', (string) $items,
    '; next=', $items->hasNext() ? 'yes' : 'no', "\n";

$items->setFlags(
    CachingIterator::FULL_CACHE | CachingIterator::TOSTRING_USE_CURRENT
);
echo cachingFlagNames($items->getFlags()), ':', (string) $items, "\n";

$items->next();
echo cachingFlagNames($items->getFlags()), ':', (string) $items,
    '; next=', $items->hasNext() ? 'yes' : 'no', "\n";
Ожидаемый результат
TOSTRING_USE_KEY|FULL_CACHE:SKU-1; next=yes
TOSTRING_USE_CURRENT|FULL_CACHE:Brush
TOSTRING_USE_CURRENT|FULL_CACHE:Paint; next=no

getFlags() вернул битовую маску. Оператор & проверил отдельные биты, а | объединил режимы. setFlags() заменил всю маску, поэтому FULL_CACHE включён повторно вместе с новым TOSTRING_USE_CURRENT. hasNext() подтвердил сосед только на первой позиции.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

CachingIterator::next

(PHP 5, PHP 7, PHP 8) CachingIterator::next — Move the iterator forward

Description

public function CachingIterator::next(): void

WarningThis function is currently not documented; only its argument list is available.

Move the iterator forward.

Parameters

This function has no parameters.

Return Values

No value is returned.

Связанные карточки: CachingIterator::rewind, CachingIterator::hasNext.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

CachingIterator::offsetExistsCachingIterator: проверить наличие ключа в полном кеше

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function CachingIterator::offsetExists($key): bool

CachingIterator::offsetExists работает с ArrayAccess-представлением FULL_CACHE, а не с внутренним хранилищем. Пример отдельно показывает накопление и ручное изменение диагностического слоя.

ПараметрЧто означает в задаче
keyЗначение параметра связано с текущей операцией; допустимый тип и значение по умолчанию видны в сигнатуре, а фактическая роль показана перед примером.
Часть контрактаЧто важно
Сигнатураpublic function CachingIterator::offsetExists($key): bool
Результатbool: true, если ключ есть в текущем FULL_CACHE; непрочитанный ключ даёт false.
Ошибки и особые значенияБез FULL_CACHE выбрасывается BadMethodCallException.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Импорт заказов читается постепенно. Для диагностики нужно посмотреть только реально пройденные записи и временно пометить одну из них, не изменяя исходный ArrayIterator.

Увидеть только уже прочитанную часть потокаСамостоятельный пример
<?php
declare(strict_types=1);

$orders = new CachingIterator(
    new ArrayIterator([
        'order-101' => 'new',
        'order-102' => 'paid',
        'order-103' => 'sent',
    ]),
    CachingIterator::FULL_CACHE
);

$orders->rewind();
echo 'key=', $orders->key(), '; full-cache=',
    ($orders->getFlags() & CachingIterator::FULL_CACHE) !== 0 ? 'yes' : 'no',
    "\n";
echo json_encode($orders->getCache()), "\n";

$orders->next();
echo json_encode($orders->getCache()), "\n";
echo 'count=', count($orders),
    '; exists=', isset($orders['order-102']) ? 'yes' : 'no',
    '; value=', $orders['order-102'], "\n";

$orders['review'] = 'manual';
echo json_encode($orders->getCache()), "\n";
unset($orders['review']);
echo json_encode($orders->getCache()), "\n";
Ожидаемый результат
key=order-101; full-cache=yes
{"order-101":"new"}
{"order-101":"new","order-102":"paid"}
count=2; exists=yes; value=paid
{"order-101":"new","order-102":"paid","review":"manual"}
{"order-101":"new","order-102":"paid"}

FULL_CACHE добавил текущую запись при rewind() и следующую при next(). getCache(), count() и ArrayAccess работают с накопленным кешем: непрочитанный order-103 ещё отсутствует. Запись review появилась только в кеше и была удалена; это не команда изменить исходный источник.

Скачать самостоятельный пример с fixtures, результатом и README

Разработчик создал CachingIterator без полного кеша, а позднее попытался читать его как массив. Пример делает отказ видимым и затем включает нужный режим явно.

Распознать операции, которым обязательно нужен FULL_CACHEСамостоятельный пример
<?php
declare(strict_types=1);

$plain = new CachingIterator(new ArrayIterator(['A']), 0);
$plain->rewind();

$operations = [
    'getCache' => fn() => $plain->getCache(),
    'count' => fn() => count($plain),
    'offsetExists' => fn() => isset($plain['missing']),
    'offsetGet' => fn() => $plain['missing'],
];

foreach ($operations as $name => $operation) {
    try {
        $operation();
        echo "$name: no error\n";
    } catch (BadMethodCallException) {
        echo "$name: FULL_CACHE required\n";
    }
}

$plain->setFlags(CachingIterator::FULL_CACHE);
$plain->rewind();
echo 'after setFlags: ', count($plain), "\n";
Ожидаемый результат
getCache: FULL_CACHE required
count: FULL_CACHE required
offsetExists: FULL_CACHE required
offsetGet: FULL_CACHE required
after setFlags: 1

Флаг 0 разрешает обычный обход, но getCache(), Countable и ArrayAccess выбрасывают BadMethodCallException. После setFlags(FULL_CACHE) и нового rewind() текущий элемент попал в кеш, поэтому count() вернул 1. Не скрывайте такую ошибку оператором @.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

CachingIterator::offsetExists

(PHP 5 >= 5.2.0, PHP 7, PHP 8) CachingIterator::offsetExists — The offsetExists purpose

Description

public function CachingIterator::offsetExists(string $key): bool

WarningThis function is currently not documented; only its argument list is available.

Parameters

key

The index being checked.

Return Values

Returns true if an entry referenced by the offset exists, false otherwise.

Связанные карточки: CachingIterator::getCache, CachingIterator::count.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

CachingIterator::offsetGetCachingIterator: прочитать значение полного кеша по ключу

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function CachingIterator::offsetGet($key): mixed

CachingIterator::offsetGet работает с ArrayAccess-представлением FULL_CACHE, а не с внутренним хранилищем. Пример отдельно показывает накопление и ручное изменение диагностического слоя.

ПараметрЧто означает в задаче
keyЗначение параметра связано с текущей операцией; допустимый тип и значение по умолчанию видны в сигнатуре, а фактическая роль показана перед примером.
Часть контрактаЧто важно
Сигнатураpublic function CachingIterator::offsetGet($key): mixed
Результатmixed: кешированное либо вручную добавленное значение выбранного ключа.
Ошибки и особые значенияБез FULL_CACHE выбрасывается BadMethodCallException; отсутствие ключа не следует смешивать с сохранённым null.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Импорт заказов читается постепенно. Для диагностики нужно посмотреть только реально пройденные записи и временно пометить одну из них, не изменяя исходный ArrayIterator.

Увидеть только уже прочитанную часть потокаСамостоятельный пример
<?php
declare(strict_types=1);

$orders = new CachingIterator(
    new ArrayIterator([
        'order-101' => 'new',
        'order-102' => 'paid',
        'order-103' => 'sent',
    ]),
    CachingIterator::FULL_CACHE
);

$orders->rewind();
echo 'key=', $orders->key(), '; full-cache=',
    ($orders->getFlags() & CachingIterator::FULL_CACHE) !== 0 ? 'yes' : 'no',
    "\n";
echo json_encode($orders->getCache()), "\n";

$orders->next();
echo json_encode($orders->getCache()), "\n";
echo 'count=', count($orders),
    '; exists=', isset($orders['order-102']) ? 'yes' : 'no',
    '; value=', $orders['order-102'], "\n";

$orders['review'] = 'manual';
echo json_encode($orders->getCache()), "\n";
unset($orders['review']);
echo json_encode($orders->getCache()), "\n";
Ожидаемый результат
key=order-101; full-cache=yes
{"order-101":"new"}
{"order-101":"new","order-102":"paid"}
count=2; exists=yes; value=paid
{"order-101":"new","order-102":"paid","review":"manual"}
{"order-101":"new","order-102":"paid"}

FULL_CACHE добавил текущую запись при rewind() и следующую при next(). getCache(), count() и ArrayAccess работают с накопленным кешем: непрочитанный order-103 ещё отсутствует. Запись review появилась только в кеше и была удалена; это не команда изменить исходный источник.

Скачать самостоятельный пример с fixtures, результатом и README

Разработчик создал CachingIterator без полного кеша, а позднее попытался читать его как массив. Пример делает отказ видимым и затем включает нужный режим явно.

Распознать операции, которым обязательно нужен FULL_CACHEСамостоятельный пример
<?php
declare(strict_types=1);

$plain = new CachingIterator(new ArrayIterator(['A']), 0);
$plain->rewind();

$operations = [
    'getCache' => fn() => $plain->getCache(),
    'count' => fn() => count($plain),
    'offsetExists' => fn() => isset($plain['missing']),
    'offsetGet' => fn() => $plain['missing'],
];

foreach ($operations as $name => $operation) {
    try {
        $operation();
        echo "$name: no error\n";
    } catch (BadMethodCallException) {
        echo "$name: FULL_CACHE required\n";
    }
}

$plain->setFlags(CachingIterator::FULL_CACHE);
$plain->rewind();
echo 'after setFlags: ', count($plain), "\n";
Ожидаемый результат
getCache: FULL_CACHE required
count: FULL_CACHE required
offsetExists: FULL_CACHE required
offsetGet: FULL_CACHE required
after setFlags: 1

Флаг 0 разрешает обычный обход, но getCache(), Countable и ArrayAccess выбрасывают BadMethodCallException. После setFlags(FULL_CACHE) и нового rewind() текущий элемент попал в кеш, поэтому count() вернул 1. Не скрывайте такую ошибку оператором @.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

CachingIterator::offsetGet

(PHP 5 >= 5.2.0, PHP 7, PHP 8) CachingIterator::offsetGet — The offsetGet purpose

Description

public function CachingIterator::offsetGet(string $key): mixed

WarningThis function is currently not documented; only its argument list is available.

Parameters

key

Description...

Return Values

Description...

Связанные карточки: CachingIterator::getCache, CachingIterator::count.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

CachingIterator::offsetSetCachingIterator: записать значение только в массив полного кеша

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function CachingIterator::offsetSet($key, mixed $value): void

CachingIterator::offsetSet работает с ArrayAccess-представлением FULL_CACHE, а не с внутренним хранилищем. Пример отдельно показывает накопление и ручное изменение диагностического слоя.

ПараметрЧто означает в задаче
keyЗначение параметра связано с текущей операцией; допустимый тип и значение по умолчанию видны в сигнатуре, а фактическая роль показана перед примером.
valueЗначение параметра связано с текущей операцией; допустимый тип и значение по умолчанию видны в сигнатуре, а фактическая роль показана перед примером.
Часть контрактаЧто важно
Сигнатураpublic function CachingIterator::offsetSet($key, mixed $value): void
Результатvoid: после вызова новый ключ/значение видны через getCache() и ArrayAccess.
Ошибки и особые значенияБез FULL_CACHE выбрасывается BadMethodCallException; неподходящий ключ может вызвать TypeError/ValueError целевой версии.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Импорт заказов читается постепенно. Для диагностики нужно посмотреть только реально пройденные записи и временно пометить одну из них, не изменяя исходный ArrayIterator.

Увидеть только уже прочитанную часть потокаСамостоятельный пример
<?php
declare(strict_types=1);

$orders = new CachingIterator(
    new ArrayIterator([
        'order-101' => 'new',
        'order-102' => 'paid',
        'order-103' => 'sent',
    ]),
    CachingIterator::FULL_CACHE
);

$orders->rewind();
echo 'key=', $orders->key(), '; full-cache=',
    ($orders->getFlags() & CachingIterator::FULL_CACHE) !== 0 ? 'yes' : 'no',
    "\n";
echo json_encode($orders->getCache()), "\n";

$orders->next();
echo json_encode($orders->getCache()), "\n";
echo 'count=', count($orders),
    '; exists=', isset($orders['order-102']) ? 'yes' : 'no',
    '; value=', $orders['order-102'], "\n";

$orders['review'] = 'manual';
echo json_encode($orders->getCache()), "\n";
unset($orders['review']);
echo json_encode($orders->getCache()), "\n";
Ожидаемый результат
key=order-101; full-cache=yes
{"order-101":"new"}
{"order-101":"new","order-102":"paid"}
count=2; exists=yes; value=paid
{"order-101":"new","order-102":"paid","review":"manual"}
{"order-101":"new","order-102":"paid"}

FULL_CACHE добавил текущую запись при rewind() и следующую при next(). getCache(), count() и ArrayAccess работают с накопленным кешем: непрочитанный order-103 ещё отсутствует. Запись review появилась только в кеше и была удалена; это не команда изменить исходный источник.

Скачать самостоятельный пример с fixtures, результатом и README

Панель диагностики добавляет свою пометку и исправляет отображаемое число. Важно не спутать этот слой с хранилищем заказов.

Изменить диагностический кеш, не переписав источникСамостоятельный пример
<?php
declare(strict_types=1);

$source = new ArrayIterator(['a' => 10, 'b' => 20]);
$cache = new CachingIterator($source, CachingIterator::FULL_CACHE);
iterator_to_array($cache);

$cache->offsetSet('a', 99);
$cache->offsetSet('note', 'checked');
echo 'cache=', json_encode($cache->getCache()), "\n";
echo 'source=', json_encode($source->getArrayCopy()), "\n";

$cache->offsetUnset('note');
echo 'after unset=', json_encode($cache->getCache()), "\n";
Ожидаемый результат
cache={"a":99,"b":20,"note":"checked"}
source={"a":10,"b":20}
after unset={"a":99,"b":20}

offsetSet() и offsetUnset() изменили массив полного кеша. Исходный ArrayIterator сохранил a=10 и b=20. Если требуется изменить бизнес-данные, меняйте их через API владельца данных, а не через диагностический кеш.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

CachingIterator::offsetSet

(PHP 5 >= 5.2.0, PHP 7, PHP 8) CachingIterator::offsetSet — The offsetSet purpose

Description

public function CachingIterator::offsetSet(string $key, mixed $value): void

WarningThis function is currently not documented; only its argument list is available.

Parameters

key

The index of the element to be set.

value

The new value for the key.

Return Values

No value is returned.

Связанные карточки: CachingIterator::getCache, CachingIterator::count.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

CachingIterator::offsetUnsetCachingIterator: удалить ключ только из массива полного кеша

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function CachingIterator::offsetUnset($key): void

CachingIterator::offsetUnset работает с ArrayAccess-представлением FULL_CACHE, а не с внутренним хранилищем. Пример отдельно показывает накопление и ручное изменение диагностического слоя.

ПараметрЧто означает в задаче
keyЗначение параметра связано с текущей операцией; допустимый тип и значение по умолчанию видны в сигнатуре, а фактическая роль показана перед примером.
Часть контрактаЧто важно
Сигнатураpublic function CachingIterator::offsetUnset($key): void
Результатvoid: выбранный ключ исчезает из getCache(); источник остаётся прежним.
Ошибки и особые значенияБез FULL_CACHE выбрасывается BadMethodCallException.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Импорт заказов читается постепенно. Для диагностики нужно посмотреть только реально пройденные записи и временно пометить одну из них, не изменяя исходный ArrayIterator.

Увидеть только уже прочитанную часть потокаСамостоятельный пример
<?php
declare(strict_types=1);

$orders = new CachingIterator(
    new ArrayIterator([
        'order-101' => 'new',
        'order-102' => 'paid',
        'order-103' => 'sent',
    ]),
    CachingIterator::FULL_CACHE
);

$orders->rewind();
echo 'key=', $orders->key(), '; full-cache=',
    ($orders->getFlags() & CachingIterator::FULL_CACHE) !== 0 ? 'yes' : 'no',
    "\n";
echo json_encode($orders->getCache()), "\n";

$orders->next();
echo json_encode($orders->getCache()), "\n";
echo 'count=', count($orders),
    '; exists=', isset($orders['order-102']) ? 'yes' : 'no',
    '; value=', $orders['order-102'], "\n";

$orders['review'] = 'manual';
echo json_encode($orders->getCache()), "\n";
unset($orders['review']);
echo json_encode($orders->getCache()), "\n";
Ожидаемый результат
key=order-101; full-cache=yes
{"order-101":"new"}
{"order-101":"new","order-102":"paid"}
count=2; exists=yes; value=paid
{"order-101":"new","order-102":"paid","review":"manual"}
{"order-101":"new","order-102":"paid"}

FULL_CACHE добавил текущую запись при rewind() и следующую при next(). getCache(), count() и ArrayAccess работают с накопленным кешем: непрочитанный order-103 ещё отсутствует. Запись review появилась только в кеше и была удалена; это не команда изменить исходный источник.

Скачать самостоятельный пример с fixtures, результатом и README

Панель диагностики добавляет свою пометку и исправляет отображаемое число. Важно не спутать этот слой с хранилищем заказов.

Изменить диагностический кеш, не переписав источникСамостоятельный пример
<?php
declare(strict_types=1);

$source = new ArrayIterator(['a' => 10, 'b' => 20]);
$cache = new CachingIterator($source, CachingIterator::FULL_CACHE);
iterator_to_array($cache);

$cache->offsetSet('a', 99);
$cache->offsetSet('note', 'checked');
echo 'cache=', json_encode($cache->getCache()), "\n";
echo 'source=', json_encode($source->getArrayCopy()), "\n";

$cache->offsetUnset('note');
echo 'after unset=', json_encode($cache->getCache()), "\n";
Ожидаемый результат
cache={"a":99,"b":20,"note":"checked"}
source={"a":10,"b":20}
after unset={"a":99,"b":20}

offsetSet() и offsetUnset() изменили массив полного кеша. Исходный ArrayIterator сохранил a=10 и b=20. Если требуется изменить бизнес-данные, меняйте их через API владельца данных, а не через диагностический кеш.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

CachingIterator::offsetUnset

(PHP 5 >= 5.2.0, PHP 7, PHP 8) CachingIterator::offsetUnset — The offsetUnset purpose

Description

public function CachingIterator::offsetUnset(string $key): void

WarningThis function is currently not documented; only its argument list is available.

Parameters

key

The index of the element to be unset.

Return Values

No value is returned.

Связанные карточки: CachingIterator::getCache, CachingIterator::count.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

CachingIterator::rewindПеремотать повторяемый источник и подготовить первую позицию

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function CachingIterator::rewind(): void

rewind() вызывает перемотку внутреннего Iterator, проверяет первую позицию и обновляет состояние CachingIterator. При FULL_CACHE первая пара уже видна сразу после вызова.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function CachingIterator::rewind(): void
Результатvoid: новое состояние читается current()/key()/valid()/getCache().
Ошибки и особые значенияОдноразовый либо уже закрытый источник может не поддержать повторную перемотку; исключение передаётся вызывающему коду.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Интерфейс показывает цепочку этапов. После последнего этапа стрелка не нужна, но обычный foreach сам по себе не сообщает, есть ли сосед справа.

Поставить разделитель только между этапами заказаСамостоятельный пример
<?php
declare(strict_types=1);

$steps = new CachingIterator(
    new ArrayIterator(['received', 'paid', 'shipped'])
);

foreach ($steps as $step) {
    echo $steps->key(), ':', (string) $steps;
    echo $steps->hasNext() ? ' -> ' : "\n";
}
Ожидаемый результат
0:received -> 1:paid -> 2:shipped

foreach вызвал rewind(), valid(), current() и next(). На каждой позиции hasNext() заглянул на один шаг вперёд, не потребляя соседний элемент. Поэтому разделитель появился только между значениями. __toString() безопасен здесь, потому что значения — строки и действует стандартный CALL_TOSTRING.

Скачать самостоятельный пример с fixtures, результатом и README

Импорт заказов читается постепенно. Для диагностики нужно посмотреть только реально пройденные записи и временно пометить одну из них, не изменяя исходный ArrayIterator.

Увидеть только уже прочитанную часть потокаСамостоятельный пример
<?php
declare(strict_types=1);

$orders = new CachingIterator(
    new ArrayIterator([
        'order-101' => 'new',
        'order-102' => 'paid',
        'order-103' => 'sent',
    ]),
    CachingIterator::FULL_CACHE
);

$orders->rewind();
echo 'key=', $orders->key(), '; full-cache=',
    ($orders->getFlags() & CachingIterator::FULL_CACHE) !== 0 ? 'yes' : 'no',
    "\n";
echo json_encode($orders->getCache()), "\n";

$orders->next();
echo json_encode($orders->getCache()), "\n";
echo 'count=', count($orders),
    '; exists=', isset($orders['order-102']) ? 'yes' : 'no',
    '; value=', $orders['order-102'], "\n";

$orders['review'] = 'manual';
echo json_encode($orders->getCache()), "\n";
unset($orders['review']);
echo json_encode($orders->getCache()), "\n";
Ожидаемый результат
key=order-101; full-cache=yes
{"order-101":"new"}
{"order-101":"new","order-102":"paid"}
count=2; exists=yes; value=paid
{"order-101":"new","order-102":"paid","review":"manual"}
{"order-101":"new","order-102":"paid"}

FULL_CACHE добавил текущую запись при rewind() и следующую при next(). getCache(), count() и ArrayAccess работают с накопленным кешем: непрочитанный order-103 ещё отсутствует. Запись review появилась только в кеше и была удалена; это не команда изменить исходный источник.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

CachingIterator::rewind

(PHP 5, PHP 7, PHP 8) CachingIterator::rewind — Rewind the iterator

Description

public function CachingIterator::rewind(): void

WarningThis function is currently not documented; only its argument list is available.

Rewind the iterator.

Parameters

This function has no parameters.

Return Values

No value is returned.

Связанные карточки: CachingIterator::valid, CachingIterator::next.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

CachingIterator::setFlagsПолностью заменить маску режимов существующего CachingIterator

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function CachingIterator::setFlags(int $flags): void

setFlags() принимает новую полную маску. В одном примере строковое представление переключается с ключа на значение; в другом FULL_CACHE включается после контролируемого отказа.

ПараметрЧто означает в задаче
flagsБитовая маска режима. Оператор | объединяет совместимые константы; setFlags заменяет прежнюю маску целиком.
Часть контрактаЧто важно
Сигнатураpublic function CachingIterator::setFlags(int $flags): void
Результатvoid: новое состояние проверяют getFlags(); кеш начинает наполняться при последующих позиционированиях.
Ошибки и особые значенияНедопустимая комбинация нескольких TOSTRING-режимов вызывает ValueError. После создания нельзя снять CALL_TOSTRING или TOSTRING_USE_INNER: PHP выбросит InvalidArgumentException. Неподходящий тип вызывает TypeError.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Один диагностический экран должен сначала показывать артикул, а затем название товара. Источник и курсор остаются прежними; меняется только правило __toString().

Переключить строковое представление с ключа на значениеСамостоятельный пример
<?php
declare(strict_types=1);

function cachingFlagNames(int $flags): string
{
    $names = [];
    foreach (['TOSTRING_USE_KEY', 'TOSTRING_USE_CURRENT', 'FULL_CACHE'] as $name) {
        $value = constant("CachingIterator::$name");
        if (($flags & $value) === $value) {
            $names[] = $name;
        }
    }
    return implode('|', $names);
}

$items = new CachingIterator(
    new ArrayIterator(['SKU-1' => 'Brush', 'SKU-2' => 'Paint']),
    CachingIterator::FULL_CACHE | CachingIterator::TOSTRING_USE_KEY
);

$items->rewind();
echo cachingFlagNames($items->getFlags()), ':', (string) $items,
    '; next=', $items->hasNext() ? 'yes' : 'no', "\n";

$items->setFlags(
    CachingIterator::FULL_CACHE | CachingIterator::TOSTRING_USE_CURRENT
);
echo cachingFlagNames($items->getFlags()), ':', (string) $items, "\n";

$items->next();
echo cachingFlagNames($items->getFlags()), ':', (string) $items,
    '; next=', $items->hasNext() ? 'yes' : 'no', "\n";
Ожидаемый результат
TOSTRING_USE_KEY|FULL_CACHE:SKU-1; next=yes
TOSTRING_USE_CURRENT|FULL_CACHE:Brush
TOSTRING_USE_CURRENT|FULL_CACHE:Paint; next=no

getFlags() вернул битовую маску. Оператор & проверил отдельные биты, а | объединил режимы. setFlags() заменил всю маску, поэтому FULL_CACHE включён повторно вместе с новым TOSTRING_USE_CURRENT. hasNext() подтвердил сосед только на первой позиции.

Скачать самостоятельный пример с fixtures, результатом и README

Разработчик создал CachingIterator без полного кеша, а позднее попытался читать его как массив. Пример делает отказ видимым и затем включает нужный режим явно.

Распознать операции, которым обязательно нужен FULL_CACHEСамостоятельный пример
<?php
declare(strict_types=1);

$plain = new CachingIterator(new ArrayIterator(['A']), 0);
$plain->rewind();

$operations = [
    'getCache' => fn() => $plain->getCache(),
    'count' => fn() => count($plain),
    'offsetExists' => fn() => isset($plain['missing']),
    'offsetGet' => fn() => $plain['missing'],
];

foreach ($operations as $name => $operation) {
    try {
        $operation();
        echo "$name: no error\n";
    } catch (BadMethodCallException) {
        echo "$name: FULL_CACHE required\n";
    }
}

$plain->setFlags(CachingIterator::FULL_CACHE);
$plain->rewind();
echo 'after setFlags: ', count($plain), "\n";
Ожидаемый результат
getCache: FULL_CACHE required
count: FULL_CACHE required
offsetExists: FULL_CACHE required
offsetGet: FULL_CACHE required
after setFlags: 1

Флаг 0 разрешает обычный обход, но getCache(), Countable и ArrayAccess выбрасывают BadMethodCallException. После setFlags(FULL_CACHE) и нового rewind() текущий элемент попал в кеш, поэтому count() вернул 1. Не скрывайте такую ошибку оператором @.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

CachingIterator::setFlags

(PHP 5 >= 5.2.0, PHP 7, PHP 8) CachingIterator::setFlags — The setFlags purpose

Description

public function CachingIterator::setFlags(int $flags): void

WarningThis function is currently not documented; only its argument list is available.

Set the flags for the CachingIterator object.

Parameters

flags

Bitmask of the flags to set.

Return Values

No value is returned.

Связанные карточки: CachingIterator::getFlags, CachingIterator::getCache.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

CachingIterator::__toStringПолучить настроенное строковое представление текущей позиции

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function CachingIterator::__toString(): string

__toString() выбирает ключ, текущее значение либо строку внутреннего итератора согласно TOSTRING-флагу. Он вызывается явным (string) и в строковом контексте.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function CachingIterator::__toString(): string
Результатstring: представление текущей позиции согласно действующей маске.
Ошибки и особые значенияБез одного из строковых режимов выбрасывается BadMethodCallException. Массив при TOSTRING_USE_CURRENT/CALL_TOSTRING вызывает предупреждение Array to string conversion.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Интерфейс показывает цепочку этапов. После последнего этапа стрелка не нужна, но обычный foreach сам по себе не сообщает, есть ли сосед справа.

Поставить разделитель только между этапами заказаСамостоятельный пример
<?php
declare(strict_types=1);

$steps = new CachingIterator(
    new ArrayIterator(['received', 'paid', 'shipped'])
);

foreach ($steps as $step) {
    echo $steps->key(), ':', (string) $steps;
    echo $steps->hasNext() ? ' -> ' : "\n";
}
Ожидаемый результат
0:received -> 1:paid -> 2:shipped

foreach вызвал rewind(), valid(), current() и next(). На каждой позиции hasNext() заглянул на один шаг вперёд, не потребляя соседний элемент. Поэтому разделитель появился только между значениями. __toString() безопасен здесь, потому что значения — строки и действует стандартный CALL_TOSTRING.

Скачать самостоятельный пример с fixtures, результатом и README

Один диагностический экран должен сначала показывать артикул, а затем название товара. Источник и курсор остаются прежними; меняется только правило __toString().

Переключить строковое представление с ключа на значениеСамостоятельный пример
<?php
declare(strict_types=1);

function cachingFlagNames(int $flags): string
{
    $names = [];
    foreach (['TOSTRING_USE_KEY', 'TOSTRING_USE_CURRENT', 'FULL_CACHE'] as $name) {
        $value = constant("CachingIterator::$name");
        if (($flags & $value) === $value) {
            $names[] = $name;
        }
    }
    return implode('|', $names);
}

$items = new CachingIterator(
    new ArrayIterator(['SKU-1' => 'Brush', 'SKU-2' => 'Paint']),
    CachingIterator::FULL_CACHE | CachingIterator::TOSTRING_USE_KEY
);

$items->rewind();
echo cachingFlagNames($items->getFlags()), ':', (string) $items,
    '; next=', $items->hasNext() ? 'yes' : 'no', "\n";

$items->setFlags(
    CachingIterator::FULL_CACHE | CachingIterator::TOSTRING_USE_CURRENT
);
echo cachingFlagNames($items->getFlags()), ':', (string) $items, "\n";

$items->next();
echo cachingFlagNames($items->getFlags()), ':', (string) $items,
    '; next=', $items->hasNext() ? 'yes' : 'no', "\n";
Ожидаемый результат
TOSTRING_USE_KEY|FULL_CACHE:SKU-1; next=yes
TOSTRING_USE_CURRENT|FULL_CACHE:Brush
TOSTRING_USE_CURRENT|FULL_CACHE:Paint; next=no

getFlags() вернул битовую маску. Оператор & проверил отдельные биты, а | объединил режимы. setFlags() заменил всю маску, поэтому FULL_CACHE включён повторно вместе с новым TOSTRING_USE_CURRENT. hasNext() подтвердил сосед только на первой позиции.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

CachingIterator::__toString

(PHP 5, PHP 7, PHP 8) CachingIterator::__toString — Return the string representation of the current element

Description

public function CachingIterator::__toString(): string

WarningThis function is currently not documented; only its argument list is available.

Get the string representation of the current element.

Parameters

This function has no parameters.

Return Values

The string representation of the current element.

Связанные карточки: CachingIterator::current, CachingIterator::setFlags.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

CachingIterator::validПроверить наличие текущей позиции после rewind/next

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function CachingIterator::valid(): bool

valid() сообщает, можно ли безопасно читать current() и key(). foreach выполняет эту проверку автоматически; ручной протокол должен делать её явно.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function CachingIterator::valid(): bool
Результатbool: true на существующей текущей позиции и false после конца.
Ошибки и особые значенияfalse означает конец обхода, а не пустое бизнес-значение. Исключения внутреннего Iterator могут возникнуть отдельно.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Интерфейс показывает цепочку этапов. После последнего этапа стрелка не нужна, но обычный foreach сам по себе не сообщает, есть ли сосед справа.

Поставить разделитель только между этапами заказаСамостоятельный пример
<?php
declare(strict_types=1);

$steps = new CachingIterator(
    new ArrayIterator(['received', 'paid', 'shipped'])
);

foreach ($steps as $step) {
    echo $steps->key(), ':', (string) $steps;
    echo $steps->hasNext() ? ' -> ' : "\n";
}
Ожидаемый результат
0:received -> 1:paid -> 2:shipped

foreach вызвал rewind(), valid(), current() и next(). На каждой позиции hasNext() заглянул на один шаг вперёд, не потребляя соседний элемент. Поэтому разделитель появился только между значениями. __toString() безопасен здесь, потому что значения — строки и действует стандартный CALL_TOSTRING.

Скачать самостоятельный пример с fixtures, результатом и README

Импорт заказов читается постепенно. Для диагностики нужно посмотреть только реально пройденные записи и временно пометить одну из них, не изменяя исходный ArrayIterator.

Увидеть только уже прочитанную часть потокаСамостоятельный пример
<?php
declare(strict_types=1);

$orders = new CachingIterator(
    new ArrayIterator([
        'order-101' => 'new',
        'order-102' => 'paid',
        'order-103' => 'sent',
    ]),
    CachingIterator::FULL_CACHE
);

$orders->rewind();
echo 'key=', $orders->key(), '; full-cache=',
    ($orders->getFlags() & CachingIterator::FULL_CACHE) !== 0 ? 'yes' : 'no',
    "\n";
echo json_encode($orders->getCache()), "\n";

$orders->next();
echo json_encode($orders->getCache()), "\n";
echo 'count=', count($orders),
    '; exists=', isset($orders['order-102']) ? 'yes' : 'no',
    '; value=', $orders['order-102'], "\n";

$orders['review'] = 'manual';
echo json_encode($orders->getCache()), "\n";
unset($orders['review']);
echo json_encode($orders->getCache()), "\n";
Ожидаемый результат
key=order-101; full-cache=yes
{"order-101":"new"}
{"order-101":"new","order-102":"paid"}
count=2; exists=yes; value=paid
{"order-101":"new","order-102":"paid","review":"manual"}
{"order-101":"new","order-102":"paid"}

FULL_CACHE добавил текущую запись при rewind() и следующую при next(). getCache(), count() и ArrayAccess работают с накопленным кешем: непрочитанный order-103 ещё отсутствует. Запись review появилась только в кеше и была удалена; это не команда изменить исходный источник.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

CachingIterator::valid

(PHP 5, PHP 7, PHP 8) CachingIterator::valid — Check whether the current element is valid

Description

public function CachingIterator::valid(): bool

WarningThis function is currently not documented; only its argument list is available.

Check whether the current element is valid.

Parameters

This function has no parameters.

Return Values

Returns true on success or false on failure.

Связанные карточки: CachingIterator::current, CachingIterator::rewind.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

CallbackFilterIterator::__constructСвязать Iterator с функцией-предикатом true/false

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function CallbackFilterIterator::__construct(Iterator $iterator, callable $callback)

CallbackFilterIterator вызывает переданный callable как callback($current, $key, $iterator). Возвращённый bool решает судьбу только текущего элемента; исходный Iterator не переписывается.

ПараметрЧто означает в задаче
iteratorГотовый Iterator заказов/остатков; курсор остаётся общим с фильтром.
callbackCallable, принимающий current, key и внутренний Iterator и возвращающий bool.
Часть контрактаЧто важно
Сигнатураpublic function CallbackFilterIterator::__construct(Iterator $iterator, callable $callback)
РезультатКонструктор не возвращает прикладное значение; new создаёт фильтр, который начнёт вызывать callback только при обходе.
Ошибки и особые значенияНе-Iterator или не-callable вызывает TypeError. Исключение callback не превращается в false и прерывает обход.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Платёжный обработчик получил три заказа, но чек нужен только для статуса paid. Сначала правило записано обычной именованной функцией, чтобы было видно вход и bool-результат.

Отправить чеки только по оплаченным заказамСамостоятельный пример
<?php
declare(strict_types=1);

$orders = new ArrayIterator([
    ['id' => 101, 'status' => 'new'],
    ['id' => 102, 'status' => 'paid'],
    ['id' => 103, 'status' => 'paid'],
]);

function isPaidOrder(array $order): bool
{
    return $order['status'] === 'paid';
}

$paidOrders = new CallbackFilterIterator($orders, 'isPaidOrder');
foreach ($paidOrders as $order) {
    echo 'send receipt #', $order['id'], "\n";
}
Ожидаемый результат
send receipt #102
send receipt #103

isPaidOrder — предикат: вопрос с ответом true или false. Callback — ссылка на вызываемую функцию; строка isPaidOrder передана конструктору, а итератор вызвал её для каждой строки. true оставил заказ, false пропустил его.

Скачать самостоятельный пример с fixtures, результатом и README

Один источник содержит склад и веб-витрину. Для публикации нужны ключи web-* с положительным остатком.

Выбрать доступные остатки веб-витрины по значению и ключуСамостоятельный пример
<?php
declare(strict_types=1);

$stock = new ArrayIterator([
    'web-brush' => 3,
    'store-paint' => 7,
    'web-tape' => 0,
    'web-gloves' => 2,
]);

$webAvailable = new CallbackFilterIterator(
    $stock,
    function (int $quantity, string $key, Iterator $iterator) use ($stock): bool {
        return $iterator === $stock
            && str_starts_with($key, 'web-')
            && $quantity > 0;
    }
);

foreach ($webAvailable as $sku => $quantity) {
    echo "$sku=$quantity\n";
}
Ожидаемый результат
web-brush=3
web-gloves=2

Анонимный callback получил значение, ключ и внутренний Iterator. Проверка идентичности показывает, какой именно объект приходит третьим аргументом; в обычном предикате она чаще не нужна. Условия соединены &&: только true по всем трём проверкам оставляет элемент.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

CallbackFilterIterator::__construct

(PHP 5 >= 5.4.0, PHP 7, PHP 8) CallbackFilterIterator::__construct — Create a filtered iterator from another iterator

Description

public function CallbackFilterIterator::__construct(Iterator $iterator, callable $callback)

Creates a filtered iterator using the callback to determine which items are accepted or rejected.

Parameters

iterator

The iterator to be filtered.

callback

The callback, which should return true to accept the current item or false otherwise. See Examples.

May be any valid callable value.

See Also

CallbackFilterIterator Examples

CallbackFilterIterator::accept() - Calls the callback with the current value, the current key and the inner iterator as arguments

Связанные карточки: CallbackFilterIterator::accept, FilterIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

CallbackFilterIterator::acceptВызвать callback для текущих value/key/iterator и получить решение

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function CallbackFilterIterator::accept(): bool

CallbackFilterIterator вызывает переданный callable как callback($current, $key, $iterator). Возвращённый bool решает судьбу только текущего элемента; исходный Iterator не переписывается.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function CallbackFilterIterator::accept(): bool
Результатbool: true оставляет текущий элемент, false заставляет механизм искать следующий.
Ошибки и особые значенияИсключение, TypeError или неверное обращение к структуре внутри callback передаётся вызывающему коду.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Платёжный обработчик получил три заказа, но чек нужен только для статуса paid. Сначала правило записано обычной именованной функцией, чтобы было видно вход и bool-результат.

Отправить чеки только по оплаченным заказамСамостоятельный пример
<?php
declare(strict_types=1);

$orders = new ArrayIterator([
    ['id' => 101, 'status' => 'new'],
    ['id' => 102, 'status' => 'paid'],
    ['id' => 103, 'status' => 'paid'],
]);

function isPaidOrder(array $order): bool
{
    return $order['status'] === 'paid';
}

$paidOrders = new CallbackFilterIterator($orders, 'isPaidOrder');
foreach ($paidOrders as $order) {
    echo 'send receipt #', $order['id'], "\n";
}
Ожидаемый результат
send receipt #102
send receipt #103

isPaidOrder — предикат: вопрос с ответом true или false. Callback — ссылка на вызываемую функцию; строка isPaidOrder передана конструктору, а итератор вызвал её для каждой строки. true оставил заказ, false пропустил его.

Скачать самостоятельный пример с fixtures, результатом и README

Один источник содержит склад и веб-витрину. Для публикации нужны ключи web-* с положительным остатком.

Выбрать доступные остатки веб-витрины по значению и ключуСамостоятельный пример
<?php
declare(strict_types=1);

$stock = new ArrayIterator([
    'web-brush' => 3,
    'store-paint' => 7,
    'web-tape' => 0,
    'web-gloves' => 2,
]);

$webAvailable = new CallbackFilterIterator(
    $stock,
    function (int $quantity, string $key, Iterator $iterator) use ($stock): bool {
        return $iterator === $stock
            && str_starts_with($key, 'web-')
            && $quantity > 0;
    }
);

foreach ($webAvailable as $sku => $quantity) {
    echo "$sku=$quantity\n";
}
Ожидаемый результат
web-brush=3
web-gloves=2

Анонимный callback получил значение, ключ и внутренний Iterator. Проверка идентичности показывает, какой именно объект приходит третьим аргументом; в обычном предикате она чаще не нужна. Условия соединены &&: только true по всем трём проверкам оставляет элемент.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

CallbackFilterIterator::accept

(PHP 5 >= 5.4.0, PHP 7, PHP 8) CallbackFilterIterator::accept — Calls the callback with the current value, the current key and the inner iterator as arguments

Description

public function CallbackFilterIterator::accept(): bool

This method calls the callback with the current value, current key and the inner iterator.

The callback is expected to return true if the current item is to be accepted, or false otherwise.

Parameters

This function has no parameters.

Return Values

Returns true to accept the current item, or false otherwise.

See Also

CallbackFilterIterator Examples

CallbackFilterIterator::__construct() - Create a filtered iterator from another iterator

Связанные карточки: CallbackFilterIterator::__construct, FilterIterator::accept.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

FilterIterator::acceptОпределить повторно используемое правило принятия текущего элемента

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

abstract public function FilterIterator::accept(): bool

Подкласс FilterIterator реализует accept(): bool. Механизм двигает внутренний Iterator, пока accept() не вернёт true; наружу видны только принятые позиции.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураabstract public function FilterIterator::accept(): bool
Результатbool: true оставляет текущую позицию, false продолжает поиск.
Ошибки и особые значенияFilterIterator абстрактный: подкласс без accept() нельзя создать. Исключение внутри правила прерывает обход.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Правило «остаток больше нуля» используется в двух каталогах и будет нужно в других отчётах. Отдельный класс даёт правилу имя и одно место изменения.

Повторно использовать один класс правила для двух каталоговСамостоятельный пример
<?php
declare(strict_types=1);

final class AvailableProducts extends FilterIterator
{
    public function accept(): bool
    {
        $product = parent::current();
        return is_array($product) && $product['stock'] > 0;
    }
}

$catalogs = [
    new ArrayIterator([
        ['name' => 'Brush', 'stock' => 2],
        ['name' => 'Paint', 'stock' => 0],
    ]),
    new ArrayIterator([
        ['name' => 'Tape', 'stock' => 4],
        ['name' => 'Gloves', 'stock' => 0],
    ]),
];

foreach ($catalogs as $catalog) {
    foreach (new AvailableProducts($catalog) as $product) {
        echo $product['name'], "\n";
    }
}
Ожидаемый результат
Brush
Tape

FilterIterator абстрактный: его нельзя создать напрямую, поэтому AvailableProducts реализует accept(). parent::current() читает текущую строку внутреннего итератора. Один класс отфильтровал два разных ArrayIterator без копирования условия.

Скачать самостоятельный пример с fixtures, результатом и README

Нужно понять не только результат foreach, но и пять операций Iterator-протокола. Минимальная цена хранится в объекте фильтра.

Увидеть, как курсор пропускает неподходящие ценыСамостоятельный пример
<?php
declare(strict_types=1);

final class PriceAtLeast extends FilterIterator
{
    public function __construct(Iterator $iterator, private int $minimum)
    {
        parent::__construct($iterator);
    }

    public function accept(): bool
    {
        return parent::current() >= $this->minimum;
    }
}

$prices = new PriceAtLeast(
    new ArrayIterator(['pen' => 40, 'brush' => 120, 'paint' => 300]),
    100
);

$prices->rewind();
while ($prices->valid()) {
    echo $prices->key(), '=', $prices->current(), "\n";
    $prices->next();
}
Ожидаемый результат
brush=120
paint=300

rewind() перемотал источник и сразу продвинул его мимо pen=40 до первого accept() === true. current()/key() прочитали brush. next() снова двигал внутренний курсор до следующего принятого элемента, а valid() завершил цикл после paint.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

FilterIterator::accept

(PHP 5 >= 5.1.0, PHP 7, PHP 8) FilterIterator::accept — Check whether the current element of the iterator is acceptable

Description

public function FilterIterator::accept(): bool

Returns whether the current element of the iterator is acceptable through this filter.

Parameters

This function has no parameters.

Return Values

true if the current element is acceptable, otherwise false.

Связанные карточки: CallbackFilterIterator::accept, FilterIterator::current.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

FilterIterator::__constructПередать готовый Iterator в конструктор конкретного подкласса

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function FilterIterator::__construct(Iterator $iterator)

Подкласс FilterIterator реализует accept(): bool. Механизм двигает внутренний Iterator, пока accept() не вернёт true; наружу видны только принятые позиции.

ПараметрЧто означает в задаче
iteratorIterator, который будет лениво продвигаться до каждой принятой позиции.
Часть контрактаЧто важно
Сигнатураpublic function FilterIterator::__construct(Iterator $iterator)
РезультатКонструктор не возвращает прикладное значение; new создаёт подкласс с общим внутренним курсором.
Ошибки и особые значенияСам абстрактный FilterIterator создать нельзя. Не-Iterator вызывает TypeError; подкласс обязан передать источник в parent::__construct().
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Правило «остаток больше нуля» используется в двух каталогах и будет нужно в других отчётах. Отдельный класс даёт правилу имя и одно место изменения.

Повторно использовать один класс правила для двух каталоговСамостоятельный пример
<?php
declare(strict_types=1);

final class AvailableProducts extends FilterIterator
{
    public function accept(): bool
    {
        $product = parent::current();
        return is_array($product) && $product['stock'] > 0;
    }
}

$catalogs = [
    new ArrayIterator([
        ['name' => 'Brush', 'stock' => 2],
        ['name' => 'Paint', 'stock' => 0],
    ]),
    new ArrayIterator([
        ['name' => 'Tape', 'stock' => 4],
        ['name' => 'Gloves', 'stock' => 0],
    ]),
];

foreach ($catalogs as $catalog) {
    foreach (new AvailableProducts($catalog) as $product) {
        echo $product['name'], "\n";
    }
}
Ожидаемый результат
Brush
Tape

FilterIterator абстрактный: его нельзя создать напрямую, поэтому AvailableProducts реализует accept(). parent::current() читает текущую строку внутреннего итератора. Один класс отфильтровал два разных ArrayIterator без копирования условия.

Скачать самостоятельный пример с fixtures, результатом и README

Нужно понять не только результат foreach, но и пять операций Iterator-протокола. Минимальная цена хранится в объекте фильтра.

Увидеть, как курсор пропускает неподходящие ценыСамостоятельный пример
<?php
declare(strict_types=1);

final class PriceAtLeast extends FilterIterator
{
    public function __construct(Iterator $iterator, private int $minimum)
    {
        parent::__construct($iterator);
    }

    public function accept(): bool
    {
        return parent::current() >= $this->minimum;
    }
}

$prices = new PriceAtLeast(
    new ArrayIterator(['pen' => 40, 'brush' => 120, 'paint' => 300]),
    100
);

$prices->rewind();
while ($prices->valid()) {
    echo $prices->key(), '=', $prices->current(), "\n";
    $prices->next();
}
Ожидаемый результат
brush=120
paint=300

rewind() перемотал источник и сразу продвинул его мимо pen=40 до первого accept() === true. current()/key() прочитали brush. next() снова двигал внутренний курсор до следующего принятого элемента, а valid() завершил цикл после paint.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

FilterIterator::__construct

(PHP 5 >= 5.1.0, PHP 7, PHP 8) FilterIterator::__construct — Construct a filterIterator

Description

public function FilterIterator::__construct(Iterator $iterator)

Constructs a new FilterIterator, which consists of a passed in iterator with filters applied to it.

WarningThis function is currently not documented; only its argument list is available.

Parameters

iterator

The iterator that is being filtered.

See Also

LimitIterator::__construct() - Construct a LimitIterator

Связанные карточки: FilterIterator::accept, CallbackFilterIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

FilterIterator::currentFilterIterator: прочитать принятое текущее значение

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function FilterIterator::current(): mixed

Подкласс FilterIterator реализует accept(): bool. Механизм двигает внутренний Iterator, пока accept() не вернёт true; наружу видны только принятые позиции.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function FilterIterator::current(): mixed
Результатmixed: текущее значение внутреннего Iterator, для которого accept() вернул true.
Ошибки и особые значенияДо успешного rewind()/valid() текущего принятого элемента нет; ошибка источника передаётся наружу.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Правило «остаток больше нуля» используется в двух каталогах и будет нужно в других отчётах. Отдельный класс даёт правилу имя и одно место изменения.

Повторно использовать один класс правила для двух каталоговСамостоятельный пример
<?php
declare(strict_types=1);

final class AvailableProducts extends FilterIterator
{
    public function accept(): bool
    {
        $product = parent::current();
        return is_array($product) && $product['stock'] > 0;
    }
}

$catalogs = [
    new ArrayIterator([
        ['name' => 'Brush', 'stock' => 2],
        ['name' => 'Paint', 'stock' => 0],
    ]),
    new ArrayIterator([
        ['name' => 'Tape', 'stock' => 4],
        ['name' => 'Gloves', 'stock' => 0],
    ]),
];

foreach ($catalogs as $catalog) {
    foreach (new AvailableProducts($catalog) as $product) {
        echo $product['name'], "\n";
    }
}
Ожидаемый результат
Brush
Tape

FilterIterator абстрактный: его нельзя создать напрямую, поэтому AvailableProducts реализует accept(). parent::current() читает текущую строку внутреннего итератора. Один класс отфильтровал два разных ArrayIterator без копирования условия.

Скачать самостоятельный пример с fixtures, результатом и README

Нужно понять не только результат foreach, но и пять операций Iterator-протокола. Минимальная цена хранится в объекте фильтра.

Увидеть, как курсор пропускает неподходящие ценыСамостоятельный пример
<?php
declare(strict_types=1);

final class PriceAtLeast extends FilterIterator
{
    public function __construct(Iterator $iterator, private int $minimum)
    {
        parent::__construct($iterator);
    }

    public function accept(): bool
    {
        return parent::current() >= $this->minimum;
    }
}

$prices = new PriceAtLeast(
    new ArrayIterator(['pen' => 40, 'brush' => 120, 'paint' => 300]),
    100
);

$prices->rewind();
while ($prices->valid()) {
    echo $prices->key(), '=', $prices->current(), "\n";
    $prices->next();
}
Ожидаемый результат
brush=120
paint=300

rewind() перемотал источник и сразу продвинул его мимо pen=40 до первого accept() === true. current()/key() прочитали brush. next() снова двигал внутренний курсор до следующего принятого элемента, а valid() завершил цикл после paint.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

FilterIterator::current

(PHP 5 >= 5.1.0, PHP 7, PHP 8) FilterIterator::current — Get the current element value

Description

public function FilterIterator::current(): mixed

WarningThis function is currently not documented; only its argument list is available.

Get the current element value.

Parameters

This function has no parameters.

Return Values

The current element value.

See Also

FilterIterator::key() - Get the current key

FilterIterator::next() - Move the iterator forward

Связанные карточки: FilterIterator::accept, FilterIterator::rewind.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

FilterIterator::keyFilterIterator: прочитать ключ принятой текущей позиции

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function FilterIterator::key(): mixed

Подкласс FilterIterator реализует accept(): bool. Механизм двигает внутренний Iterator, пока accept() не вернёт true; наружу видны только принятые позиции.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function FilterIterator::key(): mixed
Результатmixed: исходный ключ принятого элемента; фильтр не перенумеровывает его автоматически.
Ошибки и особые значенияНа недействительном курсоре ключ не является бизнес-данными.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Правило «остаток больше нуля» используется в двух каталогах и будет нужно в других отчётах. Отдельный класс даёт правилу имя и одно место изменения.

Повторно использовать один класс правила для двух каталоговСамостоятельный пример
<?php
declare(strict_types=1);

final class AvailableProducts extends FilterIterator
{
    public function accept(): bool
    {
        $product = parent::current();
        return is_array($product) && $product['stock'] > 0;
    }
}

$catalogs = [
    new ArrayIterator([
        ['name' => 'Brush', 'stock' => 2],
        ['name' => 'Paint', 'stock' => 0],
    ]),
    new ArrayIterator([
        ['name' => 'Tape', 'stock' => 4],
        ['name' => 'Gloves', 'stock' => 0],
    ]),
];

foreach ($catalogs as $catalog) {
    foreach (new AvailableProducts($catalog) as $product) {
        echo $product['name'], "\n";
    }
}
Ожидаемый результат
Brush
Tape

FilterIterator абстрактный: его нельзя создать напрямую, поэтому AvailableProducts реализует accept(). parent::current() читает текущую строку внутреннего итератора. Один класс отфильтровал два разных ArrayIterator без копирования условия.

Скачать самостоятельный пример с fixtures, результатом и README

Нужно понять не только результат foreach, но и пять операций Iterator-протокола. Минимальная цена хранится в объекте фильтра.

Увидеть, как курсор пропускает неподходящие ценыСамостоятельный пример
<?php
declare(strict_types=1);

final class PriceAtLeast extends FilterIterator
{
    public function __construct(Iterator $iterator, private int $minimum)
    {
        parent::__construct($iterator);
    }

    public function accept(): bool
    {
        return parent::current() >= $this->minimum;
    }
}

$prices = new PriceAtLeast(
    new ArrayIterator(['pen' => 40, 'brush' => 120, 'paint' => 300]),
    100
);

$prices->rewind();
while ($prices->valid()) {
    echo $prices->key(), '=', $prices->current(), "\n";
    $prices->next();
}
Ожидаемый результат
brush=120
paint=300

rewind() перемотал источник и сразу продвинул его мимо pen=40 до первого accept() === true. current()/key() прочитали brush. next() снова двигал внутренний курсор до следующего принятого элемента, а valid() завершил цикл после paint.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

FilterIterator::key

(PHP 5 >= 5.1.0, PHP 7, PHP 8) FilterIterator::key — Get the current key

Description

public function FilterIterator::key(): mixed

WarningThis function is currently not documented; only its argument list is available.

Get the current key.

Parameters

This function has no parameters.

Return Values

The current key.

See Also

FilterIterator::next() - Move the iterator forward

FilterIterator::current() - Get the current element value

Связанные карточки: FilterIterator::accept, FilterIterator::rewind.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

FilterIterator::nextFilterIterator: найти следующую принятую позицию

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function FilterIterator::next(): void

Подкласс FilterIterator реализует accept(): bool. Механизм двигает внутренний Iterator, пока accept() не вернёт true; наружу видны только принятые позиции.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function FilterIterator::next(): void
Результатvoid: курсор останавливается на следующем accept() === true либо после конца.
Ошибки и особые значенияИсключение accept() или внутреннего next() передаётся вызывающему коду.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Правило «остаток больше нуля» используется в двух каталогах и будет нужно в других отчётах. Отдельный класс даёт правилу имя и одно место изменения.

Повторно использовать один класс правила для двух каталоговСамостоятельный пример
<?php
declare(strict_types=1);

final class AvailableProducts extends FilterIterator
{
    public function accept(): bool
    {
        $product = parent::current();
        return is_array($product) && $product['stock'] > 0;
    }
}

$catalogs = [
    new ArrayIterator([
        ['name' => 'Brush', 'stock' => 2],
        ['name' => 'Paint', 'stock' => 0],
    ]),
    new ArrayIterator([
        ['name' => 'Tape', 'stock' => 4],
        ['name' => 'Gloves', 'stock' => 0],
    ]),
];

foreach ($catalogs as $catalog) {
    foreach (new AvailableProducts($catalog) as $product) {
        echo $product['name'], "\n";
    }
}
Ожидаемый результат
Brush
Tape

FilterIterator абстрактный: его нельзя создать напрямую, поэтому AvailableProducts реализует accept(). parent::current() читает текущую строку внутреннего итератора. Один класс отфильтровал два разных ArrayIterator без копирования условия.

Скачать самостоятельный пример с fixtures, результатом и README

Нужно понять не только результат foreach, но и пять операций Iterator-протокола. Минимальная цена хранится в объекте фильтра.

Увидеть, как курсор пропускает неподходящие ценыСамостоятельный пример
<?php
declare(strict_types=1);

final class PriceAtLeast extends FilterIterator
{
    public function __construct(Iterator $iterator, private int $minimum)
    {
        parent::__construct($iterator);
    }

    public function accept(): bool
    {
        return parent::current() >= $this->minimum;
    }
}

$prices = new PriceAtLeast(
    new ArrayIterator(['pen' => 40, 'brush' => 120, 'paint' => 300]),
    100
);

$prices->rewind();
while ($prices->valid()) {
    echo $prices->key(), '=', $prices->current(), "\n";
    $prices->next();
}
Ожидаемый результат
brush=120
paint=300

rewind() перемотал источник и сразу продвинул его мимо pen=40 до первого accept() === true. current()/key() прочитали brush. next() снова двигал внутренний курсор до следующего принятого элемента, а valid() завершил цикл после paint.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

FilterIterator::next

(PHP 5 >= 5.1.0, PHP 7, PHP 8) FilterIterator::next — Move the iterator forward

Description

public function FilterIterator::next(): void

WarningThis function is currently not documented; only its argument list is available.

Move the iterator forward.

Parameters

This function has no parameters.

Return Values

No value is returned.

See Also

FilterIterator::current() - Get the current element value

FilterIterator::key() - Get the current key

Связанные карточки: FilterIterator::accept, FilterIterator::rewind.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

FilterIterator::rewindFilterIterator: найти первую принятую позицию от начала

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function FilterIterator::rewind(): void

Подкласс FilterIterator реализует accept(): bool. Механизм двигает внутренний Iterator, пока accept() не вернёт true; наружу видны только принятые позиции.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function FilterIterator::rewind(): void
Результатvoid: после вызова valid() сообщает, найдена ли первая принятая позиция.
Ошибки и особые значенияНеперематываемый внутренний источник может отказать; исключение не скрывается.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Правило «остаток больше нуля» используется в двух каталогах и будет нужно в других отчётах. Отдельный класс даёт правилу имя и одно место изменения.

Повторно использовать один класс правила для двух каталоговСамостоятельный пример
<?php
declare(strict_types=1);

final class AvailableProducts extends FilterIterator
{
    public function accept(): bool
    {
        $product = parent::current();
        return is_array($product) && $product['stock'] > 0;
    }
}

$catalogs = [
    new ArrayIterator([
        ['name' => 'Brush', 'stock' => 2],
        ['name' => 'Paint', 'stock' => 0],
    ]),
    new ArrayIterator([
        ['name' => 'Tape', 'stock' => 4],
        ['name' => 'Gloves', 'stock' => 0],
    ]),
];

foreach ($catalogs as $catalog) {
    foreach (new AvailableProducts($catalog) as $product) {
        echo $product['name'], "\n";
    }
}
Ожидаемый результат
Brush
Tape

FilterIterator абстрактный: его нельзя создать напрямую, поэтому AvailableProducts реализует accept(). parent::current() читает текущую строку внутреннего итератора. Один класс отфильтровал два разных ArrayIterator без копирования условия.

Скачать самостоятельный пример с fixtures, результатом и README

Нужно понять не только результат foreach, но и пять операций Iterator-протокола. Минимальная цена хранится в объекте фильтра.

Увидеть, как курсор пропускает неподходящие ценыСамостоятельный пример
<?php
declare(strict_types=1);

final class PriceAtLeast extends FilterIterator
{
    public function __construct(Iterator $iterator, private int $minimum)
    {
        parent::__construct($iterator);
    }

    public function accept(): bool
    {
        return parent::current() >= $this->minimum;
    }
}

$prices = new PriceAtLeast(
    new ArrayIterator(['pen' => 40, 'brush' => 120, 'paint' => 300]),
    100
);

$prices->rewind();
while ($prices->valid()) {
    echo $prices->key(), '=', $prices->current(), "\n";
    $prices->next();
}
Ожидаемый результат
brush=120
paint=300

rewind() перемотал источник и сразу продвинул его мимо pen=40 до первого accept() === true. current()/key() прочитали brush. next() снова двигал внутренний курсор до следующего принятого элемента, а valid() завершил цикл после paint.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

FilterIterator::rewind

(PHP 5 >= 5.1.0, PHP 7, PHP 8) FilterIterator::rewind — Rewind the iterator

Description

public function FilterIterator::rewind(): void

WarningThis function is currently not documented; only its argument list is available.

Rewind the iterator.

Parameters

This function has no parameters.

Return Values

No value is returned.

See Also

FilterIterator::current() - Get the current element value

FilterIterator::key() - Get the current key

FilterIterator::next() - Move the iterator forward

Связанные карточки: FilterIterator::accept, FilterIterator::rewind.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

FilterIterator::validFilterIterator: проверить, найдена ли принятая текущая позиция

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function FilterIterator::valid(): bool

Подкласс FilterIterator реализует accept(): bool. Механизм двигает внутренний Iterator, пока accept() не вернёт true; наружу видны только принятые позиции.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function FilterIterator::valid(): bool
Результатbool: true только на текущем принятом элементе; false до позиционирования либо после конца.
Ошибки и особые значенияfalse — нормальный конец/отсутствие подходящих элементов, а не ошибка бизнес-данных.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Правило «остаток больше нуля» используется в двух каталогах и будет нужно в других отчётах. Отдельный класс даёт правилу имя и одно место изменения.

Повторно использовать один класс правила для двух каталоговСамостоятельный пример
<?php
declare(strict_types=1);

final class AvailableProducts extends FilterIterator
{
    public function accept(): bool
    {
        $product = parent::current();
        return is_array($product) && $product['stock'] > 0;
    }
}

$catalogs = [
    new ArrayIterator([
        ['name' => 'Brush', 'stock' => 2],
        ['name' => 'Paint', 'stock' => 0],
    ]),
    new ArrayIterator([
        ['name' => 'Tape', 'stock' => 4],
        ['name' => 'Gloves', 'stock' => 0],
    ]),
];

foreach ($catalogs as $catalog) {
    foreach (new AvailableProducts($catalog) as $product) {
        echo $product['name'], "\n";
    }
}
Ожидаемый результат
Brush
Tape

FilterIterator абстрактный: его нельзя создать напрямую, поэтому AvailableProducts реализует accept(). parent::current() читает текущую строку внутреннего итератора. Один класс отфильтровал два разных ArrayIterator без копирования условия.

Скачать самостоятельный пример с fixtures, результатом и README

Нужно понять не только результат foreach, но и пять операций Iterator-протокола. Минимальная цена хранится в объекте фильтра.

Увидеть, как курсор пропускает неподходящие ценыСамостоятельный пример
<?php
declare(strict_types=1);

final class PriceAtLeast extends FilterIterator
{
    public function __construct(Iterator $iterator, private int $minimum)
    {
        parent::__construct($iterator);
    }

    public function accept(): bool
    {
        return parent::current() >= $this->minimum;
    }
}

$prices = new PriceAtLeast(
    new ArrayIterator(['pen' => 40, 'brush' => 120, 'paint' => 300]),
    100
);

$prices->rewind();
while ($prices->valid()) {
    echo $prices->key(), '=', $prices->current(), "\n";
    $prices->next();
}
Ожидаемый результат
brush=120
paint=300

rewind() перемотал источник и сразу продвинул его мимо pen=40 до первого accept() === true. current()/key() прочитали brush. next() снова двигал внутренний курсор до следующего принятого элемента, а valid() завершил цикл после paint.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

FilterIterator::valid

(PHP 5 >= 5.1.0, PHP 7, PHP 8) FilterIterator::valid — Check whether the current element is valid

Description

public function FilterIterator::valid(): bool

Checks whether the current element is valid.

Note:

The standard implementation of this function will initially return false until the inner iterator is advanced to the first accepted element.

Parameters

This function has no parameters.

Return Values

true if the current element is valid, otherwise false

Связанные карточки: FilterIterator::accept, FilterIterator::rewind.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RegexIterator::acceptСопоставить current() либо key() и решить, попадёт ли элемент в обход

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RegexIterator::accept(): bool

accept() применяет pattern к строковому представлению current(), либо key() при USE_KEY. INVERT_MATCH меняет итоговое решение на противоположное.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RegexIterator::accept(): bool
Результатbool: решение фильтра; в преобразующих режимах true также означает, что current() содержит преобразованный результат.
Ошибки и особые значенияНекорректные данные для строкового преобразования и ошибка регулярного выражения не являются «обычным false»; валидируйте pattern при создании.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Есть две строковые задачи: распознать расширение файла в значении и распознать служебный префикс в ключе. Обе действительно относятся к форме текста.

Отобрать изображения по значению и исключить черновики по ключуСамостоятельный пример
<?php
declare(strict_types=1);

$images = new RegexIterator(
    new ArrayIterator(['notes.txt', 'PHOTO.JPG', 'icon.png']),
    '/\.(?:jpe?g|png)$/i'
);
foreach ($images as $name) {
    echo $name, "\n";
}

$published = new RegexIterator(
    new ArrayIterator([
        'draft-1' => 'A',
        'order-2' => 'B',
        'draft-3' => 'C',
    ]),
    '/^draft-/'
);
$published->setFlags(RegexIterator::USE_KEY | RegexIterator::INVERT_MATCH);
echo 'flags=', $published->getFlags(),
    '; regex=', $published->getRegex(), "\n";
foreach ($published as $key => $value) {
    echo "$key=$value\n";
}
Ожидаемый результат
PHOTO.JPG
icon.png
flags=3; regex=/^draft-/
order-2=B

Стандартный MATCH оставил совпавшие значения; модификатор i отключил зависимость от регистра. Во втором фильтре USE_KEY перенёс проверку на ключ, INVERT_MATCH инвертировал решение, а | объединил оба флага. Для статуса заказа из отдельного поля лучше callback со строгим сравнением, а не regex.

Скачать самостоятельный пример с fixtures, результатом и README

Старые коды order-N надо показать как ID:N, а заголовок не является кодом.

Нормализовать только совпавшие коды заказовСамостоятельный пример
<?php
declare(strict_types=1);

$codes = new RegexIterator(
    new ArrayIterator(['header', 'order-17', 'order-25']),
    '/^order-(\d+)$/',
    RegexIterator::REPLACE
);
$codes->replacement = 'ID:$1';

foreach ($codes as $key => $code) {
    echo "$key:$code\n";
}
Ожидаемый результат
1:ID:17
2:ID:25

REPLACE выполнил preg_replace() и вернул преобразованные совпавшие элементы с исходными ключами. header исчез: RegexIterator остаётся фильтром и не обещает сохранить несовпавшие строки. Если нужен map, сохраняющий каждый элемент, используйте обычный цикл или array_map(). Официальная документация помечает REPLACE как реализованный не полностью, поэтому критичный код требует теста целевой версии.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RegexIterator::accept

(PHP 5 >= 5.2.0, PHP 7, PHP 8) RegexIterator::accept — Get accept status

Description

public function RegexIterator::accept(): bool

Matches (string) RegexIterator::current() (or RegexIterator::key() if the RegexIterator::USE_KEY flag is set) against the regular expression.

Parameters

This function has no parameters.

Return Values

true if a match, false otherwise.

See Also

RegexIterator constants

RegexIterator::setFlags() - Sets the flags

Связанные карточки: RegexIterator::__construct, CallbackFilterIterator::accept.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RegexIterator::__constructСоздать строковый фильтр с pattern, режимом, flags и pregFlags

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RegexIterator::__construct(Iterator $iterator, string $pattern, int $mode = RegexIterator::MATCH, int $flags = 0, int $pregFlags = 0)

__construct() связывает Iterator с регулярным выражением. mode определяет форму результата, flags — выбор key/current и инверсию, pregFlags — детали preg_match/preg_match_all/preg_split.

ПараметрЧто означает в задаче
iteratorIterator строковых значений либо ключей; данные не копируются.
patternPCRE-выражение с разделителями и модификаторами, например /\.png$/i.
modeОдна константа MATCH, GET_MATCH, ALL_MATCHES, SPLIT или REPLACE.
flagsБитовая маска USE_KEY и/или INVERT_MATCH.
pregFlagsФлаги конкретной preg-функции; допустимость зависит от mode.
Часть контрактаЧто важно
Сигнатураpublic function RegexIterator::__construct(Iterator $iterator, string $pattern, int $mode = RegexIterator::MATCH, int $flags = 0, int $pregFlags = 0)
РезультатКонструктор не возвращает прикладное значение; new создаёт ленивый фильтр.
Ошибки и особые значенияНекорректный pattern вызывает InvalidArgumentException. Неверный тип параметра вызывает TypeError; неподдерживаемое значение режима — ValueError/ошибка целевой версии.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Есть две строковые задачи: распознать расширение файла в значении и распознать служебный префикс в ключе. Обе действительно относятся к форме текста.

Отобрать изображения по значению и исключить черновики по ключуСамостоятельный пример
<?php
declare(strict_types=1);

$images = new RegexIterator(
    new ArrayIterator(['notes.txt', 'PHOTO.JPG', 'icon.png']),
    '/\.(?:jpe?g|png)$/i'
);
foreach ($images as $name) {
    echo $name, "\n";
}

$published = new RegexIterator(
    new ArrayIterator([
        'draft-1' => 'A',
        'order-2' => 'B',
        'draft-3' => 'C',
    ]),
    '/^draft-/'
);
$published->setFlags(RegexIterator::USE_KEY | RegexIterator::INVERT_MATCH);
echo 'flags=', $published->getFlags(),
    '; regex=', $published->getRegex(), "\n";
foreach ($published as $key => $value) {
    echo "$key=$value\n";
}
Ожидаемый результат
PHOTO.JPG
icon.png
flags=3; regex=/^draft-/
order-2=B

Стандартный MATCH оставил совпавшие значения; модификатор i отключил зависимость от регистра. Во втором фильтре USE_KEY перенёс проверку на ключ, INVERT_MATCH инвертировал решение, а | объединил оба флага. Для статуса заказа из отдельного поля лучше callback со строгим сравнением, а не regex.

Скачать самостоятельный пример с fixtures, результатом и README

Старая строка журнала содержит номер заказа внутри текста. Нужно получить первое совпадение и место, с которого начинается захваченная группа.

Извлечь номер заказа и позицию совпаденияСамостоятельный пример
<?php
declare(strict_types=1);

$orders = new RegexIterator(
    new ArrayIterator(['order #104 costs 3500', 'broken record']),
    '/order #(?<id>\d+)/'
);
$orders->setMode(RegexIterator::GET_MATCH);
$orders->setPregFlags(PREG_OFFSET_CAPTURE);

foreach ($orders as $match) {
    echo 'id=', $match['id'][0],
        '; offset=', $match['id'][1], "\n";
}
Ожидаемый результат
id=104; offset=7

GET_MATCH заменил current() массивом результата preg_match(). Именованная группа id дала понятный ключ. PREG_OFFSET_CAPTURE превратил каждое совпадение в пару [текст, смещение]. broken record не совпал и не попал в обход.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RegexIterator::__construct

(PHP 5 >= 5.2.0, PHP 7, PHP 8) RegexIterator::__construct — Create a new RegexIterator

Description

public function RegexIterator::__construct(    Iterator $iterator,    string $pattern,    int $mode = RegexIterator::MATCH,    int $flags = 0,    int $pregFlags = 0)

Create a new RegexIterator which filters an Iterator using a regular expression.

Parameters

iterator

The iterator to apply this regex filter to.

pattern

The regular expression to match.

mode

Operation mode, see RegexIterator::setMode() for a list of modes.

flags

Special flags, see RegexIterator::setFlags() for a list of available flags.

pregFlags

The regular expression flags. These flags depend on the operation mode parameter:

RegexIterator preg_flags

operation mode available flags

RegexIterator::ALL_MATCHES

See preg_match_all().

RegexIterator::GET_MATCH

See preg_match().

RegexIterator::MATCH

See preg_match().

RegexIterator::REPLACE

none.

RegexIterator::SPLIT

See preg_split().

Errors/Exceptions

Throws an InvalidArgumentException if the pattern argument is invalid.

See Also

preg_match() - Perform a regular expression match

preg_match_all() - Perform a global regular expression match

preg_replace() - Perform a regular expression search and replace

preg_split() - Split string by a regular expression

Связанные карточки: RegexIterator::setMode, CallbackFilterIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RegexIterator::getFlagsПрочитать маску USE_KEY и INVERT_MATCH

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RegexIterator::getFlags(): int

getFlags() возвращает битовую маску специальных флагов RegexIterator. Это другая настройка, чем operation mode и pregFlags.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RegexIterator::getFlags(): int
Результатint: 0 либо комбинация USE_KEY/INVERT_MATCH.
Ошибки и особые значенияМетод сам не обнаруживает логическую ошибку выбора key вместо current; это видно только по результату сопоставления.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Есть две строковые задачи: распознать расширение файла в значении и распознать служебный префикс в ключе. Обе действительно относятся к форме текста.

Отобрать изображения по значению и исключить черновики по ключуСамостоятельный пример
<?php
declare(strict_types=1);

$images = new RegexIterator(
    new ArrayIterator(['notes.txt', 'PHOTO.JPG', 'icon.png']),
    '/\.(?:jpe?g|png)$/i'
);
foreach ($images as $name) {
    echo $name, "\n";
}

$published = new RegexIterator(
    new ArrayIterator([
        'draft-1' => 'A',
        'order-2' => 'B',
        'draft-3' => 'C',
    ]),
    '/^draft-/'
);
$published->setFlags(RegexIterator::USE_KEY | RegexIterator::INVERT_MATCH);
echo 'flags=', $published->getFlags(),
    '; regex=', $published->getRegex(), "\n";
foreach ($published as $key => $value) {
    echo "$key=$value\n";
}
Ожидаемый результат
PHOTO.JPG
icon.png
flags=3; regex=/^draft-/
order-2=B

Стандартный MATCH оставил совпавшие значения; модификатор i отключил зависимость от регистра. Во втором фильтре USE_KEY перенёс проверку на ключ, INVERT_MATCH инвертировал решение, а | объединил оба флага. Для статуса заказа из отдельного поля лучше callback со строгим сравнением, а не regex.

Скачать самостоятельный пример с fixtures, результатом и README

Конфигуратор создаёт объект раньше, чем пользователь выбирает операцию. Нужно явно прочитать и изменить режим, специальные флаги и preg-флаги.

Переключить созданный фильтр из MATCH в SPLIT и проверить состояниеСамостоятельный пример
<?php
declare(strict_types=1);

$tokens = new RegexIterator(
    new ArrayIterator(['A1 B2', 'none']),
    '/\s+/',
    RegexIterator::MATCH
);

echo 'before=', $tokens->getMode(),
    '; regex=', $tokens->getRegex(),
    '; flags=', $tokens->getFlags(),
    '; preg=', $tokens->getPregFlags(), "\n";

$tokens->setMode(RegexIterator::SPLIT);
$tokens->setPregFlags(PREG_SPLIT_NO_EMPTY);
$tokens->setFlags(0);

echo 'after=', $tokens->getMode(),
    '; flags=', $tokens->getFlags(),
    '; preg=', $tokens->getPregFlags(), "\n";
foreach ($tokens as $parts) {
    echo implode('|', $parts), "\n";
}
Ожидаемый результат
before=0; regex=/\s+/; flags=0; preg=0
after=3; flags=0; preg=1
A1|B2

Геттеры показали исходные MATCH=0, flags=0 и pregFlags=0. Сеттеры заменили эти значения, после чего current() стал массивом частей. Значения режимов — взаимоисключающий выбор, а не битовая маска; проверяйте равенством, не оператором &.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RegexIterator::getFlags

(PHP 5 >= 5.2.0, PHP 7, PHP 8) RegexIterator::getFlags — Get flags

Description

public function RegexIterator::getFlags(): int

Returns the flags, see RegexIterator::setFlags() for a list of available flags.

Parameters

This function has no parameters.

Return Values

Returns the set flags.

See Also

RegexIterator::setFlags() - Sets the flags

Связанные карточки: RegexIterator::setFlags, RegexIterator::getMode.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RegexIterator::getModeПрочитать один действующий режим MATCH/GET_MATCH/ALL_MATCHES/SPLIT/REPLACE

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RegexIterator::getMode(): int

getMode() сообщает, какую форму current() создаёт RegexIterator. Это одно взаимоисключающее значение, а не набор битов.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RegexIterator::getMode(): int
Результатint: одна из пяти констант режима.
Ошибки и особые значенияЧисло без сравнения с именованной константой плохо объясняет форму результата.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Импорт старого поля хранит теги с несколькими видами разделителей. Требуется массив непустых частей.

Разделить строку тегов по пробелам, запятым и точкам с запятойСамостоятельный пример
<?php
declare(strict_types=1);

$lines = new RegexIterator(
    new ArrayIterator(['php, spl; iterators', 'single']),
    '/[\s,;]+/',
    RegexIterator::SPLIT
);
$lines->setPregFlags(PREG_SPLIT_NO_EMPTY);

echo 'mode=', $lines->getMode(),
    '; preg-flags=', $lines->getPregFlags(), "\n";
foreach ($lines as $parts) {
    echo implode('|', $parts), "\n";
}
Ожидаемый результат
mode=3; preg-flags=1
php|spl|iterators

SPLIT возвращает результат preg_split() для совпавших строк. PREG_SPLIT_NO_EMPTY убрал пустые части. Строка single не содержит разделителя и поэтому не была принята итератором; если её тоже нужно сохранить как один тег, обычный цикл с preg_split() для каждой строки выразит требование точнее.

Скачать самостоятельный пример с fixtures, результатом и README

Конфигуратор создаёт объект раньше, чем пользователь выбирает операцию. Нужно явно прочитать и изменить режим, специальные флаги и preg-флаги.

Переключить созданный фильтр из MATCH в SPLIT и проверить состояниеСамостоятельный пример
<?php
declare(strict_types=1);

$tokens = new RegexIterator(
    new ArrayIterator(['A1 B2', 'none']),
    '/\s+/',
    RegexIterator::MATCH
);

echo 'before=', $tokens->getMode(),
    '; regex=', $tokens->getRegex(),
    '; flags=', $tokens->getFlags(),
    '; preg=', $tokens->getPregFlags(), "\n";

$tokens->setMode(RegexIterator::SPLIT);
$tokens->setPregFlags(PREG_SPLIT_NO_EMPTY);
$tokens->setFlags(0);

echo 'after=', $tokens->getMode(),
    '; flags=', $tokens->getFlags(),
    '; preg=', $tokens->getPregFlags(), "\n";
foreach ($tokens as $parts) {
    echo implode('|', $parts), "\n";
}
Ожидаемый результат
before=0; regex=/\s+/; flags=0; preg=0
after=3; flags=0; preg=1
A1|B2

Геттеры показали исходные MATCH=0, flags=0 и pregFlags=0. Сеттеры заменили эти значения, после чего current() стал массивом частей. Значения режимов — взаимоисключающий выбор, а не битовая маска; проверяйте равенством, не оператором &.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RegexIterator::getMode

(PHP 5 >= 5.2.0, PHP 7, PHP 8) RegexIterator::getMode — Returns operation mode

Description

public function RegexIterator::getMode(): int

Returns the operation mode, see RegexIterator::setMode() for the list of operation modes.

Parameters

This function has no parameters.

Return Values

Returns the operation mode.

See Also

RegexIterator::setMode() - Sets the operation mode

Связанные карточки: RegexIterator::setMode, RegexIterator::getPregFlags.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RegexIterator::getPregFlagsПрочитать флаги preg-функции, меняющие структуру совпадений/частей

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RegexIterator::getPregFlags(): int

getPregFlags() возвращает настройки preg_match(), preg_match_all() либо preg_split() для текущего режима.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RegexIterator::getPregFlags(): int
Результатint: битовая маска PREG_*; допустимый набор зависит от mode.
Ошибки и особые значенияФлаг, недопустимый для выбранного режима, может вызвать ValueError либо неожиданное представление в целевой версии.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Импорт старого поля хранит теги с несколькими видами разделителей. Требуется массив непустых частей.

Разделить строку тегов по пробелам, запятым и точкам с запятойСамостоятельный пример
<?php
declare(strict_types=1);

$lines = new RegexIterator(
    new ArrayIterator(['php, spl; iterators', 'single']),
    '/[\s,;]+/',
    RegexIterator::SPLIT
);
$lines->setPregFlags(PREG_SPLIT_NO_EMPTY);

echo 'mode=', $lines->getMode(),
    '; preg-flags=', $lines->getPregFlags(), "\n";
foreach ($lines as $parts) {
    echo implode('|', $parts), "\n";
}
Ожидаемый результат
mode=3; preg-flags=1
php|spl|iterators

SPLIT возвращает результат preg_split() для совпавших строк. PREG_SPLIT_NO_EMPTY убрал пустые части. Строка single не содержит разделителя и поэтому не была принята итератором; если её тоже нужно сохранить как один тег, обычный цикл с preg_split() для каждой строки выразит требование точнее.

Скачать самостоятельный пример с fixtures, результатом и README

Конфигуратор создаёт объект раньше, чем пользователь выбирает операцию. Нужно явно прочитать и изменить режим, специальные флаги и preg-флаги.

Переключить созданный фильтр из MATCH в SPLIT и проверить состояниеСамостоятельный пример
<?php
declare(strict_types=1);

$tokens = new RegexIterator(
    new ArrayIterator(['A1 B2', 'none']),
    '/\s+/',
    RegexIterator::MATCH
);

echo 'before=', $tokens->getMode(),
    '; regex=', $tokens->getRegex(),
    '; flags=', $tokens->getFlags(),
    '; preg=', $tokens->getPregFlags(), "\n";

$tokens->setMode(RegexIterator::SPLIT);
$tokens->setPregFlags(PREG_SPLIT_NO_EMPTY);
$tokens->setFlags(0);

echo 'after=', $tokens->getMode(),
    '; flags=', $tokens->getFlags(),
    '; preg=', $tokens->getPregFlags(), "\n";
foreach ($tokens as $parts) {
    echo implode('|', $parts), "\n";
}
Ожидаемый результат
before=0; regex=/\s+/; flags=0; preg=0
after=3; flags=0; preg=1
A1|B2

Геттеры показали исходные MATCH=0, flags=0 и pregFlags=0. Сеттеры заменили эти значения, после чего current() стал массивом частей. Значения режимов — взаимоисключающий выбор, а не битовая маска; проверяйте равенством, не оператором &.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RegexIterator::getPregFlags

(PHP 5 >= 5.2.0, PHP 7, PHP 8) RegexIterator::getPregFlags — Returns the regular expression flags

Description

public function RegexIterator::getPregFlags(): int

Returns the regular expression flags, see RegexIterator::__construct() for the list of flags.

Parameters

This function has no parameters.

Return Values

Returns a bitmask of the regular expression flags.

See Also

RegexIterator::setPregFlags() - Sets the regular expression flags

Связанные карточки: RegexIterator::setPregFlags, RegexIterator::getMode.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RegexIterator::getRegexПолучить исходную строку pattern вместе с разделителями и модификаторами

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RegexIterator::getRegex(): string

getRegex() возвращает ровно шаблон, переданный конструктору, например /^draft-/ или /\s+/.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RegexIterator::getRegex(): string
Результатstring: действующее регулярное выражение.
Ошибки и особые значенияВозвращённая строка не доказывает, что pattern подходит вашим данным; ошибки и семантику проверяют отдельными тестами.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Есть две строковые задачи: распознать расширение файла в значении и распознать служебный префикс в ключе. Обе действительно относятся к форме текста.

Отобрать изображения по значению и исключить черновики по ключуСамостоятельный пример
<?php
declare(strict_types=1);

$images = new RegexIterator(
    new ArrayIterator(['notes.txt', 'PHOTO.JPG', 'icon.png']),
    '/\.(?:jpe?g|png)$/i'
);
foreach ($images as $name) {
    echo $name, "\n";
}

$published = new RegexIterator(
    new ArrayIterator([
        'draft-1' => 'A',
        'order-2' => 'B',
        'draft-3' => 'C',
    ]),
    '/^draft-/'
);
$published->setFlags(RegexIterator::USE_KEY | RegexIterator::INVERT_MATCH);
echo 'flags=', $published->getFlags(),
    '; regex=', $published->getRegex(), "\n";
foreach ($published as $key => $value) {
    echo "$key=$value\n";
}
Ожидаемый результат
PHOTO.JPG
icon.png
flags=3; regex=/^draft-/
order-2=B

Стандартный MATCH оставил совпавшие значения; модификатор i отключил зависимость от регистра. Во втором фильтре USE_KEY перенёс проверку на ключ, INVERT_MATCH инвертировал решение, а | объединил оба флага. Для статуса заказа из отдельного поля лучше callback со строгим сравнением, а не regex.

Скачать самостоятельный пример с fixtures, результатом и README

Конфигуратор создаёт объект раньше, чем пользователь выбирает операцию. Нужно явно прочитать и изменить режим, специальные флаги и preg-флаги.

Переключить созданный фильтр из MATCH в SPLIT и проверить состояниеСамостоятельный пример
<?php
declare(strict_types=1);

$tokens = new RegexIterator(
    new ArrayIterator(['A1 B2', 'none']),
    '/\s+/',
    RegexIterator::MATCH
);

echo 'before=', $tokens->getMode(),
    '; regex=', $tokens->getRegex(),
    '; flags=', $tokens->getFlags(),
    '; preg=', $tokens->getPregFlags(), "\n";

$tokens->setMode(RegexIterator::SPLIT);
$tokens->setPregFlags(PREG_SPLIT_NO_EMPTY);
$tokens->setFlags(0);

echo 'after=', $tokens->getMode(),
    '; flags=', $tokens->getFlags(),
    '; preg=', $tokens->getPregFlags(), "\n";
foreach ($tokens as $parts) {
    echo implode('|', $parts), "\n";
}
Ожидаемый результат
before=0; regex=/\s+/; flags=0; preg=0
after=3; flags=0; preg=1
A1|B2

Геттеры показали исходные MATCH=0, flags=0 и pregFlags=0. Сеттеры заменили эти значения, после чего current() стал массивом частей. Значения режимов — взаимоисключающий выбор, а не битовая маска; проверяйте равенством, не оператором &.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RegexIterator::getRegex

(PHP 5 >= 5.4.0, PHP 7, PHP 8) RegexIterator::getRegex — Returns current regular expression

Description

public function RegexIterator::getRegex(): string

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

Связанные карточки: RegexIterator::__construct, RegexIterator::accept.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RegexIterator::setFlagsПолностью заменить маску USE_KEY/INVERT_MATCH

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RegexIterator::setFlags(int $flags): void

setFlags() выбирает, сопоставлять current или key, и нужно ли инвертировать решение accept().

ПараметрЧто означает в задаче
flagsНовая полная битовая маска USE_KEY/INVERT_MATCH.
Часть контрактаЧто важно
Сигнатураpublic function RegexIterator::setFlags(int $flags): void
Результатvoid: новое значение читают getFlags(), а эффект виден при следующем обходе.
Ошибки и особые значенияНеподходящий тип вызывает TypeError; неизвестные биты не следует считать переносимым поведением.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Есть две строковые задачи: распознать расширение файла в значении и распознать служебный префикс в ключе. Обе действительно относятся к форме текста.

Отобрать изображения по значению и исключить черновики по ключуСамостоятельный пример
<?php
declare(strict_types=1);

$images = new RegexIterator(
    new ArrayIterator(['notes.txt', 'PHOTO.JPG', 'icon.png']),
    '/\.(?:jpe?g|png)$/i'
);
foreach ($images as $name) {
    echo $name, "\n";
}

$published = new RegexIterator(
    new ArrayIterator([
        'draft-1' => 'A',
        'order-2' => 'B',
        'draft-3' => 'C',
    ]),
    '/^draft-/'
);
$published->setFlags(RegexIterator::USE_KEY | RegexIterator::INVERT_MATCH);
echo 'flags=', $published->getFlags(),
    '; regex=', $published->getRegex(), "\n";
foreach ($published as $key => $value) {
    echo "$key=$value\n";
}
Ожидаемый результат
PHOTO.JPG
icon.png
flags=3; regex=/^draft-/
order-2=B

Стандартный MATCH оставил совпавшие значения; модификатор i отключил зависимость от регистра. Во втором фильтре USE_KEY перенёс проверку на ключ, INVERT_MATCH инвертировал решение, а | объединил оба флага. Для статуса заказа из отдельного поля лучше callback со строгим сравнением, а не regex.

Скачать самостоятельный пример с fixtures, результатом и README

Конфигуратор создаёт объект раньше, чем пользователь выбирает операцию. Нужно явно прочитать и изменить режим, специальные флаги и preg-флаги.

Переключить созданный фильтр из MATCH в SPLIT и проверить состояниеСамостоятельный пример
<?php
declare(strict_types=1);

$tokens = new RegexIterator(
    new ArrayIterator(['A1 B2', 'none']),
    '/\s+/',
    RegexIterator::MATCH
);

echo 'before=', $tokens->getMode(),
    '; regex=', $tokens->getRegex(),
    '; flags=', $tokens->getFlags(),
    '; preg=', $tokens->getPregFlags(), "\n";

$tokens->setMode(RegexIterator::SPLIT);
$tokens->setPregFlags(PREG_SPLIT_NO_EMPTY);
$tokens->setFlags(0);

echo 'after=', $tokens->getMode(),
    '; flags=', $tokens->getFlags(),
    '; preg=', $tokens->getPregFlags(), "\n";
foreach ($tokens as $parts) {
    echo implode('|', $parts), "\n";
}
Ожидаемый результат
before=0; regex=/\s+/; flags=0; preg=0
after=3; flags=0; preg=1
A1|B2

Геттеры показали исходные MATCH=0, flags=0 и pregFlags=0. Сеттеры заменили эти значения, после чего current() стал массивом частей. Значения режимов — взаимоисключающий выбор, а не битовая маска; проверяйте равенством, не оператором &.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RegexIterator::setFlags

(PHP 5 >= 5.2.0, PHP 7, PHP 8) RegexIterator::setFlags — Sets the flags

Description

public function RegexIterator::setFlags(int $flags): void

Sets the flags.

Parameters

flags

The flags to set, a bitmask of class constants.

The available flags are listed below. The actual meanings of these flags are described in the predefined constants.

RegexIterator flags

value constant

1

RegexIterator::USE_KEY

Return Values

No value is returned.

See Also

RegexIterator::getFlags() - Get flags

Связанные карточки: RegexIterator::getFlags, RegexIterator::accept.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RegexIterator::setModeЗаменить форму результата на один из пяти режимов

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RegexIterator::setMode(int $mode): void

setMode() переключает MATCH, GET_MATCH, ALL_MATCHES, SPLIT или REPLACE. После переключения меняется тип current(): исходная строка, массив совпадений/частей либо заменённая строка.

ПараметрЧто означает в задаче
modeОдна константа режима; не комбинируется оператором |.
Часть контрактаЧто важно
Сигнатураpublic function RegexIterator::setMode(int $mode): void
Результатvoid: режим читают getMode(); новое представление появляется при обходе.
Ошибки и особые значенияНедопустимое значение вызывает ValueError/ошибку целевой версии. Код, ожидающий string, сломается после перехода к режиму с array.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Старая строка журнала содержит номер заказа внутри текста. Нужно получить первое совпадение и место, с которого начинается захваченная группа.

Извлечь номер заказа и позицию совпаденияСамостоятельный пример
<?php
declare(strict_types=1);

$orders = new RegexIterator(
    new ArrayIterator(['order #104 costs 3500', 'broken record']),
    '/order #(?<id>\d+)/'
);
$orders->setMode(RegexIterator::GET_MATCH);
$orders->setPregFlags(PREG_OFFSET_CAPTURE);

foreach ($orders as $match) {
    echo 'id=', $match['id'][0],
        '; offset=', $match['id'][1], "\n";
}
Ожидаемый результат
id=104; offset=7

GET_MATCH заменил current() массивом результата preg_match(). Именованная группа id дала понятный ключ. PREG_OFFSET_CAPTURE превратил каждое совпадение в пару [текст, смещение]. broken record не совпал и не попал в обход.

Скачать самостоятельный пример с fixtures, результатом и README

Конфигуратор создаёт объект раньше, чем пользователь выбирает операцию. Нужно явно прочитать и изменить режим, специальные флаги и preg-флаги.

Переключить созданный фильтр из MATCH в SPLIT и проверить состояниеСамостоятельный пример
<?php
declare(strict_types=1);

$tokens = new RegexIterator(
    new ArrayIterator(['A1 B2', 'none']),
    '/\s+/',
    RegexIterator::MATCH
);

echo 'before=', $tokens->getMode(),
    '; regex=', $tokens->getRegex(),
    '; flags=', $tokens->getFlags(),
    '; preg=', $tokens->getPregFlags(), "\n";

$tokens->setMode(RegexIterator::SPLIT);
$tokens->setPregFlags(PREG_SPLIT_NO_EMPTY);
$tokens->setFlags(0);

echo 'after=', $tokens->getMode(),
    '; flags=', $tokens->getFlags(),
    '; preg=', $tokens->getPregFlags(), "\n";
foreach ($tokens as $parts) {
    echo implode('|', $parts), "\n";
}
Ожидаемый результат
before=0; regex=/\s+/; flags=0; preg=0
after=3; flags=0; preg=1
A1|B2

Геттеры показали исходные MATCH=0, flags=0 и pregFlags=0. Сеттеры заменили эти значения, после чего current() стал массивом частей. Значения режимов — взаимоисключающий выбор, а не битовая маска; проверяйте равенством, не оператором &.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RegexIterator::setMode

(PHP 5 >= 5.2.0, PHP 7, PHP 8) RegexIterator::setMode — Sets the operation mode

Description

public function RegexIterator::setMode(int $mode): void

Sets the operation mode.

Parameters

mode

The operation mode.

The available modes are listed below. The actual meanings of these modes are described in the predefined constants.

RegexIterator modes

value constant

0

RegexIterator::MATCH

1

RegexIterator::GET_MATCH

2

RegexIterator::ALL_MATCHES

3

RegexIterator::SPLIT

4

RegexIterator::REPLACE

Return Values

No value is returned.

See Also

RegexIterator::getMode() - Returns operation mode

Связанные карточки: RegexIterator::getMode, RegexIterator::setPregFlags.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RegexIterator::setPregFlagsЗадать PREG_* флаги для структуры результата текущего режима

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RegexIterator::setPregFlags(int $pregFlags): void

setPregFlags() передаёт настройки соответствующей preg-функции: например, PREG_OFFSET_CAPTURE для GET_MATCH или PREG_SPLIT_NO_EMPTY для SPLIT.

ПараметрЧто означает в задаче
pregFlagsНовая PREG_* маска, допустимая для текущего режима.
Часть контрактаЧто важно
Сигнатураpublic function RegexIterator::setPregFlags(int $pregFlags): void
Результатvoid: новое значение читает getPregFlags(), а current() получает другую структуру.
Ошибки и особые значенияНе каждый PREG_* допустим во всех режимах; несовместимая маска может вызвать ValueError.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Старая строка журнала содержит номер заказа внутри текста. Нужно получить первое совпадение и место, с которого начинается захваченная группа.

Извлечь номер заказа и позицию совпаденияСамостоятельный пример
<?php
declare(strict_types=1);

$orders = new RegexIterator(
    new ArrayIterator(['order #104 costs 3500', 'broken record']),
    '/order #(?<id>\d+)/'
);
$orders->setMode(RegexIterator::GET_MATCH);
$orders->setPregFlags(PREG_OFFSET_CAPTURE);

foreach ($orders as $match) {
    echo 'id=', $match['id'][0],
        '; offset=', $match['id'][1], "\n";
}
Ожидаемый результат
id=104; offset=7

GET_MATCH заменил current() массивом результата preg_match(). Именованная группа id дала понятный ключ. PREG_OFFSET_CAPTURE превратил каждое совпадение в пару [текст, смещение]. broken record не совпал и не попал в обход.

Скачать самостоятельный пример с fixtures, результатом и README

Импорт старого поля хранит теги с несколькими видами разделителей. Требуется массив непустых частей.

Разделить строку тегов по пробелам, запятым и точкам с запятойСамостоятельный пример
<?php
declare(strict_types=1);

$lines = new RegexIterator(
    new ArrayIterator(['php, spl; iterators', 'single']),
    '/[\s,;]+/',
    RegexIterator::SPLIT
);
$lines->setPregFlags(PREG_SPLIT_NO_EMPTY);

echo 'mode=', $lines->getMode(),
    '; preg-flags=', $lines->getPregFlags(), "\n";
foreach ($lines as $parts) {
    echo implode('|', $parts), "\n";
}
Ожидаемый результат
mode=3; preg-flags=1
php|spl|iterators

SPLIT возвращает результат preg_split() для совпавших строк. PREG_SPLIT_NO_EMPTY убрал пустые части. Строка single не содержит разделителя и поэтому не была принята итератором; если её тоже нужно сохранить как один тег, обычный цикл с preg_split() для каждой строки выразит требование точнее.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RegexIterator::setPregFlags

(PHP 5 >= 5.2.0, PHP 7, PHP 8) RegexIterator::setPregFlags — Sets the regular expression flags

Description

public function RegexIterator::setPregFlags(int $pregFlags): void

Sets the regular expression flags.

Parameters

pregFlags

The regular expression flags. See RegexIterator::__construct() for an overview of available flags.

Return Values

No value is returned.

See Also

RegexIterator::getPregFlags() - Returns the regular expression flags

Связанные карточки: RegexIterator::getPregFlags, RegexIterator::setMode.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ParentIterator::acceptParentIterator::accept: Метод отвечает за один текущий узел и не преобразует его значение. Работа с родительских узлов.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function ParentIterator::accept(): bool

ParentIterator::accept. Метод отвечает за один текущий узел и не преобразует его значение. После rewind курсор стоит на первом принятом родителе. accept() повторно сообщает решение фильтра для этого узла. Во второй независимой ситуации: В конфигурации родителем считается database, потому что его значение можно открыть как следующий уровень. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function ParentIterator::accept(): bool
Результатbool: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Исключение из accept прерывает обход; parent нельзя отвергать, если подходящие листья могут быть глубже.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

После rewind курсор стоит на первом принятом родителе. accept() повторно сообщает решение фильтра для этого узла.

Проверить, почему текущая категория принятаСамостоятельный пример
<?php
$parents = new ParentIterator(new RecursiveArrayIterator([
    'hardware' => ['cpu' => 4],
    'delivery' => 'today',
]));
$parents->rewind();
echo 'Категория: ', $parents->key(), "\n";
echo 'accept: ', $parents->accept() ? 'true' : 'false', "\n";
Ожидаемый результат
Категория: hardware
accept: true

true относится к текущему hardware: у него есть дочерний массив. Метод не возвращает сам массив.

Скачать самостоятельный пример с fixtures, результатом и README

В конфигурации родителем считается database, потому что его значение можно открыть как следующий уровень.

Проверить принятие раздела конфигурацииСамостоятельный пример
<?php
$parents = new ParentIterator(new RecursiveArrayIterator([
    'database' => ['host' => 'db.local'],
    'debug' => false,
]));
$parents->rewind();
echo $parents->key(), ': ', $parents->accept() ? 'можно войти' : 'лист', "\n";
Ожидаемый результат
database: можно войти

accept() выражает структурное правило «есть дети», а не бизнес-оценку корректности настроек.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

ParentIterator::accept

(PHP 5 >= 5.1.0, PHP 7, PHP 8) ParentIterator::accept — Determines acceptability

Description

public function ParentIterator::accept(): bool

Determines if the current element has children.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

true if the current element is acceptable, otherwise false.

See Also

ParentIterator::hasChildren() - Check whether the inner iterator's current element has children

FilterIterator::accept() - Check whether the current element of the iterator is acceptable

Связанные карточки: ParentIterator::__construct, ParentIterator::getChildren, ParentIterator::hasChildren, ParentIterator::next.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ParentIterator::__constructParentIterator::__construct: Конструктор только связывает источник и режимы Работа с родительских узлов.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function ParentIterator::__construct(RecursiveIterator $iterator)

ParentIterator::__construct. Конструктор только связывает источник и режимы; фактическое чтение начинается при rewind/foreach. Конструктор получает готовый RecursiveIterator и сохраняет его как источник. Сам исходный массив не копируется в новый плоский список. Во второй независимой ситуации: Здесь ParentIterator строится прямо вокруг RecursiveArrayIterator: слева объект-фильтр, внутри — источник дерева. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
iteratorРекурсивный источник из сигнатуры. Объект не копируется: внешний класс управляет тем же курсором и вызывает его hasChildren()/getChildren().
Часть контрактаЧто важно
Сигнатураpublic function ParentIterator::__construct(RecursiveIterator $iterator)
РезультатКонструктор не возвращает прикладное значение; выражение new создаёт объект, который затем сохраняется в переменной.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Точный тип возврата, особые значения и изменения по версиям перечислены в таблице и полном официальном контракте.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Конструктор получает готовый RecursiveIterator и сохраняет его как источник. Сам исходный массив не копируется в новый плоский список.

Собрать навигацию только из раскрываемых группСамостоятельный пример
<?php
$source = new RecursiveArrayIterator([
    'orders' => ['new' => 12],
    'logout' => '/logout',
    'reports' => ['sales' => '/sales'],
]);
$groups = new ParentIterator($source);
echo implode(', ', array_keys(iterator_to_array($groups))), "\n";
Ожидаемый результат
orders, reports

В результате обходятся только orders и reports — элементы, имеющие дочерний уровень.

Скачать самостоятельный пример с fixtures, результатом и README

Здесь ParentIterator строится прямо вокруг RecursiveArrayIterator: слева объект-фильтр, внутри — источник дерева.

Выбрать контейнеры складских зонСамостоятельный пример
<?php
$zones = new ParentIterator(new RecursiveArrayIterator([
    'A' => ['A-01' => 'болты'],
    'gate' => 'закрыт',
    'B' => ['B-02' => 'кабель'],
]));
foreach ($zones as $zone => $_) {
    echo 'Зона ', $zone, "\n";
}
Ожидаемый результат
Зона A
Зона B

Конструктор не запускает обход. Строки появляются только в foreach, когда курсор действительно читается.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

ParentIterator::__construct

(PHP 5 >= 5.1.0, PHP 7, PHP 8) ParentIterator::__construct — Constructs a ParentIterator

Description

public function ParentIterator::__construct(RecursiveIterator $iterator)

Constructs a ParentIterator on an iterator.

WarningThis function is currently not documented; only its argument list is available.

Parameters

iterator

The iterator being constructed upon.

Связанные карточки: ParentIterator::accept, ParentIterator::getChildren, ParentIterator::hasChildren, ParentIterator::next.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ParentIterator::getChildrenParentIterator::getChildren: Метод открывает ровно следующий уровень и возвращает новый рекурсивный итератор. Работа с родительских узлов.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function ParentIterator::getChildren(): ?RecursiveFilterIterator

ParentIterator::getChildren. Метод открывает ровно следующий уровень и возвращает новый рекурсивный итератор. После проверки родителя getChildren() открывает дочерний ParentIterator именно текущей категории. Во второй независимой ситуации: Второй случай читает конфигурацию. Дочерний ParentIterator оставляет вложенный parent server и скрывает leaf enabled. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function ParentIterator::getChildren(): ?RecursiveFilterIterator
Результат?RecursiveFilterIterator: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Сначала проверяйте hasChildren(), если форма данных заранее не гарантирована.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

После проверки родителя getChildren() открывает дочерний ParentIterator именно текущей категории.

Открыть товары текущей категорииСамостоятельный пример
<?php
$parents = new ParentIterator(new RecursiveArrayIterator([
    'lamps' => ['models' => ['desk' => 3, 'floor' => 2], 'sale' => true],
    'status' => 'open',
]));
$parents->rewind();
$children = $parents->getChildren();
foreach ($children as $name => $items) {
    echo $name, ': ', count($items), " моделей\n";
}
Ожидаемый результат
models: 2 моделей

Он продолжает правило класса: models остаётся, потому что имеет детей, а leaf sale скрывается. Чтобы увидеть desk/floor, нужен ещё один getChildren().

Скачать самостоятельный пример с fixtures, результатом и README

Второй случай читает конфигурацию. Дочерний ParentIterator оставляет вложенный parent server и скрывает leaf enabled.

Открыть поля текущего блока настроекСамостоятельный пример
<?php
$parents = new ParentIterator(new RecursiveArrayIterator([
    'mail' => ['server' => ['host' => 'smtp.local', 'port' => 2525], 'enabled' => true],
    'debug' => true,
]));
$parents->rewind();
$children = $parents->getChildren();
echo implode(', ', array_keys(iterator_to_array($children))), "\n";
Ожидаемый результат
server

getChildren() не разворачивает всю глубину и сохраняет семантику «только родители» на следующем уровне.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

ParentIterator::getChildren

(PHP 5 >= 5.1.0, PHP 7, PHP 8) ParentIterator::getChildren — Return the inner iterator's children contained in a ParentIterator

Description

public function ParentIterator::getChildren(): ParentIterator

Get the inner iterator's children contained in a ParentIterator.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

An object.

Связанные карточки: ParentIterator::accept, ParentIterator::__construct, ParentIterator::hasChildren, ParentIterator::next.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ParentIterator::hasChildrenParentIterator::hasChildren: Ответ относится к текущей позиции и не двигает курсор. Работа с родительских узлов.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function ParentIterator::hasChildren(): bool

ParentIterator::hasChildren. Ответ относится к текущей позиции и не двигает курсор. hasChildren() отвечает на вопрос о текущем принятом узле, не двигая курсор и не открывая детей. Во второй независимой ситуации: Маршрут api содержит дочерние маршруты, поэтому фильтр оставляет его и hasChildren() возвращает true. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function ParentIterator::hasChildren(): bool
Результатbool: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. У файлов явно передавайте false, если политика запрещает следовать по символическим ссылкам.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

hasChildren() отвечает на вопрос о текущем принятом узле, не двигая курсор и не открывая детей.

Подтвердить раскрываемую категориюСамостоятельный пример
<?php
$parents = new ParentIterator(new RecursiveArrayIterator([
    'docs' => ['manual' => 'php.pdf'],
    'version' => '1.0',
]));
$parents->rewind();
echo $parents->key(), ': ', $parents->hasChildren() ? 'есть вложения' : 'нет', "\n";
Ожидаемый результат
docs: есть вложения

Для docs ответ true; затем можно безопасно вызывать getChildren().

Скачать самостоятельный пример с fixtures, результатом и README

Маршрут api содержит дочерние маршруты, поэтому фильтр оставляет его и hasChildren() возвращает true.

Проверить родительский узел маршрутовСамостоятельный пример
<?php
$parents = new ParentIterator(new RecursiveArrayIterator([
    'api' => ['orders' => '/api/orders'],
    'health' => '/health',
]));
$parents->rewind();
var_export($parents->hasChildren());
echo "\n";
Ожидаемый результат
true

Метод описывает форму данных. Он не проверяет, доступен ли указанный URL.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

ParentIterator::hasChildren

(PHP 5 >= 5.1.0, PHP 7, PHP 8) ParentIterator::hasChildren — Check whether the inner iterator's current element has children

Description

public function ParentIterator::hasChildren(): bool

Check whether the inner iterator's current element has children.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

Returns true on success or false on failure.

Связанные карточки: ParentIterator::accept, ParentIterator::__construct, ParentIterator::getChildren, ParentIterator::next.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ParentIterator::nextParentIterator::next: Метод меняет состояние курсора и не возвращает следующий элемент как значение. Работа с родительских узлов.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function ParentIterator::next(): void

ParentIterator::next. Метод меняет состояние курсора и не возвращает следующий элемент как значение. next() двигается к следующему принятому родителю и сам пропускает лист notice. Во второй независимой ситуации: В конфигурации next() переходит от database сразу к cache: debug не имеет детей и не входит в результат. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function ParentIterator::next(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Без valid() после продвижения нельзя безопасно читать current/key.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

next() двигается к следующему принятому родителю и сам пропускает лист notice.

Перейти от одной категории к следующейСамостоятельный пример
<?php
$parents = new ParentIterator(new RecursiveArrayIterator([
    'lamps' => ['desk' => 1],
    'notice' => 'sale',
    'cables' => ['usb' => 2],
]));
$parents->rewind();
echo 'Сначала: ', $parents->key(), "\n";
$parents->next();
echo 'Потом: ', $parents->key(), "\n";
Ожидаемый результат
Сначала: lamps
Потом: cables

Курсор после вызова находится на cables. Возвращаемого прикладного значения у next() нет.

Скачать самостоятельный пример с fixtures, результатом и README

В конфигурации next() переходит от database сразу к cache: debug не имеет детей и не входит в результат.

Пропустить одиночную настройку между блокамиСамостоятельный пример
<?php
$parents = new ParentIterator(new RecursiveArrayIterator([
    'database' => ['host' => 'db'],
    'debug' => false,
    'cache' => ['ttl' => 60],
]));
$parents->rewind();
$parents->next();
echo $parents->key(), "\n";
Ожидаемый результат
cache

Если следующего родителя нет, после next() valid() станет false; читать key/current без проверки не следует.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

ParentIterator::next

(PHP 5 >= 5.1.0, PHP 7, PHP 8) ParentIterator::next — Move the iterator forward

Description

public function ParentIterator::next(): void

Moves the iterator forward.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

No value is returned.

Связанные карточки: ParentIterator::accept, ParentIterator::__construct, ParentIterator::getChildren, ParentIterator::hasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

ParentIterator::rewindParentIterator::rewind: Метод заново устанавливает первый доступный элемент всего соответствующего обхода. Работа с родительских узлов.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function ParentIterator::rewind(): void

ParentIterator::rewind. Метод заново устанавливает первый доступный элемент всего соответствующего обхода. rewind() перематывает внутренний итератор и заново ищет первый элемент, который принимает ParentIterator. Во второй независимой ситуации: После первого foreach курсор исчерпан. Явный rewind() запускает повторяемый массивный источник заново. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function ParentIterator::rewind(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Повторяемость наследуется от источника; завершённый Generator не обязан перематываться.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

rewind() перематывает внутренний итератор и заново ищет первый элемент, который принимает ParentIterator.

Вернуться к первой раскрываемой группеСамостоятельный пример
<?php
$parents = new ParentIterator(new RecursiveArrayIterator([
    'orders' => ['new' => 2],
    'users' => ['active' => 8],
]));
$parents->rewind();
$parents->next();
echo 'До возврата: ', $parents->key(), "\n";
$parents->rewind();
echo 'После возврата: ', $parents->key(), "\n";
Ожидаемый результат
До возврата: users
После возврата: orders

Курсор возвращён на orders; массив при этом не пересоздавался.

Скачать самостоятельный пример с fixtures, результатом и README

После первого foreach курсор исчерпан. Явный rewind() запускает повторяемый массивный источник заново.

Повторно начать обход разделов справкиСамостоятельный пример
<?php
$parents = new ParentIterator(new RecursiveArrayIterator([
    'php' => ['arrays' => '/arrays'],
    'linux' => ['shell' => '/shell'],
]));
foreach ($parents as $_) { /* первый проход */ }
$parents->rewind();
echo 'Снова с: ', $parents->key(), "\n";
Ожидаемый результат
Снова с: php

Так можно делать с RecursiveArrayIterator; одноразовый источник не обязан поддерживать повторный проход.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

ParentIterator::rewind

(PHP 5 >= 5.1.0, PHP 7, PHP 8) ParentIterator::rewind — Rewind the iterator

Description

public function ParentIterator::rewind(): void

Rewinds the iterator.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

No value is returned.

Связанные карточки: ParentIterator::accept, ParentIterator::__construct, ParentIterator::getChildren, ParentIterator::hasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveArrayIterator::getChildrenRecursiveArrayIterator::getChildren: Метод открывает ровно следующий уровень и возвращает новый рекурсивный итератор. Работа с вложенного массива.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveArrayIterator::getChildren(): ?RecursiveArrayIterator

RecursiveArrayIterator::getChildren. Метод открывает ровно следующий уровень и возвращает новый рекурсивный итератор. getChildren() вызывается на позиции customer и возвращает новый RecursiveArrayIterator над вложенным массивом. Во второй независимой ситуации: Каждый getChildren() спускает ровно на один уровень: root → app → cache. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveArrayIterator::getChildren(): ?RecursiveArrayIterator
Результат?RecursiveArrayIterator: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Сначала проверяйте hasChildren(), если форма данных заранее не гарантирована.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

getChildren() вызывается на позиции customer и возвращает новый RecursiveArrayIterator над вложенным массивом.

Открыть адрес клиента на один уровеньСамостоятельный пример
<?php
$tree = new RecursiveArrayIterator([
    'customer' => ['name' => 'Ирина', 'city' => 'Тула'],
]);
$tree->rewind();
$children = $tree->getChildren();
foreach ($children as $key => $value) {
    echo $key, '=', $value, "\n";
}
Ожидаемый результат
name=Ирина
city=Тула

Родительский курсор остаётся на customer; дочерний foreach читает name и city.

Скачать самостоятельный пример с fixtures, результатом и README

Каждый getChildren() спускает ровно на один уровень: root → app → cache.

Открыть третий уровень конфигурации по шагамСамостоятельный пример
<?php
$root = new RecursiveArrayIterator([
    'app' => ['cache' => ['driver' => 'file']],
]);
$root->rewind();
$app = $root->getChildren();
$app->rewind();
$cache = $app->getChildren();
echo 'driver=', $cache['driver'], "\n";
Ожидаемый результат
driver=file

Так видна механика рекурсии без магии: автоматический обход позднее будет повторять эти же hasChildren/getChildren.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveArrayIterator::getChildren

(PHP 5 >= 5.1.0, PHP 7, PHP 8) RecursiveArrayIterator::getChildren — Returns an iterator for the current entry if it is an array or an object

Description

public function RecursiveArrayIterator::getChildren(): ?RecursiveArrayIterator

Returns an iterator for the current iterator entry.

Parameters

This function has no parameters.

Return Values

An iterator for the current entry, if it is an array or object; or null on failure.

Errors/Exceptions

An InvalidArgumentException will be thrown if the current entry does not contain an array or an object.

See Also

RecursiveArrayIterator::hasChildren() - Returns whether current entry is an array or an object

Связанные карточки: RecursiveArrayIterator::hasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveArrayIterator::hasChildrenRecursiveArrayIterator::hasChildren: Ответ относится к текущей позиции и не двигает курсор. Работа с вложенного массива.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveArrayIterator::hasChildren(): bool

RecursiveArrayIterator::hasChildren. Ответ относится к текущей позиции и не двигает курсор. hasChildren() проверяет текущее значение: скаляр id — лист, массив customer — ветка. Во второй независимой ситуации: Флаг CHILD_ARRAYS_ONLY задаёт границу модели: только PHP-массивы считаются дочерними уровнями. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveArrayIterator::hasChildren(): bool
Результатbool: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. У файлов явно передавайте false, если политика запрещает следовать по символическим ссылкам.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

hasChildren() проверяет текущее значение: скаляр id — лист, массив customer — ветка.

Отличить номер заказа от блока клиентаСамостоятельный пример
<?php
$tree = new RecursiveArrayIterator([
    'id' => 41,
    'customer' => ['name' => 'Ирина'],
]);
foreach ($tree as $key => $_) {
    echo $key, '=', $tree->hasChildren() ? 'ветка' : 'лист', "\n";
}
Ожидаемый результат
id=лист
customer=ветка

Метод не продвигает курсор и не возвращает детей; он только разрешает безопасный следующий шаг.

Скачать самостоятельный пример с fixtures, результатом и README

Флаг CHILD_ARRAYS_ONLY задаёт границу модели: только PHP-массивы считаются дочерними уровнями.

Ограничить детьми только массивыСамостоятельный пример
<?php
$tree = new RecursiveArrayIterator([
    'arrayNode' => ['enabled' => true],
    'objectNode' => (object) ['enabled' => true],
], RecursiveArrayIterator::CHILD_ARRAYS_ONLY);
foreach ($tree as $key => $_) {
    echo $key, '=', $tree->hasChildren() ? 'ветка' : 'лист', "\n";
}
Ожидаемый результат
arrayNode=ветка
objectNode=лист

Объект остаётся значением-листом. Без этого флага RecursiveArrayIterator может рассматривать его свойства как детей.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveArrayIterator::hasChildren

(PHP 5 >= 5.1.0, PHP 7, PHP 8) RecursiveArrayIterator::hasChildren — Returns whether current entry is an array or an object

Description

public function RecursiveArrayIterator::hasChildren(): bool

Returns whether current entry is an array or an object for which an iterator can be obtained via RecursiveArrayIterator::getChildren().

Parameters

This function has no parameters.

Return Values

Returns true if the current entry is an array or an object, otherwise false is returned.

See Also

RecursiveArrayIterator::getChildren() - Returns an iterator for the current entry if it is an array or an object

Связанные карточки: RecursiveArrayIterator::getChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveCachingIterator::__constructRecursiveCachingIterator::__construct: Конструктор только связывает источник и режимы Работа с кэширующего дерева.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveCachingIterator::__construct(Iterator $iterator, int $flags = RecursiveCachingIterator::CALL_TOSTRING)

RecursiveCachingIterator::__construct. Конструктор только связывает источник и режимы; фактическое чтение начинается при rewind/foreach. Конструктор принимает Iterator и флаги. FULL_CACHE сохраняет пройденные значения, чтобы getCache() мог вернуть всю историю уровня. Во второй независимой ситуации: Второй конструктор оборачивает меню. hasNext() использует look-ahead и позволяет выбрать разделитель без лишней стрелки после последнего пункта. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
iteratorРекурсивный источник из сигнатуры. Объект не копируется: внешний класс управляет тем же курсором и вызывает его hasChildren()/getChildren().
flagsБитовая маска именно данного класса: выбор ключа/current, политика представления или CATCH_GET_CHILD. Совмещаются только документированные константы.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveCachingIterator::__construct(Iterator $iterator, int $flags = RecursiveCachingIterator::CALL_TOSTRING)
РезультатКонструктор не возвращает прикладное значение; выражение new создаёт объект, который затем сохраняется в переменной.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Точный тип возврата, особые значения и изменения по версиям перечислены в таблице и полном официальном контракте.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Конструктор принимает Iterator и флаги. FULL_CACHE сохраняет пройденные значения, чтобы getCache() мог вернуть всю историю уровня.

Создать кэш этапов импортаСамостоятельный пример
<?php
$steps = new RecursiveCachingIterator(
    new RecursiveArrayIterator(['read', 'validate', 'save']),
    CachingIterator::FULL_CACHE
);
foreach ($steps as $step) {
    echo $step, ': cached=', count($steps->getCache()), "\n";
}
Ожидаемый результат
read: cached=1
validate: cached=2
save: cached=3

Кэш растёт от одного до трёх элементов. Для большого потока это осознанная плата памятью.

Скачать самостоятельный пример с fixtures, результатом и README

Второй конструктор оборачивает меню. hasNext() использует look-ahead и позволяет выбрать разделитель без лишней стрелки после последнего пункта.

Создать кэш пунктов меню и увидеть конецСамостоятельный пример
<?php
$menu = new RecursiveCachingIterator(
    new RecursiveArrayIterator(['catalog', 'cart']),
    CachingIterator::FULL_CACHE
);
foreach ($menu as $item) {
    echo $item, $menu->hasNext() ? ' → ' : ' ✓', "\n";
}
Ожидаемый результат
catalog → 
cart ✓

Объект не меняет значения catalog/cart; он добавляет сведения о позиции.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveCachingIterator::__construct

(PHP 5 >= 5.1.0, PHP 7, PHP 8) RecursiveCachingIterator::__construct — Construct

Description

public function RecursiveCachingIterator::__construct(Iterator $iterator, int $flags = RecursiveCachingIterator::CALL_TOSTRING)

Constructs a new RecursiveCachingIterator, which consists of a passed in iterator.

WarningThis function is currently not documented; only its argument list is available.

Parameters

iterator

The iterator being used.

flags

The flags. Use CALL_TOSTRING to call RecursiveCachingIterator::__toString() for every element (the default), and/or CATCH_GET_CHILD to catch exceptions when trying to get children.

See Also

CachingIterator::__construct() - Construct a new CachingIterator object for the iterator

Связанные карточки: RecursiveCachingIterator::getChildren, RecursiveCachingIterator::hasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveCachingIterator::getChildrenRecursiveCachingIterator::getChildren: Метод открывает ровно следующий уровень и возвращает новый рекурсивный итератор. Работа с кэширующего дерева.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveCachingIterator::getChildren(): ?RecursiveCachingIterator

RecursiveCachingIterator::getChildren. Метод открывает ровно следующий уровень и возвращает новый рекурсивный итератор. getChildren() возвращает RecursiveCachingIterator, поэтому дочерний уровень умеет вести собственный FULL_CACHE. Во второй независимой ситуации: Дочерний объект сохраняет поведение look-ahead: при печати маршрутов видно, есть ли следующий сосед. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveCachingIterator::getChildren(): ?RecursiveCachingIterator
Результат?RecursiveCachingIterator: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Сначала проверяйте hasChildren(), если форма данных заранее не гарантирована.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

getChildren() возвращает RecursiveCachingIterator, поэтому дочерний уровень умеет вести собственный FULL_CACHE.

Получить кэшируемые позиции заказаСамостоятельный пример
<?php
$root = new RecursiveCachingIterator(
    new RecursiveArrayIterator(['items' => ['A-1' => 2, 'B-2' => 1]]),
    CachingIterator::FULL_CACHE
);
$root->rewind();
$items = $root->getChildren();
foreach ($items as $sku => $qty) {
    echo $sku, '=', $qty, '; cached=', count($items->getCache()), "\n";
}
Ожидаемый результат
A-1=2; cached=1
B-2=1; cached=2

Кэш содержит уже пройденные позиции заказа, а не родительский ключ items.

Скачать самостоятельный пример с fixtures, результатом и README

Дочерний объект сохраняет поведение look-ahead: при печати маршрутов видно, есть ли следующий сосед.

Получить кэшируемые маршруты APIСамостоятельный пример
<?php
$root = new RecursiveCachingIterator(
    new RecursiveArrayIterator(['api' => ['list' => '/orders', 'one' => '/orders/41']]),
    CachingIterator::FULL_CACHE
);
$root->rewind();
$routes = $root->getChildren();
foreach ($routes as $name => $path) {
    echo $name, ':', $path, ':next=', $routes->hasNext() ? 'yes' : 'no', "\n";
}
Ожидаемый результат
list:/orders:next=yes
one:/orders/41:next=no

getChildren() вызывается только после hasChildren() или при точно известной форме данных.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveCachingIterator::getChildren

(PHP 5 >= 5.1.0, PHP 7, PHP 8) RecursiveCachingIterator::getChildren — Return the inner iterator's children as a RecursiveCachingIterator

Description

public function RecursiveCachingIterator::getChildren(): ?RecursiveCachingIterator

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

The inner iterator's children, as a RecursiveCachingIterator; or null if there is no children.

Связанные карточки: RecursiveCachingIterator::__construct, RecursiveCachingIterator::hasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveCachingIterator::hasChildrenRecursiveCachingIterator::hasChildren: Ответ относится к текущей позиции и не двигает курсор. Работа с кэширующего дерева.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveCachingIterator::hasChildren(): bool

RecursiveCachingIterator::hasChildren. Ответ относится к текущей позиции и не двигает курсор. hasChildren() делегирует вопрос рекурсивному источнику на текущей позиции. Во второй независимой ситуации: Первый вызов относится к массиву stock, второй после next() — к строке status. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveCachingIterator::hasChildren(): bool
Результатbool: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. У файлов явно передавайте false, если политика запрещает следовать по символическим ссылкам.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

hasChildren() делегирует вопрос рекурсивному источнику на текущей позиции.

Проверить ветку настроек перед спускомСамостоятельный пример
<?php
$cache = new RecursiveCachingIterator(
    new RecursiveArrayIterator(['mail' => ['host' => 'smtp'], 'debug' => false]),
    CachingIterator::FULL_CACHE
);
foreach ($cache as $key => $_) {
    echo $key, ': ', $cache->hasChildren() ? 'ветка' : 'лист', "\n";
}
Ожидаемый результат
mail: ветка
debug: лист

Кэширование не превращает debug в ветку: структура данных остаётся исходной.

Скачать самостоятельный пример с fixtures, результатом и README

Первый вызов относится к массиву stock, второй после next() — к строке status.

Отличить группу товаров от одиночной меткиСамостоятельный пример
<?php
$cache = new RecursiveCachingIterator(
    new RecursiveArrayIterator(['stock' => ['A-1' => 3], 'status' => 'ok']),
    CachingIterator::FULL_CACHE
);
$cache->rewind();
echo 'stock: ', $cache->hasChildren() ? 'можно открыть' : 'лист', "\n";
$cache->next();
echo 'status: ', $cache->hasChildren() ? 'можно открыть' : 'лист', "\n";
Ожидаемый результат
stock: можно открыть
status: лист

Результат зависит от текущего курсора; его нельзя сохранить и применять к другому элементу.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveCachingIterator::hasChildren

(PHP 5 >= 5.1.0, PHP 7, PHP 8) RecursiveCachingIterator::hasChildren — Check whether the current element of the inner iterator has children

Description

public function RecursiveCachingIterator::hasChildren(): bool

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

true if the inner iterator has children, otherwise false

Связанные карточки: RecursiveCachingIterator::__construct, RecursiveCachingIterator::getChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveCallbackFilterIterator::__constructRecursiveCallbackFilterIterator::__construct: Конструктор только связывает источник и режимы Работа с callback-фильтра дерева.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveCallbackFilterIterator::__construct(RecursiveIterator $iterator, callable $callback)

RecursiveCallbackFilterIterator::__construct. Конструктор только связывает источник и режимы; фактическое чтение начинается при rewind/foreach. Конструктор связывает RecursiveIterator и callback. В callback родитель shop пропускается для спуска, а служебные листья с подчёркиванием скрываются. Во второй независимой ситуации: В другой задаче тот же конструктор получает числовое правило. Родители service-a/service-b снова пропускаются только ради доступа к листьям. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
iteratorРекурсивный источник из сигнатуры. Объект не копируется: внешний класс управляет тем же курсором и вызывает его hasChildren()/getChildren().
callbackФункция получает current, key и текущий RecursiveIterator. Она возвращает bool отдельно для каждого узла и обязана сохранять нужные parent.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveCallbackFilterIterator::__construct(RecursiveIterator $iterator, callable $callback)
РезультатКонструктор не возвращает прикладное значение; выражение new создаёт объект, который затем сохраняется в переменной.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Точный тип возврата, особые значения и изменения по версиям перечислены в таблице и полном официальном контракте.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Конструктор связывает RecursiveIterator и callback. В callback родитель shop пропускается для спуска, а служебные листья с подчёркиванием скрываются.

Создать фильтр опубликованных пунктов менюСамостоятельный пример
<?php
$source = new RecursiveArrayIterator([
    'shop' => ['catalog' => '/catalog', '_draft' => '/new'],
    '_admin' => '/admin',
]);
$filter = new RecursiveCallbackFilterIterator(
    $source,
    fn(mixed $value, mixed $key, RecursiveIterator $it): bool =>
        $it->hasChildren() || !str_starts_with((string) $key, '_')
);
foreach (new RecursiveIteratorIterator($filter) as $key => $value) {
    echo $key, '=', $value, "\n";
}
Ожидаемый результат
catalog=/catalog

Видимый результат содержит только опубликованный catalog. Callback выполняется лениво во время foreach.

Скачать самостоятельный пример с fixtures, результатом и README

В другой задаче тот же конструктор получает числовое правило. Родители service-a/service-b снова пропускаются только ради доступа к листьям.

Создать фильтр ошибок уровня warning и вышеСамостоятельный пример
<?php
$source = new RecursiveArrayIterator([
    'service-a' => ['info' => 100, 'warning' => 300],
    'service-b' => ['error' => 500],
]);
$filter = new RecursiveCallbackFilterIterator(
    $source,
    fn(mixed $value, mixed $key, RecursiveIterator $it): bool =>
        $it->hasChildren() || (is_int($value) && $value >= 300)
);
foreach (new RecursiveIteratorIterator($filter) as $key => $value) {
    echo $key, '=', $value, "\n";
}
Ожидаемый результат
warning=300
error=500

Фильтр не сортирует и не агрегирует события: он решает лишь, какие узлы попадут в обход.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveCallbackFilterIterator::__construct

(PHP 5 >= 5.4.0, PHP 7, PHP 8) RecursiveCallbackFilterIterator::__construct — Create a RecursiveCallbackFilterIterator from a RecursiveIterator

Description

public function RecursiveCallbackFilterIterator::__construct(RecursiveIterator $iterator, callable $callback)

Creates a filtered iterator from a RecursiveIterator using the callback to determine which items are accepted or rejected.

Parameters

iterator

The recursive iterator to be filtered.

callback

The callback, which should return true to accept the current item or false otherwise. See Examples.

May be any valid callable value.

See Also

RecursiveCallbackFilterIterator Examples

RecursiveCallbackFilterIterator::getChildren() - Return the inner iterator's children contained in a RecursiveCallbackFilterIterator

RecursiveCallbackFilterIterator::hasChildren() - Check whether the inner iterator's current element has children

Связанные карточки: RecursiveCallbackFilterIterator::getChildren, RecursiveCallbackFilterIterator::hasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveCallbackFilterIterator::getChildrenRecursiveCallbackFilterIterator::getChildren: Метод открывает ровно следующий уровень и возвращает новый рекурсивный итератор. Работа с callback-фильтра дерева.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveCallbackFilterIterator::getChildren(): RecursiveCallbackFilterIterator

RecursiveCallbackFilterIterator::getChildren. Метод открывает ровно следующий уровень и возвращает новый рекурсивный итератор. getChildren() переносит тот же callback на дочерний уровень database. Во второй независимой ситуации: На уровне features дочерний фильтр применяет условие к булевым листьям. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveCallbackFilterIterator::getChildren(): RecursiveCallbackFilterIterator
РезультатRecursiveCallbackFilterIterator: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Сначала проверяйте hasChildren(), если форма данных заранее не гарантирована.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

getChildren() переносит тот же callback на дочерний уровень database.

Получить безопасные поля подключенияСамостоятельный пример
<?php
$filter = new RecursiveCallbackFilterIterator(
    new RecursiveArrayIterator(['database' => ['host' => 'db', 'password' => 'secret']]),
    fn(mixed $v, mixed $k, RecursiveIterator $it): bool => $it->hasChildren() || $k !== 'password'
);
$filter->rewind();
$children = $filter->getChildren();
foreach ($children as $key => $value) echo $key, '=', $value, "\n";
Ожидаемый результат
host=db

host проходит, password скрывается. Родительский фильтр остаётся на своей позиции.

Скачать самостоятельный пример с fixtures, результатом и README

На уровне features дочерний фильтр применяет условие к булевым листьям.

Получить только активные флаги функцииСамостоятельный пример
<?php
$filter = new RecursiveCallbackFilterIterator(
    new RecursiveArrayIterator(['features' => ['search' => true, 'beta' => false]]),
    fn(mixed $v, mixed $k, RecursiveIterator $it): bool => $it->hasChildren() || $v === true
);
$filter->rewind();
$children = $filter->getChildren();
foreach ($children as $key => $value) echo $key, '=', $value ? 'on' : 'off', "\n";
Ожидаемый результат
search=on

getChildren() возвращает новый RecursiveCallbackFilterIterator, а не готовый массив результатов.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveCallbackFilterIterator::getChildren

(PHP 5 >= 5.4.0, PHP 7, PHP 8) RecursiveCallbackFilterIterator::getChildren — Return the inner iterator's children contained in a RecursiveCallbackFilterIterator

Description

public function RecursiveCallbackFilterIterator::getChildren(): RecursiveCallbackFilterIterator

Fetches the filtered children of the inner iterator.

RecursiveCallbackFilterIterator::hasChildren() should be used to determine if there are children to be fetched.

Parameters

This function has no parameters.

Return Values

Returns a RecursiveCallbackFilterIterator containing the children.

See Also

RecursiveCallbackFilterIterator Examples

RecursiveCallbackFilterIterator::__construct() - Create a RecursiveCallbackFilterIterator from a RecursiveIterator

RecursiveCallbackFilterIterator::hasChildren() - Check whether the inner iterator's current element has children

Связанные карточки: RecursiveCallbackFilterIterator::__construct, RecursiveCallbackFilterIterator::hasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveCallbackFilterIterator::hasChildrenRecursiveCallbackFilterIterator::hasChildren: Ответ относится к текущей позиции и не двигает курсор. Работа с callback-фильтра дерева.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveCallbackFilterIterator::hasChildren(): bool

RecursiveCallbackFilterIterator::hasChildren. Ответ относится к текущей позиции и не двигает курсор. После rewind текущий принятый узел database остаётся ветвью. hasChildren() относится к исходной структуре, уже обёрнутой фильтром. Во второй независимой ситуации: Первый текущий элемент — массив room, второй — булево значение online. Оба приняты callback, но только у первого есть дети. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveCallbackFilterIterator::hasChildren(): bool
Результатbool: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. У файлов явно передавайте false, если политика запрещает следовать по символическим ссылкам.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

После rewind текущий принятый узел database остаётся ветвью. hasChildren() относится к исходной структуре, уже обёрнутой фильтром.

Проверить разрешённый спуск в блок databaseСамостоятельный пример
<?php
$filter = new RecursiveCallbackFilterIterator(
    new RecursiveArrayIterator(['database' => ['host' => 'db'], 'debug' => true]),
    fn(mixed $v, mixed $k, RecursiveIterator $it): bool => $it->hasChildren() || $k !== 'debug'
);
$filter->rewind();
echo $filter->key(), ': ', $filter->hasChildren() ? 'есть дети' : 'лист', "\n";
Ожидаемый результат
database: есть дети

true означает, что getChildren() создаст дочерний фильтр с тем же callback.

Скачать самостоятельный пример с fixtures, результатом и README

Первый текущий элемент — массив room, второй — булево значение online. Оба приняты callback, но только у первого есть дети.

Отличить группу датчиков от значенияСамостоятельный пример
<?php
$filter = new RecursiveCallbackFilterIterator(
    new RecursiveArrayIterator(['room' => ['temperature' => 22], 'online' => true]),
    fn(mixed $v, mixed $k, RecursiveIterator $it): bool => $it->hasChildren() || $v === true
);
$filter->rewind();
echo 'room=', $filter->hasChildren() ? 'branch' : 'leaf', "\n";
$filter->next();
echo 'online=', $filter->hasChildren() ? 'branch' : 'leaf', "\n";
Ожидаемый результат
room=branch
online=leaf

Решение accept и наличие детей — разные вопросы; их нельзя сводить к одному флагу.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveCallbackFilterIterator::hasChildren

(PHP 5 >= 5.4.0, PHP 7, PHP 8) RecursiveCallbackFilterIterator::hasChildren — Check whether the inner iterator's current element has children

Description

public function RecursiveCallbackFilterIterator::hasChildren(): bool

Returns true if the current element has children, false otherwise.

Parameters

This function has no parameters.

Return Values

Returns true if the current element has children, false otherwise.

See Also

RecursiveCallbackFilterIterator Examples

RecursiveCallbackFilterIterator::__construct() - Create a RecursiveCallbackFilterIterator from a RecursiveIterator

RecursiveCallbackFilterIterator::getChildren() - Return the inner iterator's children contained in a RecursiveCallbackFilterIterator

Связанные карточки: RecursiveCallbackFilterIterator::__construct, RecursiveCallbackFilterIterator::getChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveDirectoryIterator::__constructRecursiveDirectoryIterator::__construct: Конструктор только связывает источник и режимы Работа с дерева файлов.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveDirectoryIterator::__construct(string $directory, int $flags = 0)

RecursiveDirectoryIterator::__construct. Конструктор только связывает источник и режимы; фактическое чтение начинается при rewind/foreach. Конструктор получает локальный путь и флаги. KEY_AS_FILENAME делает ключи переносимыми, SKIP_DOTS убирает служебные записи. Во второй независимой ситуации: Вторая настройка возвращает SplFileInfo как current. На первом уровне видны config, logs и health.txt. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
directoryАбсолютный или относительный путь к разрешённой локальной папке. Примеры используют собственные fixtures рядом с example.php.
flagsБитовая маска именно данного класса: выбор ключа/current, политика представления или CATCH_GET_CHILD. Совмещаются только документированные константы.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveDirectoryIterator::__construct(string $directory, int $flags = 0)
РезультатКонструктор не возвращает прикладное значение; выражение new создаёт объект, который затем сохраняется в переменной.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Точный тип возврата, особые значения и изменения по версиям перечислены в таблице и полном официальном контракте.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Конструктор получает локальный путь и флаги. KEY_AS_FILENAME делает ключи переносимыми, SKIP_DOTS убирает служебные записи.

Создать безопасный источник дерева проектаСамостоятельный пример
<?php
$flags = FilesystemIterator::SKIP_DOTS | FilesystemIterator::KEY_AS_FILENAME;
$tree = new RecursiveDirectoryIterator(__DIR__ . '/fixture', $flags);
$names = [];
foreach ($tree as $key => $entry) $names[] = $key . ':' . ($entry->isDir() ? 'dir' : 'file');
sort($names);
echo implode(', ', $names), "\n";
echo 'Следовать по ссылкам: ', ($flags & FilesystemIterator::FOLLOW_SYMLINKS) ? 'да' : 'нет', "\n";
Ожидаемый результат
docs:dir, root.txt:file, src:dir
Следовать по ссылкам: нет

FOLLOW_SYMLINKS отсутствует, поэтому ссылки не превращаются в новые ветви. Порядок специально отсортирован после чтения.

Скачать самостоятельный пример с fixtures, результатом и README

Вторая настройка возвращает SplFileInfo как current. На первом уровне видны config, logs и health.txt.

Создать источник дерева журнала и конфигурацииСамостоятельный пример
<?php
$tree = new RecursiveDirectoryIterator(
    __DIR__ . '/workspace',
    FilesystemIterator::SKIP_DOTS | FilesystemIterator::CURRENT_AS_FILEINFO
);
$summary = ['dirs' => 0, 'files' => 0];
foreach ($tree as $entry) $summary[$entry->isDir() ? 'dirs' : 'files']++;
echo 'Первый уровень: dirs=', $summary['dirs'], ', files=', $summary['files'], "\n";
Ожидаемый результат
Первый уровень: dirs=2, files=1

Конструктор только открывает корень; рекурсивный спуск начнётся при вызове getChildren или через внешний обходчик.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveDirectoryIterator::__construct

(PHP 5 >= 5.1.2, PHP 7, PHP 8) RecursiveDirectoryIterator::__construct — Constructs a RecursiveDirectoryIterator

Description

public function RecursiveDirectoryIterator::__construct(string $directory, int $flags = FilesystemIterator::KEY_AS_PATHNAME | FilesystemIterator::CURRENT_AS_FILEINFO)

Constructs a RecursiveDirectoryIterator() for the provided directory.

Parameters

directory

The path of the directory to be iterated over.

flags

Flags may be provided which will affect the behavior of some methods. A list of the flags can found under FilesystemIterator predefined constants. They can also be set later with FilesystemIterator::setFlags().

Errors/Exceptions

Throws an UnexpectedValueException if the directory does not exist.

Throws a ValueError if the directory is an empty string.

Changelog

Version Description

8.0.0

Now throws a ValueError if directory is an empty string; previously it threw a RuntimeException.

See Also

FilesystemIterator::__construct() - Constructs a new filesystem iterator

RecursiveIteratorIterator::__construct() - Construct a RecursiveIteratorIterator

FilesystemIterator predefined constants

Связанные карточки: RecursiveDirectoryIterator::getChildren, RecursiveDirectoryIterator::getSubPath, RecursiveDirectoryIterator::getSubPathname, RecursiveDirectoryIterator::hasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveDirectoryIterator::getChildrenRecursiveDirectoryIterator::getChildren: Метод открывает ровно следующий уровень и возвращает новый рекурсивный итератор. Работа с дерева файлов.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveDirectoryIterator::getChildren(): RecursiveDirectoryIterator

RecursiveDirectoryIterator::getChildren. Метод открывает ровно следующий уровень и возвращает новый рекурсивный итератор. Когда current — каталог docs, getChildren() создаёт RecursiveDirectoryIterator для этого пути. Во второй независимой ситуации: Тот же метод открывает папку archive внутри logs и возвращает объект того же рекурсивного класса. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveDirectoryIterator::getChildren(): RecursiveDirectoryIterator
РезультатRecursiveDirectoryIterator: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Сначала проверяйте hasChildren(), если форма данных заранее не гарантирована.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Когда current — каталог docs, getChildren() создаёт RecursiveDirectoryIterator для этого пути.

Открыть каталог docs отдельным дочерним итераторомСамостоятельный пример
<?php
$root = new RecursiveDirectoryIterator(__DIR__ . '/fixture', FilesystemIterator::SKIP_DOTS);
foreach ($root as $entry) {
    if ($entry->getFilename() !== 'docs') continue;
    $children = $root->getChildren();
    $names = [];
    foreach ($children as $child) $names[] = $child->getFilename();
    sort($names);
    echo implode(', ', $names), "\n";
}
Ожидаемый результат
api.md, readme.txt

Дочерний объект читает только содержимое docs; корневой объект продолжает свой первый уровень.

Скачать самостоятельный пример с fixtures, результатом и README

Тот же метод открывает папку archive внутри logs и возвращает объект того же рекурсивного класса.

Открыть вложенный архив журналовСамостоятельный пример
<?php
$root = new RecursiveDirectoryIterator(__DIR__ . '/workspace/logs', FilesystemIterator::SKIP_DOTS);
foreach ($root as $entry) {
    if ($entry->getFilename() !== 'archive') continue;
    $children = $root->getChildren();
    foreach ($children as $child) echo $child->getFilename(), "\n";
}
Ожидаемый результат
old.log

Перед вызовом код знает, что current — каталог; в общем алгоритме это подтверждают hasChildren(false).

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveDirectoryIterator::getChildren

(PHP 5 >= 5.1.0, PHP 7, PHP 8) RecursiveDirectoryIterator::getChildren — Returns an iterator for the current entry if it is a directory

Description

public function RecursiveDirectoryIterator::getChildren(): RecursiveDirectoryIterator

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

The filename, file information, or $this depending on the set flags. See the FilesystemIterator constants.

Связанные карточки: RecursiveDirectoryIterator::__construct, RecursiveDirectoryIterator::getSubPath, RecursiveDirectoryIterator::getSubPathname, RecursiveDirectoryIterator::hasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveDirectoryIterator::getSubPathRecursiveDirectoryIterator::getSubPath: Возвращается относительная папка без имени текущей записи и без абсолютного корня. Работа с дерева файлов.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveDirectoryIterator::getSubPath(): string

RecursiveDirectoryIterator::getSubPath. Возвращается относительная папка без имени текущей записи и без абсолютного корня. getSubPath() возвращает путь подпапки относительно переданного корня, без имени текущего файла. Во второй независимой ситуации: В импорте журналов getSubPath() помогает сохранить группу, не раскрывая полный путь сервера. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveDirectoryIterator::getSubPath(): string
Результатstring: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Точный тип возврата, особые значения и изменения по версиям перечислены в таблице и полном официальном контракте.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

getSubPath() возвращает путь подпапки относительно переданного корня, без имени текущего файла.

Получить только относительные папки файловСамостоятельный пример
<?php
$flat = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator(__DIR__ . '/fixture', FilesystemIterator::SKIP_DOTS)
);
$rows = [];
foreach ($flat as $file) {
    if (!$file->isFile()) continue;
    $rows[] = $file->getFilename() . ' => ' . str_replace('\\', '/', $flat->getSubIterator()->getSubPath());
}
sort($rows);
echo implode("\n", $rows), "\n";
Ожидаемый результат
App.php => src
api.md => docs
readme.txt => docs
root.txt => 

Для root.txt строка пуста: файл лежит прямо в fixture. Абсолютный временный путь в вывод не попадает.

Скачать самостоятельный пример с fixtures, результатом и README

В импорте журналов getSubPath() помогает сохранить группу, не раскрывая полный путь сервера.

Сгруппировать журналы по относительной папкеСамостоятельный пример
<?php
$flat = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator(__DIR__ . '/workspace', FilesystemIterator::SKIP_DOTS)
);
$rows = [];
foreach ($flat as $file) {
    if ($file->getExtension() !== 'log') continue;
    $inner = $flat->getSubIterator();
    $rows[] = $file->getFilename() . ' @ ' . str_replace('\\', '/', $inner->getSubPath());
}
sort($rows);
echo implode("\n", $rows), "\n";
Ожидаемый результат
app.log @ logs
old.log @ logs/archive

Метод не нормализует разделители сам; пример делает это только для переносимого текстового результата.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveDirectoryIterator::getSubPath

(PHP 5 >= 5.1.0, PHP 7, PHP 8) RecursiveDirectoryIterator::getSubPath — Get sub path

Description

public function RecursiveDirectoryIterator::getSubPath(): string

Returns the sub path relative to the directory given in the constructor.

Parameters

This function has no parameters.

Return Values

The sub path.

See Also

RecursiveDirectoryIterator::getSubPathName() - Get sub path and name

RecursiveDirectoryIterator::key() - Return path and filename of current dir entry

Связанные карточки: RecursiveDirectoryIterator::__construct, RecursiveDirectoryIterator::getChildren, RecursiveDirectoryIterator::getSubPathname, RecursiveDirectoryIterator::hasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveDirectoryIterator::getSubPathnameRecursiveDirectoryIterator::getSubPathname: Возвращается относительная папка вместе с текущим именем — удобный ключ манифеста. Работа с дерева файлов.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveDirectoryIterator::getSubPathname(): string

RecursiveDirectoryIterator::getSubPathname. Возвращается относительная папка вместе с текущим именем — удобный ключ манифеста. getSubPathname() объединяет относительную подпапку и текущее имя, но не добавляет абсолютный корень. Во второй независимой ситуации: В резервной копии относительное имя можно присоединить к новому корню backup. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveDirectoryIterator::getSubPathname(): string
Результатstring: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Точный тип возврата, особые значения и изменения по версиям перечислены в таблице и полном официальном контракте.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

getSubPathname() объединяет относительную подпапку и текущее имя, но не добавляет абсолютный корень.

Получить переносимые относительные имена проектаСамостоятельный пример
<?php
$flat = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator(__DIR__ . '/fixture', FilesystemIterator::SKIP_DOTS)
);
$paths = [];
foreach ($flat as $file) if ($file->isFile()) $paths[] = str_replace('\\', '/', $flat->getSubPathname());
sort($paths);
echo implode(', ', $paths), "\n";
Ожидаемый результат
docs/api.md, docs/readme.txt, root.txt, src/App.php

Такие значения подходят для манифеста проекта; перед записью в URL всё равно нужны отдельные правила кодирования.

Скачать самостоятельный пример с fixtures, результатом и README

В резервной копии относительное имя можно присоединить к новому корню backup.

Построить относительный список резервного копированияСамостоятельный пример
<?php
$flat = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator(__DIR__ . '/workspace', FilesystemIterator::SKIP_DOTS)
);
$paths = [];
foreach ($flat as $file) if ($file->isFile()) $paths[] = str_replace('\\', '/', $flat->getSubPathname());
sort($paths);
foreach ($paths as $path) echo 'backup/', $path, "\n";
Ожидаемый результат
backup/config/app.ini
backup/health.txt
backup/logs/app.log
backup/logs/archive/old.log

getSubPathname() не копирует файл и не защищает от выхода из каталога; здесь источником является собственная фиксированная папка.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveDirectoryIterator::getSubPathname

(PHP 5 >= 5.1.0, PHP 7, PHP 8) RecursiveDirectoryIterator::getSubPathname — Get sub path and name

Description

public function RecursiveDirectoryIterator::getSubPathname(): string

Gets the sub path and filename.

Parameters

This function has no parameters.

Return Values

The sub path (sub directory) and filename.

See Also

RecursiveDirectoryIterator::getSubPath() - Get sub path

RecursiveDirectoryIterator::key() - Return path and filename of current dir entry

Связанные карточки: RecursiveDirectoryIterator::__construct, RecursiveDirectoryIterator::getChildren, RecursiveDirectoryIterator::getSubPath, RecursiveDirectoryIterator::hasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveDirectoryIterator::hasChildrenRecursiveDirectoryIterator::hasChildren: Ответ относится к текущей позиции и не двигает курсор. Работа с дерева файлов.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveDirectoryIterator::hasChildren(bool $allowLinks = false): bool

RecursiveDirectoryIterator::hasChildren. Ответ относится к текущей позиции и не двигает курсор. hasChildren(false) проверяет текущую запись и запрещает считать символическую ссылку дочерним каталогом. Во второй независимой ситуации: Вторая проверка строит карту первого уровня workspace и снова передаёт false как политику ссылок. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
allowLinksfalse запрещает считать ссылку дочерним каталогом; true разрешает следование и требует защиты от циклов и выхода за доверенный корень.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveDirectoryIterator::hasChildren(bool $allowLinks = false): bool
Результатbool: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. У файлов явно передавайте false, если политика запрещает следовать по символическим ссылкам.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

hasChildren(false) проверяет текущую запись и запрещает считать символическую ссылку дочерним каталогом.

Отличить каталоги от файлов без следования по ссылкамСамостоятельный пример
<?php
$root = new RecursiveDirectoryIterator(__DIR__ . '/fixture', FilesystemIterator::SKIP_DOTS);
$rows = [];
foreach ($root as $entry) $rows[] = $entry->getFilename() . '=' . ($root->hasChildren(false) ? 'branch' : 'leaf');
sort($rows);
echo implode(', ', $rows), "\n";
Ожидаемый результат
docs=branch, root.txt=leaf, src=branch

На этой fixture ветви — docs и src, leaf — root.txt. Метод не открывает каталог.

Скачать самостоятельный пример с fixtures, результатом и README

Вторая проверка строит карту первого уровня workspace и снова передаёт false как политику ссылок.

Проверить вложенность рабочих папокСамостоятельный пример
<?php
$root = new RecursiveDirectoryIterator(__DIR__ . '/workspace', FilesystemIterator::SKIP_DOTS);
$rows = [];
foreach ($root as $entry) $rows[$entry->getFilename()] = $root->hasChildren(false) ? 'dir' : 'file';
ksort($rows);
foreach ($rows as $name => $type) echo $name, ':', $type, "\n";
Ожидаемый результат
config:dir
health.txt:file
logs:dir

Права доступа могут помешать открыть настоящий каталог позднее; true здесь сообщает структурную возможность, а не гарантию чтения.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveDirectoryIterator::hasChildren

(PHP 5, PHP 7, PHP 8) RecursiveDirectoryIterator::hasChildren — Returns whether current entry is a directory and not '.' or '..'

Description

public function RecursiveDirectoryIterator::hasChildren(bool $allowLinks = false): bool

WarningThis function is currently not documented; only its argument list is available.

Parameters

allowLinks

Return Values

Returns whether the current entry is a directory, but not '.' or '..'

Связанные карточки: RecursiveDirectoryIterator::__construct, RecursiveDirectoryIterator::getChildren, RecursiveDirectoryIterator::getSubPath, RecursiveDirectoryIterator::getSubPathname.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveDirectoryIterator::keyRecursiveDirectoryIterator::key: Метод читает идентификатор текущей позиции Работа с дерева файлов.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveDirectoryIterator::key(): string

RecursiveDirectoryIterator::key. Метод читает идентификатор текущей позиции; форма зависит от флагов и уровня. С KEY_AS_FILENAME метод key() возвращает имя текущей записи, а не абсолютный путь временной папки. Во второй независимой ситуации: key() читает текущую позицию ручного протокола rewind/valid/next. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveDirectoryIterator::key(): string
Результатstring: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Ключ одного уровня не всегда уникален во всём дереве; при необходимости собирайте полный путь.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

С KEY_AS_FILENAME метод key() возвращает имя текущей записи, а не абсолютный путь временной папки.

Получить короткие ключи вместо абсолютных путейСамостоятельный пример
<?php
$root = new RecursiveDirectoryIterator(
    __DIR__ . '/fixture',
    FilesystemIterator::SKIP_DOTS | FilesystemIterator::KEY_AS_FILENAME
);
$keys = [];
foreach ($root as $ignored) $keys[] = $root->key();
sort($keys);
echo implode(', ', $keys), "\n";
Ожидаемый результат
docs, root.txt, src

Ключи уникальны только внутри этого каталога; одинаковые имена на разных уровнях требуют getSubPathname().

Скачать самостоятельный пример с fixtures, результатом и README

key() читает текущую позицию ручного протокола rewind/valid/next.

Увидеть имя текущей записи при ручном обходеСамостоятельный пример
<?php
$root = new RecursiveDirectoryIterator(
    __DIR__ . '/workspace',
    FilesystemIterator::SKIP_DOTS | FilesystemIterator::KEY_AS_FILENAME
);
$root->rewind();
$seen = [];
while ($root->valid()) {
    $seen[] = $root->key();
    $root->next();
}
sort($seen);
echo implode(' | ', $seen), "\n";
Ожидаемый результат
config | health.txt | logs

Сортировка выполнена после чтения: сам итератор не обещает алфавитный порядок файловой системы.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveDirectoryIterator::key

(PHP 5, PHP 7, PHP 8) RecursiveDirectoryIterator::key — Return path and filename of current dir entry

Description

public function RecursiveDirectoryIterator::key(): string

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

The path and filename of the current dir entry.

Связанные карточки: RecursiveDirectoryIterator::__construct, RecursiveDirectoryIterator::getChildren, RecursiveDirectoryIterator::getSubPath, RecursiveDirectoryIterator::getSubPathname.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveDirectoryIterator::nextRecursiveDirectoryIterator::next: Метод меняет состояние курсора и не возвращает следующий элемент как значение. Работа с дерева файлов.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveDirectoryIterator::next(): void

RecursiveDirectoryIterator::next. Метод меняет состояние курсора и не возвращает следующий элемент как значение. next() пропускает ровно одну запись первого уровня. Затем цикл считает две оставшиеся записи независимо от их имён. Во второй независимой ситуации: Ручной цикл явно показывает роль next(): после обработки current он передвигает курсор. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveDirectoryIterator::next(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Без valid() после продвижения нельзя безопасно читать current/key.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

next() пропускает ровно одну запись первого уровня. Затем цикл считает две оставшиеся записи независимо от их имён.

Продвинуть курсор и посчитать оставшиеся записиСамостоятельный пример
<?php
$root = new RecursiveDirectoryIterator(__DIR__ . '/fixture', FilesystemIterator::SKIP_DOTS);
$root->rewind();
echo 'До next valid: ', $root->valid() ? 'yes' : 'no', "\n";
$root->next();
$remaining = 0;
while ($root->valid()) { $remaining++; $root->next(); }
echo 'Осталось: ', $remaining, "\n";
Ожидаемый результат
До next valid: yes
Осталось: 2

Метод не спускается в подкаталог; рекурсией управляет внешний RecursiveIteratorIterator.

Скачать самостоятельный пример с fixtures, результатом и README

Ручной цикл явно показывает роль next(): после обработки current он передвигает курсор.

Перейти к следующей рабочей записиСамостоятельный пример
<?php
$root = new RecursiveDirectoryIterator(__DIR__ . '/workspace', FilesystemIterator::SKIP_DOTS);
$root->rewind();
$count = 0;
while ($root->valid()) {
    $count++;
    $root->next();
}
echo 'Обработано на первом уровне: ', $count, "\n";
Ожидаемый результат
Обработано на первом уровне: 3

Без next() цикл не завершится. Здесь считаются config, logs и health.txt, но не их содержимое.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveDirectoryIterator::next

(PHP 5, PHP 7, PHP 8) RecursiveDirectoryIterator::next — Move to next entry

Description

public function RecursiveDirectoryIterator::next(): void

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

No value is returned.

Связанные карточки: RecursiveDirectoryIterator::__construct, RecursiveDirectoryIterator::getChildren, RecursiveDirectoryIterator::getSubPath, RecursiveDirectoryIterator::getSubPathname.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveDirectoryIterator::rewindRecursiveDirectoryIterator::rewind: Метод заново устанавливает первый доступный элемент всего соответствующего обхода. Работа с дерева файлов.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveDirectoryIterator::rewind(): void

RecursiveDirectoryIterator::rewind. Метод заново устанавливает первый доступный элемент всего соответствующего обхода. После полного foreach курсор недействителен. rewind() заново открывает первую доступную запись корня. Во второй независимой ситуации: Явный rewind() перед каждым проходом даёт одинаковый подсчёт трёх записей первого уровня. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveDirectoryIterator::rewind(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Повторяемость наследуется от источника; завершённый Generator не обязан перематываться.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

После полного foreach курсор недействителен. rewind() заново открывает первую доступную запись корня.

Повторно начать первый уровень проектаСамостоятельный пример
<?php
$root = new RecursiveDirectoryIterator(__DIR__ . '/fixture', FilesystemIterator::SKIP_DOTS);
foreach ($root as $_) { /* исчерпываем */ }
echo 'После foreach: ', $root->valid() ? 'valid' : 'end', "\n";
$root->rewind();
echo 'После rewind: ', $root->valid() ? 'valid' : 'end', "\n";
Ожидаемый результат
После foreach: end
После rewind: valid

Имя первой записи не выводится, потому что порядок каталога платформозависим; проверяется именно состояние курсора.

Скачать самостоятельный пример с fixtures, результатом и README

Явный rewind() перед каждым проходом даёт одинаковый подсчёт трёх записей первого уровня.

Сделать два полных подсчёта одной папкиСамостоятельный пример
<?php
$root = new RecursiveDirectoryIterator(__DIR__ . '/workspace', FilesystemIterator::SKIP_DOTS);
$counts = [];
for ($pass = 1; $pass <= 2; $pass++) {
    $root->rewind();
    $count = 0;
    while ($root->valid()) { $count++; $root->next(); }
    $counts[] = $count;
}
echo implode(', ', $counts), "\n";
Ожидаемый результат
3, 3

Если каталог меняется между проходами, числа могут различаться: итератор не создаёт снимок файловой системы.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveDirectoryIterator::rewind

(PHP 5, PHP 7, PHP 8) RecursiveDirectoryIterator::rewind — Rewind dir back to the start

Description

public function RecursiveDirectoryIterator::rewind(): void

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

No value is returned.

Связанные карточки: RecursiveDirectoryIterator::__construct, RecursiveDirectoryIterator::getChildren, RecursiveDirectoryIterator::getSubPath, RecursiveDirectoryIterator::getSubPathname.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveFilterIterator::__constructRecursiveFilterIterator::__construct: Конструктор только связывает источник и режимы Работа с именованного фильтра дерева.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveFilterIterator::__construct(RecursiveIterator $iterator)

RecursiveFilterIterator::__construct. Конструктор только связывает источник и режимы; фактическое чтение начинается при rewind/foreach. Конструктор базового RecursiveFilterIterator получает рекурсивный источник; подкласс добавляет только правило accept(). Во второй независимой ситуации: Второй конструктор связывает источник с именованным правилом остатков. Сам фильтр остаётся ленивым. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
iteratorРекурсивный источник из сигнатуры. Объект не копируется: внешний класс управляет тем же курсором и вызывает его hasChildren()/getChildren().
Часть контрактаЧто важно
Сигнатураpublic function RecursiveFilterIterator::__construct(RecursiveIterator $iterator)
РезультатКонструктор не возвращает прикладное значение; выражение new создаёт объект, который затем сохраняется в переменной.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Точный тип возврата, особые значения и изменения по версиям перечислены в таблице и полном официальном контракте.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Конструктор базового RecursiveFilterIterator получает рекурсивный источник; подкласс добавляет только правило accept().

Создать именованный фильтр публичных настроекСамостоятельный пример
<?php
class VisibleSettings extends RecursiveFilterIterator {
    public function accept(): bool {
        return $this->hasChildren() || !str_starts_with((string) $this->key(), '_');
    }
}
$visible = new VisibleSettings(new RecursiveArrayIterator([
    'mail' => ['host' => 'smtp', '_password' => 'secret'],
]));
foreach (new RecursiveIteratorIterator($visible) as $key => $value) echo $key, '=', $value, "\n";
Ожидаемый результат
host=smtp

Подкласс удобен, когда правило VisibleSettings нужно переиспользовать и тестировать отдельно.

Скачать самостоятельный пример с fixtures, результатом и README

Второй конструктор связывает источник с именованным правилом остатков. Сам фильтр остаётся ленивым.

Создать фильтр положительных остатковСамостоятельный пример
<?php
class PositiveStock extends RecursiveFilterIterator {
    public function accept(): bool {
        return $this->hasChildren() || (is_int($this->current()) && $this->current() > 0);
    }
}
$stock = new PositiveStock(new RecursiveArrayIterator([
    'A' => ['A-1' => 3, 'A-2' => 0],
]));
foreach (new RecursiveIteratorIterator($stock) as $sku => $qty) echo $sku, '=', $qty, "\n";
Ожидаемый результат
A-1=3

Нулевая позиция исчезает при обходе; исходный массив при этом не изменяется.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveFilterIterator::__construct

(PHP 5 >= 5.1.0, PHP 7, PHP 8) RecursiveFilterIterator::__construct — Create a RecursiveFilterIterator from a RecursiveIterator

Description

public function RecursiveFilterIterator::__construct(RecursiveIterator $iterator)

Create a RecursiveFilterIterator from a RecursiveIterator.

Parameters

iterator

The RecursiveIterator to be filtered.

See Also

RecursiveFilterIterator::getChildren() - Return the inner iterator's children contained in a RecursiveFilterIterator

RecursiveFilterIterator::hasChildren() - Check whether the inner iterator's current element has children

FilterIterator::accept() - Check whether the current element of the iterator is acceptable

Связанные карточки: RecursiveFilterIterator::getChildren, RecursiveFilterIterator::hasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveFilterIterator::getChildrenRecursiveFilterIterator::getChildren: Метод открывает ровно следующий уровень и возвращает новый рекурсивный итератор. Работа с именованного фильтра дерева.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveFilterIterator::getChildren(): ?RecursiveFilterIterator

RecursiveFilterIterator::getChildren. Метод открывает ровно следующий уровень и возвращает новый рекурсивный итератор. getChildren() создаёт тот же класс PublicTree вокруг дочернего источника. Во второй независимой ситуации: Дочерний AvailableTree повторно использует accept() подкласса для позиций cables. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveFilterIterator::getChildren(): ?RecursiveFilterIterator
Результат?RecursiveFilterIterator: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Сначала проверяйте hasChildren(), если форма данных заранее не гарантирована.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

getChildren() создаёт тот же класс PublicTree вокруг дочернего источника.

Продолжить публичный фильтр внутри группыСамостоятельный пример
<?php
class PublicTree extends RecursiveFilterIterator {
    public function accept(): bool { return $this->hasChildren() || !str_starts_with((string) $this->key(), '_'); }
}
$root = new PublicTree(new RecursiveArrayIterator(['service' => ['url' => '/api', '_token' => 'x']]));
$root->rewind();
$children = $root->getChildren();
foreach ($children as $key => $value) echo $key, '=', $value, "\n";
Ожидаемый результат
url=/api

Поэтому правило имени сохраняется на каждом уровне и _token не попадает в результат.

Скачать самостоятельный пример с fixtures, результатом и README

Дочерний AvailableTree повторно использует accept() подкласса для позиций cables.

Продолжить фильтр доступности в категорииСамостоятельный пример
<?php
class AvailableTree extends RecursiveFilterIterator {
    public function accept(): bool { return $this->hasChildren() || (int) $this->current() > 0; }
}
$root = new AvailableTree(new RecursiveArrayIterator(['cables' => ['usb' => 4, 'hdmi' => 0]]));
$root->rewind();
$children = $root->getChildren();
foreach ($children as $sku => $qty) echo $sku, '=', $qty, "\n";
Ожидаемый результат
usb=4

Конструктор подкласса оставлен совместимым с одним RecursiveIterator — иначе getChildren() не смог бы создать объект.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveFilterIterator::getChildren

(PHP 5 >= 5.1.0, PHP 7, PHP 8) RecursiveFilterIterator::getChildren — Return the inner iterator's children contained in a RecursiveFilterIterator

Description

public function RecursiveFilterIterator::getChildren(): ?RecursiveFilterIterator

Return the inner iterator's children contained in a RecursiveFilterIterator.

Parameters

This function has no parameters.

Return Values

Returns a RecursiveFilterIterator containing the inner iterator's children.

See Also

RecursiveFilterIterator::hasChildren() - Check whether the inner iterator's current element has children

RecursiveIterator::getChildren() - Returns an iterator for the current entry

Связанные карточки: RecursiveFilterIterator::__construct, RecursiveFilterIterator::hasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveFilterIterator::hasChildrenRecursiveFilterIterator::hasChildren: Ответ относится к текущей позиции и не двигает курсор. Работа с именованного фильтра дерева.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveFilterIterator::hasChildren(): bool

RecursiveFilterIterator::hasChildren. Ответ относится к текущей позиции и не двигает курсор. hasChildren() делегируется текущему внутреннему RecursiveIterator и нужен самому accept(), чтобы не отсечь api. Во второй независимой ситуации: Оба элемента проходят accept, но только stock является ветвью. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveFilterIterator::hasChildren(): bool
Результатbool: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. У файлов явно передавайте false, если политика запрещает следовать по символическим ссылкам.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

hasChildren() делегируется текущему внутреннему RecursiveIterator и нужен самому accept(), чтобы не отсечь api.

Проверить родителя в фильтре настроекСамостоятельный пример
<?php
class PublicOnly extends RecursiveFilterIterator {
    public function accept(): bool { return $this->hasChildren() || $this->key() !== 'secret'; }
}
$filter = new PublicOnly(new RecursiveArrayIterator(['api' => ['url' => '/v1'], 'secret' => 'x']));
$filter->rewind();
echo $filter->key(), ':', $filter->hasChildren() ? 'branch' : 'leaf', "\n";
Ожидаемый результат
api:branch

Метод не применяет правило к детям заранее; он лишь сообщает, можно ли создать дочерний фильтр.

Скачать самостоятельный пример с fixtures, результатом и README

Оба элемента проходят accept, но только stock является ветвью.

Отличить категорию от остаткаСамостоятельный пример
<?php
class NonZero extends RecursiveFilterIterator {
    public function accept(): bool { return $this->hasChildren() || (int) $this->current() > 0; }
}
$filter = new NonZero(new RecursiveArrayIterator(['stock' => ['A-1' => 2], 'total' => 2]));
$filter->rewind();
echo 'stock=', $filter->hasChildren() ? 'branch' : 'leaf', "\n";
$filter->next();
echo 'total=', $filter->hasChildren() ? 'branch' : 'leaf', "\n";
Ожидаемый результат
stock=branch
total=leaf

Родительская структура и условие принятия остаются двумя отдельными аспектами.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveFilterIterator::hasChildren

(PHP 5 >= 5.1.0, PHP 7, PHP 8) RecursiveFilterIterator::hasChildren — Check whether the inner iterator's current element has children

Description

public function RecursiveFilterIterator::hasChildren(): bool

Check whether the inner iterator's current element has children.

Parameters

This function has no parameters.

Return Values

true if the inner iterator has children, otherwise false

See Also

RecursiveFilterIterator::getChildren() - Return the inner iterator's children contained in a RecursiveFilterIterator

RecursiveIterator::hasChildren() - Returns if an iterator can be created for the current entry

Связанные карточки: RecursiveFilterIterator::__construct, RecursiveFilterIterator::getChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveIteratorIterator::beginChildrenRecursiveIteratorIterator::beginChildren: Hook отмечает вход в дочерний уровень после подготовки его курсора. Работа с рекурсивного стека.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveIteratorIterator::beginChildren(): void

RecursiveIteratorIterator::beginChildren. Hook отмечает вход в дочерний уровень после подготовки его курсора. beginChildren() вызывается после создания и rewind дочернего итератора. В дереве есть входы в app и cache. Во второй независимой ситуации: Hook видит глубину активного дочернего уровня: сначала 1 для shop, затем 2 для catalog. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveIteratorIterator::beginChildren(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Точный тип возврата, особые значения и изменения по версиям перечислены в таблице и полном официальном контракте.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

beginChildren() вызывается после создания и rewind дочернего итератора. В дереве есть входы в app и cache.

Посчитать входы в уровни конфигурацииСамостоятельный пример
<?php
class EnterWalk extends RecursiveIteratorIterator {
    public int $enters = 0;
    public function beginChildren(): void { $this->enters++; }
}
$walk = new EnterWalk(new RecursiveArrayIterator(['app' => ['cache' => ['driver' => 'file'], 'debug' => true]]));
foreach ($walk as $_) { }
echo 'Входов: ', $walk->enters, "\n";
Ожидаемый результат
Входов: 2

Hook считает переходы между уровнями, а не число листьев.

Скачать самостоятельный пример с fixtures, результатом и README

Hook видит глубину активного дочернего уровня: сначала 1 для shop, затем 2 для catalog.

Поставить маркер перед детьми каталогаСамостоятельный пример
<?php
class CatalogEnterWalk extends RecursiveIteratorIterator {
    public array $events = [];
    public function beginChildren(): void { $this->events[] = 'enter-depth-' . $this->getDepth(); }
}
$walk = new CatalogEnterWalk(new RecursiveArrayIterator(['shop' => ['catalog' => ['lamp' => 2]]]));
foreach ($walk as $_) { }
echo implode(', ', $walk->events), "\n";
Ожидаемый результат
enter-depth-1, enter-depth-2

Нумерация начинается с нулевого корня; это техническая глубина обхода, не ID категории.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveIteratorIterator::beginChildren

(PHP 5 >= 5.1.0, PHP 7, PHP 8) RecursiveIteratorIterator::beginChildren — Begin children

Description

public function RecursiveIteratorIterator::beginChildren(): void

Is called after calling RecursiveIteratorIterator::getChildren(), and its associated RecursiveIteratorIterator::rewind().

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

No value is returned.

Связанные карточки: RecursiveIteratorIterator::beginIteration, RecursiveIteratorIterator::callGetChildren, RecursiveIteratorIterator::callHasChildren, RecursiveIteratorIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveIteratorIterator::beginIterationRecursiveIteratorIterator::beginIteration: Hook срабатывает один раз перед выдачей первого элемента полного обхода. Работа с рекурсивного стека.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveIteratorIterator::beginIteration(): void

RecursiveIteratorIterator::beginIteration. Hook срабатывает один раз перед выдачей первого элемента полного обхода. beginIteration() — hook: подкласс получает вызов один раз после первой перемотки и до первого выдаваемого элемента. Во второй независимой ситуации: Второй hook записывает событие open перед чтением двух листьев заказа. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveIteratorIterator::beginIteration(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Точный тип возврата, особые значения и изменения по версиям перечислены в таблице и полном официальном контракте.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

beginIteration() — hook: подкласс получает вызов один раз после первой перемотки и до первого выдаваемого элемента.

Зафиксировать начало экспорта конфигурацииСамостоятельный пример
<?php
class ExportWalk extends RecursiveIteratorIterator {
    public int $starts = 0;
    public function beginIteration(): void { $this->starts++; echo "BEGIN export\n"; }
}
$walk = new ExportWalk(new RecursiveArrayIterator(['app' => ['debug' => true]]));
foreach ($walk as $_) echo "leaf\n";
echo 'starts=', $walk->starts, "\n";
Ожидаемый результат
BEGIN export
leaf
starts=1

Hook подходит для заголовка или счётчика обхода, но не заменяет обработку каждого элемента.

Скачать самостоятельный пример с fixtures, результатом и README

Второй hook записывает событие open перед чтением двух листьев заказа.

Открыть журнал перед обходом заказовСамостоятельный пример
<?php
class OrderWalk extends RecursiveIteratorIterator {
    public array $events = [];
    public function beginIteration(): void { $this->events[] = 'open'; }
}
$walk = new OrderWalk(new RecursiveArrayIterator(['orders' => ['A-1' => 2, 'B-2' => 1]]));
$count = 0;
foreach ($walk as $_) $count++;
echo implode(',', $walk->events), '; items=', $count, "\n";
Ожидаемый результат
open; items=2

В реальном журнале beginIteration должен быть быстрым; исключение из него остановит весь foreach.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveIteratorIterator::beginIteration

(PHP 5 >= 5.1.0, PHP 7, PHP 8) RecursiveIteratorIterator::beginIteration — Begin Iteration

Description

public function RecursiveIteratorIterator::beginIteration(): void

Called when iteration begins (after the first RecursiveIteratorIterator::rewind() call.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

No value is returned.

Связанные карточки: RecursiveIteratorIterator::beginChildren, RecursiveIteratorIterator::callGetChildren, RecursiveIteratorIterator::callHasChildren, RecursiveIteratorIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveIteratorIterator::callGetChildrenRecursiveIteratorIterator::callGetChildren: Это явный вызов getChildren() активного источника Работа с рекурсивного стека.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveIteratorIterator::callGetChildren(): ?RecursiveIterator

RecursiveIteratorIterator::callGetChildren. Это явный вызов getChildren() активного источника; обычный foreach делает его сам. callGetChildren() вызывает getChildren() активного источника на app и возвращает RecursiveIterator. Во второй независимой ситуации: Второй пример открывает непосредственных детей shop: catalog и cart. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveIteratorIterator::callGetChildren(): ?RecursiveIterator
Результат?RecursiveIterator: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Прямой вызов нужен в основном подклассу и диагностике; не рассинхронизируйте внутренний курсор.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

callGetChildren() вызывает getChildren() активного источника на app и возвращает RecursiveIterator.

Получить детей app через обходчикСамостоятельный пример
<?php
$walk = new RecursiveIteratorIterator(
    new RecursiveArrayIterator(['app' => ['cache' => [], 'debug' => true]]),
    RecursiveIteratorIterator::SELF_FIRST
);
$walk->rewind();
$children = $walk->callGetChildren();
echo implode(', ', array_keys(iterator_to_array($children))), "\n";
Ожидаемый результат
cache, debug

Метод не меняет текущий режим и не разворачивает детей автоматически в массив; iterator_to_array здесь сделан только для показа ключей.

Скачать самостоятельный пример с fixtures, результатом и README

Второй пример открывает непосредственных детей shop: catalog и cart.

Получить детей категории shopСамостоятельный пример
<?php
$walk = new RecursiveIteratorIterator(
    new RecursiveArrayIterator(['shop' => ['catalog' => ['lamp' => 2], 'cart' => 0]]),
    RecursiveIteratorIterator::SELF_FIRST
);
$walk->rewind();
$children = $walk->callGetChildren();
foreach ($children as $key => $_) echo $key, "\n";
Ожидаемый результат
catalog
cart

Перед callGetChildren() следует подтвердить callHasChildren(); здесь форма fixture известна заранее.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveIteratorIterator::callGetChildren

(PHP 5 >= 5.1.0, PHP 7, PHP 8) RecursiveIteratorIterator::callGetChildren — Get children

Description

public function RecursiveIteratorIterator::callGetChildren(): ?RecursiveIterator

Get children of the current element.

Parameters

This function has no parameters.

Return Values

A RecursiveIterator() on success, or null on failure.

Связанные карточки: RecursiveIteratorIterator::beginChildren, RecursiveIteratorIterator::beginIteration, RecursiveIteratorIterator::callHasChildren, RecursiveIteratorIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveIteratorIterator::callHasChildrenRecursiveIteratorIterator::callHasChildren: Это явный вызов hasChildren() активного внутреннего рекурсивного источника. Работа с рекурсивного стека.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveIteratorIterator::callHasChildren(): bool

RecursiveIteratorIterator::callHasChildren. Это явный вызов hasChildren() активного внутреннего рекурсивного источника. В SELF_FIRST после rewind текущим является app. callHasChildren() явно вызывает hasChildren() активного рекурсивного источника. Во второй независимой ситуации: На status тот же вызов возвращает false: строка не открывает дочерний уровень. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveIteratorIterator::callHasChildren(): bool
Результатbool: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Ответ структурный; он не гарантирует, что дочерний ресурс удастся прочитать.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

В SELF_FIRST после rewind текущим является app. callHasChildren() явно вызывает hasChildren() активного рекурсивного источника.

Спросить текущий источник о детях appСамостоятельный пример
<?php
$walk = new RecursiveIteratorIterator(
    new RecursiveArrayIterator(['app' => ['debug' => true], 'version' => '1']),
    RecursiveIteratorIterator::SELF_FIRST
);
$walk->rewind();
echo $walk->key(), ': ', $walk->callHasChildren() ? 'branch' : 'leaf', "\n";
Ожидаемый результат
app: branch

Это низкоуровневый диагностический метод обходчика; обычный foreach вызывает проверку сам.

Скачать самостоятельный пример с fixtures, результатом и README

На status тот же вызов возвращает false: строка не открывает дочерний уровень.

Спросить о детях корневого листа statusСамостоятельный пример
<?php
$walk = new RecursiveIteratorIterator(
    new RecursiveArrayIterator(['shop' => ['cart' => 0], 'status' => 'open']),
    RecursiveIteratorIterator::SELF_FIRST
);
foreach ($walk as $key => $_) {
    if ($key === 'status') echo 'status: ', $walk->callHasChildren() ? 'branch' : 'leaf', "\n";
}
Ожидаемый результат
status: leaf

false не является ошибкой; это нормальное завершение ветви.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveIteratorIterator::callHasChildren

(PHP 5 >= 5.1.0, PHP 7, PHP 8) RecursiveIteratorIterator::callHasChildren — Has children

Description

public function RecursiveIteratorIterator::callHasChildren(): bool

Called for each element to test whether it has children.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

Returns whether the element has children.

Связанные карточки: RecursiveIteratorIterator::beginChildren, RecursiveIteratorIterator::beginIteration, RecursiveIteratorIterator::callGetChildren, RecursiveIteratorIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveIteratorIterator::__constructRecursiveIteratorIterator::__construct: Конструктор только связывает источник и режимы Работа с рекурсивного стека.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveIteratorIterator::__construct(Traversable $iterator, int $mode = RecursiveIteratorIterator::LEAVES_ONLY, int $flags = 0)

RecursiveIteratorIterator::__construct. Конструктор только связывает источник и режимы; фактическое чтение начинается при rewind/foreach. Конструктор связывает рекурсивный источник и режим SELF_FIRST: сначала приходит родитель, затем его содержимое. Во второй независимой ситуации: CHILD_FIRST отдаёт листья до родительского узла. Это удобно, когда родительский итог зависит от уже обработанных детей. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
iteratorРекурсивный источник из сигнатуры. Объект не копируется: внешний класс управляет тем же курсором и вызывает его hasChildren()/getChildren().
modeДля рекурсивного обхода: LEAVES_ONLY/SELF_FIRST/CHILD_FIRST; для regex — форма совпадения MATCH/GET_MATCH/ALL_MATCHES/SPLIT/REPLACE.
flagsБитовая маска именно данного класса: выбор ключа/current, политика представления или CATCH_GET_CHILD. Совмещаются только документированные константы.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveIteratorIterator::__construct(Traversable $iterator, int $mode = RecursiveIteratorIterator::LEAVES_ONLY, int $flags = 0)
РезультатКонструктор не возвращает прикладное значение; выражение new создаёт объект, который затем сохраняется в переменной.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Точный тип возврата, особые значения и изменения по версиям перечислены в таблице и полном официальном контракте.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Конструктор связывает рекурсивный источник и режим SELF_FIRST: сначала приходит родитель, затем его содержимое.

Выбрать режим SELF_FIRST для родителей перед детьмиСамостоятельный пример
<?php
$walk = new RecursiveIteratorIterator(
    new RecursiveArrayIterator(['app' => ['cache' => ['driver' => 'file'], 'debug' => true], 'version' => '1']),
    RecursiveIteratorIterator::SELF_FIRST
);
foreach ($walk as $key => $value) {
    echo $walk->getDepth(), ':', $key, '=', is_array($value) ? '[branch]' : var_export($value, true), "\n";
}
Ожидаемый результат
0:app=[branch]
1:cache=[branch]
2:driver='file'
1:debug=true
0:version='1'

Такой порядок подходит для открытия контейнера перед обработкой детей. Третий аргумент flags здесь оставлен 0.

Скачать самостоятельный пример с fixtures, результатом и README

CHILD_FIRST отдаёт листья до родительского узла. Это удобно, когда родительский итог зависит от уже обработанных детей.

Выбрать режим CHILD_FIRST для итогов после детейСамостоятельный пример
<?php
$walk = new RecursiveIteratorIterator(
    new RecursiveArrayIterator(['shop' => ['catalog' => ['lamp' => 2], 'cart' => 0], 'status' => 'open']),
    RecursiveIteratorIterator::CHILD_FIRST
);
foreach ($walk as $key => $value) {
    echo $walk->getDepth(), ':', $key, '=', is_array($value) ? '[branch]' : $value, "\n";
}
Ожидаемый результат
2:lamp=2
1:catalog=[branch]
1:cart=0
0:shop=[branch]
0:status=open

Режим меняет порядок выдачи, но не изменяет исходный массив.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveIteratorIterator::__construct

(PHP 5 >= 5.1.3, PHP 7, PHP 8) RecursiveIteratorIterator::__construct — Construct a RecursiveIteratorIterator

Description

public function RecursiveIteratorIterator::__construct(Traversable $iterator, int $mode = RecursiveIteratorIterator::LEAVES_ONLY, int $flags = 0)

Creates a RecursiveIteratorIterator from a RecursiveIterator.

Parameters

iterator

The iterator being constructed from. Either a RecursiveIterator or IteratorAggregate.

mode

Optional mode. Possible values are

RecursiveIteratorIterator::LEAVES_ONLY - The default. Lists only leaves in iteration.

RecursiveIteratorIterator::SELF_FIRST - Lists leaves and parents in iteration with parents coming first.

RecursiveIteratorIterator::CHILD_FIRST - Lists leaves and parents in iteration with leaves coming first.

flags

Optional flag. Possible values are RecursiveIteratorIterator::CATCH_GET_CHILD which will then ignore exceptions thrown in calls to RecursiveIteratorIterator::getChildren().

Связанные карточки: RecursiveIteratorIterator::beginChildren, RecursiveIteratorIterator::beginIteration, RecursiveIteratorIterator::callGetChildren, RecursiveIteratorIterator::callHasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveIteratorIterator::currentRecursiveIteratorIterator::current: Метод читает текущее значение без продвижения Работа с рекурсивного стека.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveIteratorIterator::current(): mixed

RecursiveIteratorIterator::current. Метод читает текущее значение без продвижения; у дерева оно может быть уже украшено. В режиме LEAVES_ONLY rewind приводит к первому листу. current() возвращает его значение file без продвижения. Во второй независимой ситуации: current() сохраняет тип исходного листа: остаток 4 остаётся int. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveIteratorIterator::current(): mixed
Результатmixed: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Не сохраняйте украшенную строку RecursiveTreeIterator как исходное бизнес-значение.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

В режиме LEAVES_ONLY rewind приводит к первому листу. current() возвращает его значение file без продвижения.

Прочитать первый лист конфигурацииСамостоятельный пример
<?php
$walk = new RecursiveIteratorIterator(new RecursiveArrayIterator(['app' => ['driver' => 'file']]));
$walk->rewind();
echo 'key=', $walk->key(), '; value=', $walk->current(), "\n";
Ожидаемый результат
key=driver; value=file

Повторный current() на той же позиции вернёт то же значение; движение выполняет next().

Скачать самостоятельный пример с fixtures, результатом и README

current() сохраняет тип исходного листа: остаток 4 остаётся int.

Прочитать числовой остаток товараСамостоятельный пример
<?php
$walk = new RecursiveIteratorIterator(new RecursiveArrayIterator(['stock' => ['A-1' => 4]]));
$walk->rewind();
echo get_debug_type($walk->current()), ':', $walk->current(), "\n";
Ожидаемый результат
int:4

Метод не нормализует внешние данные; строки из формы или JSON нужно проверять отдельно.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveIteratorIterator::current

(PHP 5, PHP 7, PHP 8) RecursiveIteratorIterator::current — Access the current element value

Description

public function RecursiveIteratorIterator::current(): mixed

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

The current elements value.

Связанные карточки: RecursiveIteratorIterator::beginChildren, RecursiveIteratorIterator::beginIteration, RecursiveIteratorIterator::callGetChildren, RecursiveIteratorIterator::callHasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveIteratorIterator::endChildrenRecursiveIteratorIterator::endChildren: Hook отмечает возврат после полного исчерпания одного дочернего уровня. Работа с рекурсивного стека.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveIteratorIterator::endChildren(): void

RecursiveIteratorIterator::endChildren. Hook отмечает возврат после полного исчерпания одного дочернего уровня. endChildren() срабатывает после исчерпания каждого дочернего уровня: cache и app дают два выхода. Во второй независимой ситуации: Hook отмечает закрытие вложенной catalog, затем внешней shop. Значение глубины в hook отражает момент возврата реализации. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveIteratorIterator::endChildren(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Точный тип возврата, особые значения и изменения по версиям перечислены в таблице и полном официальном контракте.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

endChildren() срабатывает после исчерпания каждого дочернего уровня: cache и app дают два выхода.

Посчитать выходы из уровней конфигурацииСамостоятельный пример
<?php
class LeaveWalk extends RecursiveIteratorIterator {
    public int $leaves = 0;
    public function endChildren(): void { $this->leaves++; }
}
$walk = new LeaveWalk(new RecursiveArrayIterator(['app' => ['cache' => ['driver' => 'file'], 'debug' => true]]));
foreach ($walk as $_) { }
echo 'Выходов: ', $walk->leaves, "\n";
Ожидаемый результат
Выходов: 2

Количество входов и выходов совпадает при нормальном полном обходе.

Скачать самостоятельный пример с fixtures, результатом и README

Hook отмечает закрытие вложенной catalog, затем внешней shop. Значение глубины в hook отражает момент возврата реализации.

Закрыть визуальные группы каталогаСамостоятельный пример
<?php
class GroupLeaveWalk extends RecursiveIteratorIterator {
    public array $events = [];
    public function endChildren(): void { $this->events[] = 'leave-to-' . ($this->getDepth() - 1); }
}
$walk = new GroupLeaveWalk(new RecursiveArrayIterator(['shop' => ['catalog' => ['lamp' => 2]]]));
foreach ($walk as $_) { }
echo implode(', ', $walk->events), "\n";
Ожидаемый результат
leave-to-1, leave-to-0

Для человекочитаемых отступов обычно достаточно getDepth() на самих элементах; hooks нужны, если требуется явное открытие/закрытие контейнеров.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveIteratorIterator::endChildren

(PHP 5 >= 5.1.0, PHP 7, PHP 8) RecursiveIteratorIterator::endChildren — End children

Description

public function RecursiveIteratorIterator::endChildren(): void

Called when end recursing one level.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

No value is returned.

Связанные карточки: RecursiveIteratorIterator::beginChildren, RecursiveIteratorIterator::beginIteration, RecursiveIteratorIterator::callGetChildren, RecursiveIteratorIterator::callHasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveIteratorIterator::endIterationRecursiveIteratorIterator::endIteration: Hook срабатывает после исчерпания полного обхода, когда valid() стал false. Работа с рекурсивного стека.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveIteratorIterator::endIteration(): void

RecursiveIteratorIterator::endIteration. Hook срабатывает после исчерпания полного обхода, когда valid() стал false. endIteration() вызывается, когда valid() впервые стал false после полного обхода. Во второй независимой ситуации: Здесь nextElement считает готовые элементы, а endIteration печатает итог после завершения. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveIteratorIterator::endIteration(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Точный тип возврата, особые значения и изменения по версиям перечислены в таблице и полном официальном контракте.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

endIteration() вызывается, когда valid() впервые стал false после полного обхода.

Закрыть экспорт после последнего листаСамостоятельный пример
<?php
class ExportEndWalk extends RecursiveIteratorIterator {
    public function endIteration(): void { echo "END export\n"; }
}
$walk = new ExportEndWalk(new RecursiveArrayIterator(['app' => ['debug' => true]]));
foreach ($walk as $key => $value) echo $key, '=', $value ? 'true' : 'false', "\n";
Ожидаемый результат
debug=true
END export

Это место для финального счётчика или закрытия собственного ресурса подкласса; оно не вызывается как значение каждого листа.

Скачать самостоятельный пример с fixtures, результатом и README

Здесь nextElement считает готовые элементы, а endIteration печатает итог после завершения.

Подвести число обработанных позицийСамостоятельный пример
<?php
class CountEndWalk extends RecursiveIteratorIterator {
    public int $seen = 0;
    public function nextElement(): void { $this->seen++; }
    public function endIteration(): void { echo 'processed=', $this->seen, "\n"; }
}
$walk = new CountEndWalk(new RecursiveArrayIterator(['stock' => ['A' => 3, 'B' => 4]]));
foreach ($walk as $_) { }
Ожидаемый результат
processed=2

Hooks связаны одним объектом, поэтому состояние seen доступно финальному этапу.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveIteratorIterator::endIteration

(PHP 5 >= 5.1.0, PHP 7, PHP 8) RecursiveIteratorIterator::endIteration — End Iteration

Description

public function RecursiveIteratorIterator::endIteration(): void

Called when the iteration ends (when RecursiveIteratorIterator::valid() first returns false.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

No value is returned.

Связанные карточки: RecursiveIteratorIterator::beginChildren, RecursiveIteratorIterator::beginIteration, RecursiveIteratorIterator::callGetChildren, RecursiveIteratorIterator::callHasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveIteratorIterator::getDepthRecursiveIteratorIterator::getDepth: Нулевой корень и активный стек определяют целую глубину текущего узла. Работа с рекурсивного стека.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveIteratorIterator::getDepth(): int

RecursiveIteratorIterator::getDepth. Нулевой корень и активный стек определяют целую глубину текущего узла. getDepth() считает нулевой корень: driver находится на 2, debug на 1, version на 0. Во второй независимой ситуации: Число глубины превращается в два пробела на уровень, поэтому вложенность видна в текстовом отчёте. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveIteratorIterator::getDepth(): int
Результатint: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Точный тип возврата, особые значения и изменения по версиям перечислены в таблице и полном официальном контракте.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

getDepth() считает нулевой корень: driver находится на 2, debug на 1, version на 0.

Показать глубину каждого параметраСамостоятельный пример
<?php
$walk = new RecursiveIteratorIterator(new RecursiveArrayIterator([
    'app' => ['cache' => ['driver' => 'file'], 'debug' => true],
    'version' => '1',
]));
foreach ($walk as $key => $_) echo $key, ': depth=', $walk->getDepth(), "\n";
Ожидаемый результат
driver: depth=2
debug: depth=1
version: depth=0

Глубина относится к текущему положению стека и доступна только во время валидного обхода.

Скачать самостоятельный пример с fixtures, результатом и README

Число глубины превращается в два пробела на уровень, поэтому вложенность видна в текстовом отчёте.

Сделать отступы по уровню каталогаСамостоятельный пример
<?php
$walk = new RecursiveIteratorIterator(new RecursiveArrayIterator([
    'shop' => ['catalog' => ['lamp' => 2], 'cart' => 0],
    'status' => 'open',
]));
foreach ($walk as $key => $value) echo str_repeat('  ', $walk->getDepth()), $key, '=', $value, "\n";
Ожидаемый результат
    lamp=2
  cart=0
status=open

Пробелы — представление, а не часть ключа или значения.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveIteratorIterator::getDepth

(PHP 5, PHP 7, PHP 8) RecursiveIteratorIterator::getDepth — Get the current depth of the recursive iteration

Description

public function RecursiveIteratorIterator::getDepth(): int

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

The current depth of the recursive iteration.

Связанные карточки: RecursiveIteratorIterator::beginChildren, RecursiveIteratorIterator::beginIteration, RecursiveIteratorIterator::callGetChildren, RecursiveIteratorIterator::callHasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveIteratorIterator::getInnerIteratorRecursiveIteratorIterator::getInnerIterator: Возвращается активный внутренний итератор текущего, обычно самого глубокого, уровня. Работа с рекурсивного стека.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveIteratorIterator::getInnerIterator(): RecursiveIterator

RecursiveIteratorIterator::getInnerIterator. Возвращается активный внутренний итератор текущего, обычно самого глубокого, уровня. getInnerIterator() возвращает активный RecursiveIterator самого глубокого текущего уровня. Во второй независимой ситуации: На листе sku активный inner хранит значение 7 и находится на глубине 2. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveIteratorIterator::getInnerIterator(): RecursiveIterator
РезультатRecursiveIterator: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Точный тип возврата, особые значения и изменения по версиям перечислены в таблице и полном официальном контракте.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

getInnerIterator() возвращает активный RecursiveIterator самого глубокого текущего уровня.

Увидеть активный итератор на глубоком листеСамостоятельный пример
<?php
$walk = new RecursiveIteratorIterator(new RecursiveArrayIterator(['app' => ['cache' => ['driver' => 'file']]]));
$walk->rewind();
$inner = $walk->getInnerIterator();
echo $inner::class, '; key=', $inner->key(), "\n";
Ожидаемый результат
RecursiveArrayIterator; key=driver

Это тот объект, у которого current/key соответствуют выдаваемому driver, а не обязательно корневой источник.

Скачать самостоятельный пример с fixtures, результатом и README

На листе sku активный inner хранит значение 7 и находится на глубине 2.

Получить активный уровень складаСамостоятельный пример
<?php
$walk = new RecursiveIteratorIterator(new RecursiveArrayIterator(['warehouse' => ['zone-A' => ['sku' => 7]]]));
$walk->rewind();
$inner = $walk->getInnerIterator();
echo 'depth=', $walk->getDepth(), '; current=', $inner->current(), "\n";
Ожидаемый результат
depth=2; current=7

Изменение внутреннего курсора вручную может сломать протокол внешнего обходчика; обычно его только читают.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveIteratorIterator::getInnerIterator

(PHP 5 >= 5.1.0, PHP 7, PHP 8) RecursiveIteratorIterator::getInnerIterator — Get inner iterator

Description

public function RecursiveIteratorIterator::getInnerIterator(): RecursiveIterator

Gets the current active sub iterator.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

The current active sub iterator.

Связанные карточки: RecursiveIteratorIterator::beginChildren, RecursiveIteratorIterator::beginIteration, RecursiveIteratorIterator::callGetChildren, RecursiveIteratorIterator::callHasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveIteratorIterator::getMaxDepthRecursiveIteratorIterator::getMaxDepth: false означает отсутствие собственной границы, int — последний разрешённый уровень. Работа с рекурсивного стека.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveIteratorIterator::getMaxDepth(): int|false

RecursiveIteratorIterator::getMaxDepth. false означает отсутствие собственной границы, int — последний разрешённый уровень. До setMaxDepth() метод возвращает false: обходчик не задаёт собственного максимума. Во второй независимой ситуации: После setMaxDepth(1) getMaxDepth() возвращает целое 1. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveIteratorIterator::getMaxDepth(): int|false
Результатint|false: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Точный тип возврата, особые значения и изменения по версиям перечислены в таблице и полном официальном контракте.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

До setMaxDepth() метод возвращает false: обходчик не задаёт собственного максимума.

Увидеть отсутствие ограничения глубиныСамостоятельный пример
<?php
$walk = new RecursiveIteratorIterator(new RecursiveArrayIterator(['a' => ['b' => 1]]));
var_export($walk->getMaxDepth());
echo "\n";
Ожидаемый результат
false

false нужно проверять строго; это не число 0 и не ошибка.

Скачать самостоятельный пример с fixtures, результатом и README

После setMaxDepth(1) getMaxDepth() возвращает целое 1.

Прочитать установленную границуСамостоятельный пример
<?php
$walk = new RecursiveIteratorIterator(new RecursiveArrayIterator(['a' => ['b' => ['c' => 1]]]));
$walk->setMaxDepth(1);
echo 'max=', $walk->getMaxDepth(), "\n";
Ожидаемый результат
max=1

Граница относится к нулевой системе глубин этого обходчика и может быть снята значением -1.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveIteratorIterator::getMaxDepth

(PHP 5 >= 5.1.0, PHP 7, PHP 8) RecursiveIteratorIterator::getMaxDepth — Get max depth

Description

public function RecursiveIteratorIterator::getMaxDepth(): int|false

Gets the maximum allowable depth.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

The maximum accepted depth, or false if any depth is allowed.

See Also

RecursiveIteratorIterator::setMaxDepth() - Set max depth

Связанные карточки: RecursiveIteratorIterator::beginChildren, RecursiveIteratorIterator::beginIteration, RecursiveIteratorIterator::callGetChildren, RecursiveIteratorIterator::callHasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveIteratorIterator::getSubIteratorRecursiveIteratorIterator::getSubIterator: Метод открывает конкретный уровень активного стека и позволяет собрать полный путь. Работа с рекурсивного стека.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveIteratorIterator::getSubIterator(?int $level = null): ?RecursiveIterator

RecursiveIteratorIterator::getSubIterator. Метод открывает конкретный уровень активного стека и позволяет собрать полный путь. getSubIterator(level) даёт итератор каждого активного уровня: ключи app, cache и driver складываются в полный путь. Во второй независимой ситуации: null по умолчанию означает текущий активный уровень. На первом листе это уровень lamp. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
levelНомер уровня активного стека от 0; null выбирает текущий активный уровень. Вне существующего стека возвращается null.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveIteratorIterator::getSubIterator(?int $level = null): ?RecursiveIterator
Результат?RecursiveIterator: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Несуществующий уровень даёт null; курсор объекта меняется при следующем шаге.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

getSubIterator(level) даёт итератор каждого активного уровня: ключи app, cache и driver складываются в полный путь.

Восстановить путь к драйверу из стекаСамостоятельный пример
<?php
$walk = new RecursiveIteratorIterator(new RecursiveArrayIterator(['app' => ['cache' => ['driver' => 'file']]]));
$walk->rewind();
$parts = [];
for ($level = 0; $level <= $walk->getDepth(); $level++) {
    $parts[] = (string) $walk->getSubIterator($level)->key();
}
echo implode('.', $parts), "\n";
Ожидаемый результат
app.cache.driver

Это стек текущей ветви. После next() его содержимое может измениться.

Скачать самостоятельный пример с fixtures, результатом и README

null по умолчанию означает текущий активный уровень. На первом листе это уровень lamp.

Получить текущий подытератор без номера уровняСамостоятельный пример
<?php
$walk = new RecursiveIteratorIterator(new RecursiveArrayIterator(['shop' => ['catalog' => ['lamp' => 2]]]));
$walk->rewind();
$currentLevel = $walk->getSubIterator();
echo 'class=', $currentLevel::class, '; key=', $currentLevel->key(), "\n";
Ожидаемый результат
class=RecursiveArrayIterator; key=lamp

Запрос несуществующего уровня возвращает null; перед вызовом методов результат надо проверить.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveIteratorIterator::getSubIterator

(PHP 5, PHP 7, PHP 8) RecursiveIteratorIterator::getSubIterator — The current active sub iterator

Description

public function RecursiveIteratorIterator::getSubIterator(?int $level = null): ?RecursiveIterator

WarningThis function is currently not documented; only its argument list is available.

Parameters

level

Return Values

The current active sub iterator on success; null on failure.

Changelog

Version Description

8.0.0

level is now nullable.

Связанные карточки: RecursiveIteratorIterator::beginChildren, RecursiveIteratorIterator::beginIteration, RecursiveIteratorIterator::callGetChildren, RecursiveIteratorIterator::callHasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveIteratorIterator::keyRecursiveIteratorIterator::key: Метод читает идентификатор текущей позиции Работа с рекурсивного стека.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveIteratorIterator::key(): mixed

RecursiveIteratorIterator::key. Метод читает идентификатор текущей позиции; форма зависит от флагов и уровня. key() возвращает ключ текущего листа активного уровня, а не полный путь. Во второй независимой ситуации: В индексном списке key() сохраняет целые ключи 0 и 1. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveIteratorIterator::key(): mixed
Результатmixed: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Ключ одного уровня не всегда уникален во всём дереве; при необходимости собирайте полный путь.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

key() возвращает ключ текущего листа активного уровня, а не полный путь.

Прочитать ключи листьев конфигурацииСамостоятельный пример
<?php
$walk = new RecursiveIteratorIterator(new RecursiveArrayIterator(['app' => ['debug' => true], 'version' => '1']));
foreach ($walk as $_) echo $walk->key(), "\n";
Ожидаемый результат
debug
version

Одинаковые ключи в разных ветвях возможны; для уникального адреса добавляют стек getSubIterator().

Скачать самостоятельный пример с fixtures, результатом и README

В индексном списке key() сохраняет целые ключи 0 и 1.

Прочитать числовые ключи вложенного спискаСамостоятельный пример
<?php
$walk = new RecursiveIteratorIterator(new RecursiveArrayIterator(['items' => ['A', 'B']]));
foreach ($walk as $_) echo get_debug_type($walk->key()), ':', $walk->key(), "\n";
Ожидаемый результат
int:0
int:1

Метод не преобразует их в строки; форматирование выполняет вызывающий код.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveIteratorIterator::key

(PHP 5, PHP 7, PHP 8) RecursiveIteratorIterator::key — Access the current key

Description

public function RecursiveIteratorIterator::key(): mixed

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

The current key.

Связанные карточки: RecursiveIteratorIterator::beginChildren, RecursiveIteratorIterator::beginIteration, RecursiveIteratorIterator::callGetChildren, RecursiveIteratorIterator::callHasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveIteratorIterator::nextRecursiveIteratorIterator::next: Метод меняет состояние курсора и не возвращает следующий элемент как значение. Работа с рекурсивного стека.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveIteratorIterator::next(): void

RecursiveIteratorIterator::next. Метод меняет состояние курсора и не возвращает следующий элемент как значение. next() переводит внешний курсор к следующему выдаваемому листу, даже если внутри для этого меняется рекурсивный уровень. Во второй независимой ситуации: Один next() завершает дочернюю ветвь group и возвращает стек на корень к outside. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveIteratorIterator::next(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Без valid() после продвижения нельзя безопасно читать current/key.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

next() переводит внешний курсор к следующему выдаваемому листу, даже если внутри для этого меняется рекурсивный уровень.

Перейти от первого листа ко второмуСамостоятельный пример
<?php
$walk = new RecursiveIteratorIterator(new RecursiveArrayIterator(['app' => ['a' => 1, 'b' => 2]]));
$walk->rewind();
echo $walk->key(), '=', $walk->current(), "\n";
$walk->next();
echo $walk->key(), '=', $walk->current(), "\n";
Ожидаемый результат
a=1
b=2

Метод возвращает void; новое значение читается отдельным current().

Скачать самостоятельный пример с fixtures, результатом и README

Один next() завершает дочернюю ветвь group и возвращает стек на корень к outside.

Перейти из вложенной ветви к корневому листуСамостоятельный пример
<?php
$walk = new RecursiveIteratorIterator(new RecursiveArrayIterator(['group' => ['inside' => 'x'], 'outside' => 'y']));
$walk->rewind();
echo $walk->key(), '; depth=', $walk->getDepth(), "\n";
$walk->next();
echo $walk->key(), '; depth=', $walk->getDepth(), "\n";
Ожидаемый результат
inside; depth=1
outside; depth=0

Вызывающему коду не нужно вручную делать endChildren: обходчик управляет стеком.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveIteratorIterator::next

(PHP 5, PHP 7, PHP 8) RecursiveIteratorIterator::next — Move forward to the next element

Description

public function RecursiveIteratorIterator::next(): void

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

No value is returned.

Связанные карточки: RecursiveIteratorIterator::beginChildren, RecursiveIteratorIterator::beginIteration, RecursiveIteratorIterator::callGetChildren, RecursiveIteratorIterator::callHasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveIteratorIterator::nextElementRecursiveIteratorIterator::nextElement: Hook вызывается для каждого узла, готового к выдаче выбранным режимом. Работа с рекурсивного стека.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveIteratorIterator::nextElement(): void

RecursiveIteratorIterator::nextElement. Hook вызывается для каждого узла, готового к выдаче выбранным режимом. nextElement() вызывается при готовности очередного элемента к выдаче. В LEAVES_ONLY это три строки A/B/C. Во второй независимой ситуации: Для листа b hook видит глубину 1, для корневого c — 0. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveIteratorIterator::nextElement(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Точный тип возврата, особые значения и изменения по версиям перечислены в таблице и полном официальном контракте.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

nextElement() вызывается при готовности очередного элемента к выдаче. В LEAVES_ONLY это три строки A/B/C.

Отметить каждый готовый лист импортаСамостоятельный пример
<?php
class ItemWalk extends RecursiveIteratorIterator {
    public int $ready = 0;
    public function nextElement(): void { $this->ready++; }
}
$walk = new ItemWalk(new RecursiveArrayIterator(['rows' => ['A', 'B', 'C']]));
foreach ($walk as $_) { }
echo 'ready=', $walk->ready, "\n";
Ожидаемый результат
ready=3

Hook не заменяет current(): он сообщает о событии, а значение всё равно читается в foreach.

Скачать самостоятельный пример с fixtures, результатом и README

Для листа b hook видит глубину 1, для корневого c — 0.

Собрать глубины готовых значенийСамостоятельный пример
<?php
class DepthEventWalk extends RecursiveIteratorIterator {
    public array $depths = [];
    public function nextElement(): void { $this->depths[] = $this->getDepth(); }
}
$walk = new DepthEventWalk(new RecursiveArrayIterator(['a' => ['b' => 1], 'c' => 2]));
foreach ($walk as $_) { }
echo implode(', ', $walk->depths), "\n";
Ожидаемый результат
1, 0

Событие полезно для метрик обхода; помещать сетевой запрос в каждый nextElement дорого и рискованно.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveIteratorIterator::nextElement

(PHP 5 >= 5.1.0, PHP 7, PHP 8) RecursiveIteratorIterator::nextElement — Next element

Description

public function RecursiveIteratorIterator::nextElement(): void

Called when the next element is available.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

No value is returned.

Связанные карточки: RecursiveIteratorIterator::beginChildren, RecursiveIteratorIterator::beginIteration, RecursiveIteratorIterator::callGetChildren, RecursiveIteratorIterator::callHasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveIteratorIterator::rewindRecursiveIteratorIterator::rewind: Метод заново устанавливает первый доступный элемент всего соответствующего обхода. Работа с рекурсивного стека.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveIteratorIterator::rewind(): void

RecursiveIteratorIterator::rewind. Метод заново устанавливает первый доступный элемент всего соответствующего обхода. rewind() сбрасывает весь рекурсивный стек и снова ищет первый выдаваемый элемент x. Во второй независимой ситуации: Каждый rewind() строит стек заново и позволяет посчитать три листа повторно. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveIteratorIterator::rewind(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Повторяемость наследуется от источника; завершённый Generator не обязан перематываться.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

rewind() сбрасывает весь рекурсивный стек и снова ищет первый выдаваемый элемент x.

Вернуться к первому листу конфигурацииСамостоятельный пример
<?php
$walk = new RecursiveIteratorIterator(new RecursiveArrayIterator(['a' => ['x' => 1], 'b' => 2]));
$walk->rewind();
$walk->next();
echo 'До: ', $walk->key(), "\n";
$walk->rewind();
echo 'После: ', $walk->key(), "\n";
Ожидаемый результат
До: b
После: x

Повторяемость возможна потому, что RecursiveArrayIterator можно перемотать.

Скачать самостоятельный пример с fixtures, результатом и README

Каждый rewind() строит стек заново и позволяет посчитать три листа повторно.

Повторить подсчёт листьевСамостоятельный пример
<?php
$walk = new RecursiveIteratorIterator(new RecursiveArrayIterator(['items' => ['A', 'B', 'C']]));
$counts = [];
for ($pass = 0; $pass < 2; $pass++) {
    $walk->rewind();
    $count = 0;
    while ($walk->valid()) { $count++; $walk->next(); }
    $counts[] = $count;
}
echo implode(', ', $counts), "\n";
Ожидаемый результат
3, 3

Для Generator повторная перемотка после завершения может быть невозможна; контракт зависит от вложенного источника.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveIteratorIterator::rewind

(PHP 5, PHP 7, PHP 8) RecursiveIteratorIterator::rewind — Rewind the iterator to the first element of the top level inner iterator

Description

public function RecursiveIteratorIterator::rewind(): void

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

No value is returned.

Связанные карточки: RecursiveIteratorIterator::beginChildren, RecursiveIteratorIterator::beginIteration, RecursiveIteratorIterator::callGetChildren, RecursiveIteratorIterator::callHasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveIteratorIterator::setMaxDepthRecursiveIteratorIterator::setMaxDepth: Граница меняет разрешённый спуск Работа с рекурсивного стека.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveIteratorIterator::setMaxDepth(int $maxDepth = -1): void

RecursiveIteratorIterator::setMaxDepth. Граница меняет разрешённый спуск; -1 снова разрешает любую глубину. Максимум 1 разрешает уровни 0 и 1, но не спускается к driver на глубине 2. Во второй независимой ситуации: Значение -1 возвращает неограниченный спуск, поэтому глубокий c снова достигается. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
maxDepthМаксимальный разрешённый уровень, где корень равен 0. Значение -1 снимает ограничение; меньше -1 недопустимо.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveIteratorIterator::setMaxDepth(int $maxDepth = -1): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Значение меньше -1 вызывает исключение; 0 разрешает только нулевой уровень.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Максимум 1 разрешает уровни 0 и 1, но не спускается к driver на глубине 2.

Ограничить отчёт двумя уровнямиСамостоятельный пример
<?php
$walk = new RecursiveIteratorIterator(
    new RecursiveArrayIterator(['app' => ['cache' => ['driver' => 'file'], 'debug' => true], 'version' => '1']),
    RecursiveIteratorIterator::SELF_FIRST
);
$walk->setMaxDepth(1);
foreach ($walk as $key => $_) echo $walk->getDepth(), ':', $key, "\n";
Ожидаемый результат
0:app
1:cache
1:debug
0:version

В SELF_FIRST ветка cache всё равно видна как узел; её глубокое содержимое пропущено.

Скачать самостоятельный пример с fixtures, результатом и README

Значение -1 возвращает неограниченный спуск, поэтому глубокий c снова достигается.

Снять ранее установленную границуСамостоятельный пример
<?php
$walk = new RecursiveIteratorIterator(new RecursiveArrayIterator(['a' => ['b' => ['c' => 1]]]));
$walk->setMaxDepth(0);
$walk->setMaxDepth(-1);
foreach ($walk as $key => $value) echo $key, '=', $value, '; depth=', $walk->getDepth(), "\n";
Ожидаемый результат
c=1; depth=2

Значение меньше -1 вызывает исключение; оно не означает «ещё глубже».

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveIteratorIterator::setMaxDepth

(PHP 5 >= 5.1.0, PHP 7, PHP 8) RecursiveIteratorIterator::setMaxDepth — Set max depth

Description

public function RecursiveIteratorIterator::setMaxDepth(int $maxDepth = -1): void

Set the maximum allowed depth.

WarningThis function is currently not documented; only its argument list is available.

Parameters

maxDepth

The maximum allowed depth. -1 is used for any depth.

Return Values

No value is returned.

Errors/Exceptions

Emits an Exception if maxDepth is less than -1.

Связанные карточки: RecursiveIteratorIterator::beginChildren, RecursiveIteratorIterator::beginIteration, RecursiveIteratorIterator::callGetChildren, RecursiveIteratorIterator::callHasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveIteratorIterator::validRecursiveIteratorIterator::valid: false означает отсутствие текущей позиции Работа с рекурсивного стека.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveIteratorIterator::valid(): bool

RecursiveIteratorIterator::valid. false означает отсутствие текущей позиции; это обязательная граница перед current/key. valid() охраняет current/key в ручном цикле. После второго next() стек исчерпан и ответ false. Во второй независимой ситуации: Пустой RecursiveArrayIterator после rewind сразу даёт valid() === false. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveIteratorIterator::valid(): bool
Результатbool: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Точный тип возврата, особые значения и изменения по версиям перечислены в таблице и полном официальном контракте.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

valid() охраняет current/key в ручном цикле. После второго next() стек исчерпан и ответ false.

Остановить ручной обход на концеСамостоятельный пример
<?php
$walk = new RecursiveIteratorIterator(new RecursiveArrayIterator(['items' => ['A', 'B']]));
$walk->rewind();
while ($walk->valid()) {
    echo $walk->current(), "\n";
    $walk->next();
}
echo 'valid=', $walk->valid() ? 'true' : 'false', "\n";
Ожидаемый результат
A
B
valid=false

false означает конец обхода, а не ошибочное значение листа.

Скачать самостоятельный пример с fixtures, результатом и README

Пустой RecursiveArrayIterator после rewind сразу даёт valid() === false.

Проверить пустое деревоСамостоятельный пример
<?php
$walk = new RecursiveIteratorIterator(new RecursiveArrayIterator([]));
$walk->rewind();
echo $walk->valid() ? 'есть данные' : 'пусто', "\n";
Ожидаемый результат
пусто

Так пустой результат обрабатывается отдельно от листа null, который был бы валидным элементом.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveIteratorIterator::valid

(PHP 5, PHP 7, PHP 8) RecursiveIteratorIterator::valid — Check whether the current position is valid

Description

public function RecursiveIteratorIterator::valid(): bool

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

true if the current position is valid, otherwise false

Связанные карточки: RecursiveIteratorIterator::beginChildren, RecursiveIteratorIterator::beginIteration, RecursiveIteratorIterator::callGetChildren, RecursiveIteratorIterator::callHasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveRegexIterator::__constructRecursiveRegexIterator::__construct: Конструктор только связывает источник и режимы Работа с regex-фильтра дерева.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveRegexIterator::__construct(RecursiveIterator $iterator, string $pattern, int $mode = RecursiveRegexIterator::MATCH, int $flags = 0, int $pregFlags = 0)

RecursiveRegexIterator::__construct. Конструктор только связывает источник и режимы; фактическое чтение начинается при rewind/foreach. Конструктор принимает рекурсивный источник, pattern, mode, flags и pregFlags. USE_KEY означает сопоставление ключа. Во второй независимой ситуации: Вторая настройка оставляет parent zones и листья с форматом буква-дефис-две цифры. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
iteratorРекурсивный источник из сигнатуры. Объект не копируется: внешний класс управляет тем же курсором и вызывает его hasChildren()/getChildren().
patternPCRE-выражение с разделителями. При USE_KEY оно сопоставляется с ключом; parent тоже должен совпасть для разрешённого спуска.
modeДля рекурсивного обхода: LEAVES_ONLY/SELF_FIRST/CHILD_FIRST; для regex — форма совпадения MATCH/GET_MATCH/ALL_MATCHES/SPLIT/REPLACE.
flagsБитовая маска именно данного класса: выбор ключа/current, политика представления или CATCH_GET_CHILD. Совмещаются только документированные константы.
pregFlagsФлаги preg_match(), например PREG_OFFSET_CAPTURE; они могут изменить форму получаемого совпадения.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveRegexIterator::__construct(RecursiveIterator $iterator, string $pattern, int $mode = RecursiveRegexIterator::MATCH, int $flags = 0, int $pregFlags = 0)
РезультатКонструктор не возвращает прикладное значение; выражение new создаёт объект, который затем сохраняется в переменной.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Точный тип возврата, особые значения и изменения по версиям перечислены в таблице и полном официальном контракте.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Конструктор принимает рекурсивный источник, pattern, mode, flags и pregFlags. USE_KEY означает сопоставление ключа.

Создать фильтр конфигурационных ключейСамостоятельный пример
<?php
$filter = new RecursiveRegexIterator(
    new RecursiveArrayIterator(['app' => ['host' => 'localhost', 'port' => '8080', 'secret' => 'x']]),
    '/^(app|host|port)$/',
    RecursiveRegexIterator::MATCH,
    RecursiveRegexIterator::USE_KEY
);
foreach (new RecursiveIteratorIterator($filter) as $key => $value) echo $key, '=', $value, "\n";
Ожидаемый результат
host=localhost
port=8080

app включён в pattern для сохранения пути; в плоском LEAVES_ONLY выводятся только host и port.

Скачать самостоятельный пример с fixtures, результатом и README

Вторая настройка оставляет parent zones и листья с форматом буква-дефис-две цифры.

Создать фильтр кодов складских ячеекСамостоятельный пример
<?php
$filter = new RecursiveRegexIterator(
    new RecursiveArrayIterator(['zones' => ['A-01' => 4, 'bad' => 9, 'B-12' => 2]]),
    '/^(zones|[A-Z]-\d{2})$/',
    RecursiveRegexIterator::MATCH,
    RecursiveRegexIterator::USE_KEY
);
foreach (new RecursiveIteratorIterator($filter) as $key => $value) echo $key, '=', $value, "\n";
Ожидаемый результат
A-01=4
B-12=2

Совпадение имени не гарантирует существование ячейки в базе: это только синтаксический фильтр.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveRegexIterator::__construct

(PHP 5 >= 5.2.0, PHP 7, PHP 8) RecursiveRegexIterator::__construct — Creates a new RecursiveRegexIterator

Description

public function RecursiveRegexIterator::__construct(    RecursiveIterator $iterator,    string $pattern,    int $mode = RecursiveRegexIterator::MATCH,    int $flags = 0,    int $pregFlags = 0)

Creates a new regular expression iterator.

Parameters

iterator

The recursive iterator to apply this regex filter to.

pattern

The regular expression to match.

mode

Operation mode, see RegexIterator::setMode() for a list of modes.

flags

Special flags, see RegexIterator::setFlags() for a list of available flags.

pregFlags

The regular expression flags. These flags depend on the operation mode parameter:

RegexIterator preg_flags

operation mode available flags

RecursiveRegexIterator::ALL_MATCHES

See preg_match_all().

RecursiveRegexIterator::GET_MATCH

See preg_match().

RecursiveRegexIterator::MATCH

See preg_match().

RecursiveRegexIterator::REPLACE

none.

RecursiveRegexIterator::SPLIT

See preg_split().

See Also

preg_match() - Perform a regular expression match

preg_match_all() - Perform a global regular expression match

preg_replace() - Perform a regular expression search and replace

preg_split() - Split string by a regular expression

Связанные карточки: RecursiveRegexIterator::getChildren, RecursiveRegexIterator::hasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveRegexIterator::getChildrenRecursiveRegexIterator::getChildren: Метод открывает ровно следующий уровень и возвращает новый рекурсивный итератор. Работа с regex-фильтра дерева.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveRegexIterator::getChildren(): RecursiveRegexIterator

RecursiveRegexIterator::getChildren. Метод открывает ровно следующий уровень и возвращает новый рекурсивный итератор. getChildren() возвращает RecursiveRegexIterator с тем же pattern и режимами для уровня app. Во второй независимой ситуации: Дочерний regex-итератор выбирает A-01 и отбрасывает wrong. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveRegexIterator::getChildren(): RecursiveRegexIterator
РезультатRecursiveRegexIterator: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Сначала проверяйте hasChildren(), если форма данных заранее не гарантирована.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

getChildren() возвращает RecursiveRegexIterator с тем же pattern и режимами для уровня app.

Перенести regex на дочерние настройкиСамостоятельный пример
<?php
$filter = new RecursiveRegexIterator(
    new RecursiveArrayIterator(['app' => ['host' => 'localhost', 'secret' => 'x']]),
    '/^(app|host)$/',
    RecursiveRegexIterator::MATCH,
    RecursiveRegexIterator::USE_KEY
);
$filter->rewind();
$children = $filter->getChildren();
foreach ($children as $key => $value) echo $key, '=', $value, "\n";
Ожидаемый результат
host=localhost

secret исключается на дочернем уровне; новый объект остаётся ленивым.

Скачать самостоятельный пример с fixtures, результатом и README

Дочерний regex-итератор выбирает A-01 и отбрасывает wrong.

Перенести regex на дочерние кодыСамостоятельный пример
<?php
$filter = new RecursiveRegexIterator(
    new RecursiveArrayIterator(['zones' => ['A-01' => 4, 'wrong' => 8]]),
    '/^(zones|[A-Z]-\d{2})$/',
    RecursiveRegexIterator::MATCH,
    RecursiveRegexIterator::USE_KEY
);
$filter->rewind();
$children = $filter->getChildren();
foreach ($children as $key => $value) echo $key, '=', $value, "\n";
Ожидаемый результат
A-01=4

Для сложных типизированных правил callback часто читается лучше регулярного выражения.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveRegexIterator::getChildren

(PHP 5 >= 5.2.0, PHP 7, PHP 8) RecursiveRegexIterator::getChildren — Returns an iterator for the current entry

Description

public function RecursiveRegexIterator::getChildren(): RecursiveRegexIterator

Returns an iterator for the current iterator entry.

Parameters

This function has no parameters.

Return Values

An iterator for the current entry, if it can be iterated over by the inner iterator.

Errors/Exceptions

An InvalidArgumentException will be thrown if the current entry does not contain a value that can be iterated over by the inner iterator.

See Also

RecursiveRegexIterator::hasChildren() - Returns whether an iterator can be obtained for the current entry

Связанные карточки: RecursiveRegexIterator::__construct, RecursiveRegexIterator::hasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveRegexIterator::hasChildrenRecursiveRegexIterator::hasChildren: Ответ относится к текущей позиции и не двигает курсор. Работа с regex-фильтра дерева.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveRegexIterator::hasChildren(): bool

RecursiveRegexIterator::hasChildren. Ответ относится к текущей позиции и не двигает курсор. services совпадает с pattern и остаётся ветвью. hasChildren() подтверждает, что можно создать дочерний regex-итератор. Во второй независимой ситуации: Один и тот же regex принимает zones и A-01, но наличие детей определяется структурой их значений. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveRegexIterator::hasChildren(): bool
Результатbool: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. У файлов явно передавайте false, если политика запрещает следовать по символическим ссылкам.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

services совпадает с pattern и остаётся ветвью. hasChildren() подтверждает, что можно создать дочерний regex-итератор.

Проверить принятого родителя servicesСамостоятельный пример
<?php
$filter = new RecursiveRegexIterator(
    new RecursiveArrayIterator(['services' => ['cache' => 'redis']]),
    '/^(services|cache)$/',
    RecursiveRegexIterator::MATCH,
    RecursiveRegexIterator::USE_KEY
);
$filter->rewind();
echo $filter->key(), ':', $filter->hasChildren() ? 'branch' : 'leaf', "\n";
Ожидаемый результат
services:branch

Если parent не совпадёт, фильтр может скрыть всю ветвь до чтения нужного листа.

Скачать самостоятельный пример с fixtures, результатом и README

Один и тот же regex принимает zones и A-01, но наличие детей определяется структурой их значений.

Отличить ветку zones от кода ячейкиСамостоятельный пример
<?php
$filter = new RecursiveRegexIterator(
    new RecursiveArrayIterator(['zones' => ['A-01' => 4]]),
    '/^(zones|[A-Z]-\d{2})$/',
    RecursiveRegexIterator::MATCH,
    RecursiveRegexIterator::USE_KEY
);
$filter->rewind();
echo 'zones=', $filter->hasChildren() ? 'branch' : 'leaf', "\n";
$child = $filter->getChildren();
$child->rewind();
echo 'A-01=', $child->hasChildren() ? 'branch' : 'leaf', "\n";
Ожидаемый результат
zones=branch
A-01=leaf

hasChildren() не сообщает, почему строка совпала с pattern; это отдельная ответственность accept().

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveRegexIterator::hasChildren

(PHP 5 >= 5.2.0, PHP 7, PHP 8) RecursiveRegexIterator::hasChildren — Returns whether an iterator can be obtained for the current entry

Description

public function RecursiveRegexIterator::hasChildren(): bool

Returns whether an iterator can be obtained for the current entry. This iterator can be obtained via RecursiveRegexIterator::getChildren().

Parameters

This function has no parameters.

Return Values

Returns true if an iterator can be obtained for the current entry, otherwise returns false.

See Also

RecursiveRegexIterator::getChildren() - Returns an iterator for the current entry

Связанные карточки: RecursiveRegexIterator::__construct, RecursiveRegexIterator::getChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveTreeIterator::beginChildrenRecursiveTreeIterator::beginChildren: Hook отмечает вход в дочерний уровень после подготовки его курсора. Работа с текстового дерева.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveTreeIterator::beginChildren(): void

RecursiveTreeIterator::beginChildren. Hook отмечает вход в дочерний уровень после подготовки его курсора. beginChildren() срабатывает при входе в shop и catalog, то есть два раза. Во второй независимой ситуации: При входе в app активная глубина детей равна 1, при входе в cache — 2. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveTreeIterator::beginChildren(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Точный тип возврата, особые значения и изменения по версиям перечислены в таблице и полном официальном контракте.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

beginChildren() срабатывает при входе в shop и catalog, то есть два раза.

Посчитать входы в дочерние группы дереваСамостоятельный пример
<?php
class EnterTree extends RecursiveTreeIterator {
    public int $enters = 0;
    public function beginChildren(): void { $this->enters++; }
}
$tree = new EnterTree(new RecursiveArrayIterator(['shop' => ['catalog' => ['lamp' => '2'], 'cart' => '0']]));
foreach ($tree as $_) { }
echo 'enters=', $tree->enters, "\n";
Ожидаемый результат
enters=2

Hook относится к переходу уровней; число отображённых узлов больше.

Скачать самостоятельный пример с fixtures, результатом и README

При входе в app активная глубина детей равна 1, при входе в cache — 2.

Отметить глубины открытия конфигурацииСамостоятельный пример
<?php
class EnterDepthTree extends RecursiveTreeIterator {
    public array $depths = [];
    public function beginChildren(): void { $this->depths[] = $this->getDepth(); }
}
$tree = new EnterDepthTree(new RecursiveArrayIterator(['app' => ['cache' => ['driver' => 'file']]]));
foreach ($tree as $_) { }
echo implode(', ', $tree->depths), "\n";
Ожидаемый результат
1, 2

Эти значения технические; подпись пользовательской категории всё равно берётся из ключа.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveTreeIterator::beginChildren

(PHP 5 >= 5.3.0, PHP 7, PHP 8) RecursiveTreeIterator::beginChildren — Begin children

Description

public function RecursiveTreeIterator::beginChildren(): void

Called when recursing one level down.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

No value is returned.

Связанные карточки: RecursiveTreeIterator::beginIteration, RecursiveTreeIterator::callGetChildren, RecursiveTreeIterator::callHasChildren, RecursiveTreeIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveTreeIterator::beginIterationRecursiveTreeIterator::beginIteration: Hook срабатывает один раз перед выдачей первого элемента полного обхода. Работа с текстового дерева.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveTreeIterator::beginIteration(): void

RecursiveTreeIterator::beginIteration. Hook срабатывает один раз перед выдачей первого элемента полного обхода. beginIteration() вызывается один раз после первого rewind. В default SELF_FIRST дерево выдаёт parent app и leaf debug. Во второй независимой ситуации: Второй hook сохраняет событие до трёх SELF_FIRST узлов: orders, A и B. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveTreeIterator::beginIteration(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Точный тип возврата, особые значения и изменения по версиям перечислены в таблице и полном официальном контракте.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

beginIteration() вызывается один раз после первого rewind. В default SELF_FIRST дерево выдаёт parent app и leaf debug.

Отметить начало построения дерева конфигурацииСамостоятельный пример
<?php
class ConfigTreeStart extends RecursiveTreeIterator {
    public int $starts = 0;
    public function beginIteration(): void { $this->starts++; echo "TREE START\n"; }
}
$tree = new ConfigTreeStart(new RecursiveArrayIterator(['app' => ['debug' => 'on']]));
foreach ($tree as $_) echo "node\n";
echo 'starts=', $tree->starts, "\n";
Ожидаемый результат
TREE START
node
node
starts=1

Hook позволяет поставить заголовок перед всем деревом; не используйте его для заголовка каждой ветви.

Скачать самостоятельный пример с fixtures, результатом и README

Второй hook сохраняет событие до трёх SELF_FIRST узлов: orders, A и B.

Открыть блок отчёта перед первым узломСамостоятельный пример
<?php
class ReportTreeStart extends RecursiveTreeIterator {
    public array $events = [];
    public function beginIteration(): void { $this->events[] = 'open-report'; }
}
$tree = new ReportTreeStart(new RecursiveArrayIterator(['orders' => ['A' => '2', 'B' => '1']]));
$count = 0;
foreach ($tree as $_) $count++;
echo implode(',', $tree->events), '; nodes=', $count, "\n";
Ожидаемый результат
open-report; nodes=3

Если нужен только листовой отчёт, передайте LEAVES_ONLY в конструктор, а не фильтруйте Array после выдачи.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveTreeIterator::beginIteration

(PHP 5 >= 5.3.0, PHP 7, PHP 8) RecursiveTreeIterator::beginIteration — Begin iteration

Description

public function RecursiveTreeIterator::beginIteration(): RecursiveIterator

Called when iteration begins (after the first RecursiveTreeIterator::rewind() call).

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

A RecursiveIterator.

Связанные карточки: RecursiveTreeIterator::beginChildren, RecursiveTreeIterator::callGetChildren, RecursiveTreeIterator::callHasChildren, RecursiveTreeIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveTreeIterator::callGetChildrenRecursiveTreeIterator::callGetChildren: Это явный вызов getChildren() активного источника Работа с текстового дерева.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveTreeIterator::callGetChildren(): ?RecursiveIterator

RecursiveTreeIterator::callGetChildren. Это явный вызов getChildren() активного источника; обычный foreach делает его сам. callGetChildren() возвращает RecursiveIterator активного parent shop до декоративного форматирования строк. Во второй независимой ситуации: Дочерний источник возвращает исходные ключи cache/debug и значения без префикса дерева. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveTreeIterator::callGetChildren(): ?RecursiveIterator
Результат?RecursiveIterator: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Прямой вызов нужен в основном подклассу и диагностике; не рассинхронизируйте внутренний курсор.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

callGetChildren() возвращает RecursiveIterator активного parent shop до декоративного форматирования строк.

Получить детей shop из текущего дереваСамостоятельный пример
<?php
$tree = new RecursiveTreeIterator(new RecursiveArrayIterator(['shop' => ['catalog' => 'yes', 'cart' => 'yes']]));
$tree->rewind();
$children = $tree->callGetChildren();
echo implode(', ', array_keys(iterator_to_array($children))), "\n";
Ожидаемый результат
catalog, cart

Это диагностический доступ к источнику; обычный RecursiveTreeIterator вызывает его сам.

Скачать самостоятельный пример с fixtures, результатом и README

Дочерний источник возвращает исходные ключи cache/debug и значения без префикса дерева.

Получить детей блока appСамостоятельный пример
<?php
$tree = new RecursiveTreeIterator(new RecursiveArrayIterator(['app' => ['cache' => 'file', 'debug' => 'on']]));
$tree->rewind();
$children = $tree->callGetChildren();
foreach ($children as $key => $value) echo $key, '=', $value, "\n";
Ожидаемый результат
cache=file
debug=on

Перед прямым вызовом нужно знать, что current имеет детей; иначе результат может быть null или исключением источника.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveTreeIterator::callGetChildren

(PHP 5 >= 5.3.0, PHP 7, PHP 8) RecursiveTreeIterator::callGetChildren — Get children

Description

public function RecursiveTreeIterator::callGetChildren(): RecursiveIterator

Gets children of the current element.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

A RecursiveIterator.

Связанные карточки: RecursiveTreeIterator::beginChildren, RecursiveTreeIterator::beginIteration, RecursiveTreeIterator::callHasChildren, RecursiveTreeIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveTreeIterator::callHasChildrenRecursiveTreeIterator::callHasChildren: Это явный вызов hasChildren() активного внутреннего рекурсивного источника. Работа с текстового дерева.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveTreeIterator::callHasChildren(): bool

RecursiveTreeIterator::callHasChildren. Это явный вызов hasChildren() активного внутреннего рекурсивного источника. На первом SELF_FIRST узле shop метод делегирует hasChildren() текущему RecursiveArrayIterator. Во второй независимой ситуации: На status метод возвращает false: строка является конечным значением. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveTreeIterator::callHasChildren(): bool
Результатbool: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Ответ структурный; он не гарантирует, что дочерний ресурс удастся прочитать.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

На первом SELF_FIRST узле shop метод делегирует hasChildren() текущему RecursiveArrayIterator.

Проверить parent shop через деревоСамостоятельный пример
<?php
$tree = new RecursiveTreeIterator(new RecursiveArrayIterator(['shop' => ['cart' => '0'], 'status' => 'open']));
$tree->rewind();
echo $tree->key(), ':', $tree->callHasChildren() ? 'branch' : 'leaf', "\n";
Ожидаемый результат
shop:branch

true объясняет, почему дерево позже вызовет callGetChildren() и добавит префикс следующего уровня.

Скачать самостоятельный пример с fixtures, результатом и README

На status метод возвращает false: строка является конечным значением.

Проверить лист status через деревоСамостоятельный пример
<?php
$tree = new RecursiveTreeIterator(new RecursiveArrayIterator(['shop' => ['cart' => '0'], 'status' => 'open']));
foreach ($tree as $key => $_) if ($key === 'status') echo $tree->callHasChildren() ? 'branch' : 'leaf', "\n";
Ожидаемый результат
leaf

false — штатный конец ветви, а не ошибка графического форматирования.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveTreeIterator::callHasChildren

(PHP 5 >= 5.3.0, PHP 7, PHP 8) RecursiveTreeIterator::callHasChildren — Has children

Description

public function RecursiveTreeIterator::callHasChildren(): bool

Called for each element to test whether it has children.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

true if there are children, otherwise false

Связанные карточки: RecursiveTreeIterator::beginChildren, RecursiveTreeIterator::beginIteration, RecursiveTreeIterator::callGetChildren, RecursiveTreeIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveTreeIterator::__constructRecursiveTreeIterator::__construct: Конструктор только связывает источник и режимы Работа с текстового дерева.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveTreeIterator::__construct(RecursiveIterator|IteratorAggregate $iterator, int $flags = RecursiveTreeIterator::BYPASS_KEY, int $cachingIteratorFlags = CachingIterator::CATCH_GET_CHILD, int $mode = RecursiveTreeIterator::SELF_FIRST)

RecursiveTreeIterator::__construct. Конструктор только связывает источник и режимы; фактическое чтение начинается при rewind/foreach. Конструктор получает RecursiveIterator, флаги представления, флаги внутреннего кэша и режим рекурсивного обхода. Во второй независимой ситуации: SELF_FIRST показывает parent shop до его cart, поэтому в entry родителя видно строковое Array. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
iteratorРекурсивный источник из сигнатуры. Объект не копируется: внешний класс управляет тем же курсором и вызывает его hasChildren()/getChildren().
flagsБитовая маска именно данного класса: выбор ключа/current, политика представления или CATCH_GET_CHILD. Совмещаются только документированные константы.
cachingIteratorFlagsФлаги внутреннего RecursiveCachingIterator. CATCH_GET_CHILD меняет обработку исключений при открытии детей.
modeДля рекурсивного обхода: LEAVES_ONLY/SELF_FIRST/CHILD_FIRST; для regex — форма совпадения MATCH/GET_MATCH/ALL_MATCHES/SPLIT/REPLACE.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveTreeIterator::__construct(RecursiveIterator|IteratorAggregate $iterator, int $flags = RecursiveTreeIterator::BYPASS_KEY, int $cachingIteratorFlags = CachingIterator::CATCH_GET_CHILD, int $mode = RecursiveTreeIterator::SELF_FIRST)
РезультатКонструктор не возвращает прикладное значение; выражение new создаёт объект, который затем сохраняется в переменной.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Точный тип возврата, особые значения и изменения по версиям перечислены в таблице и полном официальном контракте.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Конструктор получает RecursiveIterator, флаги представления, флаги внутреннего кэша и режим рекурсивного обхода.

Создать дерево листьев конфигурацииСамостоятельный пример
<?php
$tree = new RecursiveTreeIterator(
    new RecursiveArrayIterator(['app' => ['cache' => 'file', 'debug' => 'on'], 'version' => '1']),
    RecursiveTreeIterator::BYPASS_KEY,
    CachingIterator::CATCH_GET_CHILD,
    RecursiveTreeIterator::LEAVES_ONLY
);
foreach ($tree as $key => $value) echo $key, ':', $value, "\n";
Ожидаемый результат
cache:| |-file
debug:| \-on
version:\-1

BYPASS_KEY оставляет ключи cache/debug/version чистыми, а current() получает графический префикс.

Скачать самостоятельный пример с fixtures, результатом и README

SELF_FIRST показывает parent shop до его cart, поэтому в entry родителя видно строковое Array.

Создать SELF_FIRST дерево со всеми узламиСамостоятельный пример
<?php
$tree = new RecursiveTreeIterator(
    new RecursiveArrayIterator(['shop' => ['cart' => '0'], 'status' => 'open']),
    RecursiveTreeIterator::BYPASS_KEY,
    CachingIterator::CATCH_GET_CHILD,
    RecursiveTreeIterator::SELF_FIRST
);
foreach ($tree as $key => $value) echo $key, ':', $value, "\n";
Ожидаемый результат
shop:|-Array
cart:| \-0
status:\-open

Для пользовательского интерфейса имя узла обычно берут из key(), а current() листа — из значения; Array не следует выдавать как готовое описание категории.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveTreeIterator::__construct

(PHP 5 >= 5.3.0, PHP 7, PHP 8) RecursiveTreeIterator::__construct — Construct a RecursiveTreeIterator

Description

public function RecursiveTreeIterator::__construct(    RecursiveIterator|IteratorAggregate $iterator,    int $flags = RecursiveTreeIterator::BYPASS_KEY,    int $cachingIteratorFlags = CachingIterator::CATCH_GET_CHILD,    int $mode = RecursiveTreeIterator::SELF_FIRST)

Constructs a new RecursiveTreeIterator from the supplied recursive iterator.

WarningThis function is currently not documented; only its argument list is available.

Parameters

iterator

The RecursiveIterator or IteratorAggregate to iterate over.

flags

Flags may be provided which will affect the behavior of some methods. A list of the flags can found under RecursiveTreeIterator predefined constants.

caching_it_flags

Flags to affect the behavior of the RecursiveCachingIterator used internally.

mode

Flags to affect the behavior of the RecursiveIteratorIterator used internally.

Связанные карточки: RecursiveTreeIterator::beginChildren, RecursiveTreeIterator::beginIteration, RecursiveTreeIterator::callGetChildren, RecursiveTreeIterator::callHasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveTreeIterator::currentRecursiveTreeIterator::current: Метод читает текущее значение без продвижения Работа с текстового дерева.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveTreeIterator::current(): mixed

RecursiveTreeIterator::current. Метод читает текущее значение без продвижения; у дерева оно может быть уже украшено. current() соединяет getPrefix(), getEntry() и getPostfix(). Для единственного листа prefix равен \-. Во второй независимой ситуации: Для соседей current() различает продолжающуюся и последнюю ветвь, а inner current сохраняет A/B. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveTreeIterator::current(): mixed
Результатmixed: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Не сохраняйте украшенную строку RecursiveTreeIterator как исходное бизнес-значение.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

current() соединяет getPrefix(), getEntry() и getPostfix(). Для единственного листа prefix равен \-.

Получить украшенное текущее значениеСамостоятельный пример
<?php
$tree = new RecursiveTreeIterator(
    new RecursiveArrayIterator(['app' => ['debug' => 'on']]),
    RecursiveTreeIterator::BYPASS_KEY,
    CachingIterator::CATCH_GET_CHILD,
    RecursiveTreeIterator::LEAVES_ONLY
);
$tree->rewind();
echo 'current=', $tree->current(), "\n";
Ожидаемый результат
current=  \-on

Это строка для вывода; исходное значение on доступно через внутренний итератор.

Скачать самостоятельный пример с fixtures, результатом и README

Для соседей current() различает продолжающуюся и последнюю ветвь, а inner current сохраняет A/B.

Сравнить украшенное и исходное значениеСамостоятельный пример
<?php
$tree = new RecursiveTreeIterator(
    new RecursiveArrayIterator(['group' => ['first' => 'A', 'last' => 'B']]),
    RecursiveTreeIterator::BYPASS_KEY,
    CachingIterator::CATCH_GET_CHILD,
    RecursiveTreeIterator::LEAVES_ONLY
);
foreach ($tree as $key => $decorated) {
    echo $key, ': decorated=', $decorated, '; raw=', $tree->getInnerIterator()->current(), "\n";
}
Ожидаемый результат
first: decorated=  |-A; raw=A
last: decorated=  \-B; raw=B

Не сохраняйте decorated как бизнес-значение: префикс предназначен для представления.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveTreeIterator::current

(PHP 5 >= 5.3.0, PHP 7, PHP 8) RecursiveTreeIterator::current — Get current element

Description

public function RecursiveTreeIterator::current(): mixed

Gets the current element prefixed and postfixed.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

Returns the current element prefixed and postfixed.

Связанные карточки: RecursiveTreeIterator::beginChildren, RecursiveTreeIterator::beginIteration, RecursiveTreeIterator::callGetChildren, RecursiveTreeIterator::callHasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveTreeIterator::endChildrenRecursiveTreeIterator::endChildren: Hook отмечает возврат после полного исчерпания одного дочернего уровня. Работа с текстового дерева.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveTreeIterator::endChildren(): void

RecursiveTreeIterator::endChildren. Hook отмечает возврат после полного исчерпания одного дочернего уровня. После последнего ребёнка закрываются catalog и shop, поэтому endChildren() вызывается дважды. Во второй независимой ситуации: Два close соответствуют завершению cache и app после обработки их детей. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveTreeIterator::endChildren(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Точный тип возврата, особые значения и изменения по версиям перечислены в таблице и полном официальном контракте.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

После последнего ребёнка закрываются catalog и shop, поэтому endChildren() вызывается дважды.

Посчитать закрытые группы дереваСамостоятельный пример
<?php
class LeaveTree extends RecursiveTreeIterator {
    public int $leaves = 0;
    public function endChildren(): void { $this->leaves++; }
}
$tree = new LeaveTree(new RecursiveArrayIterator(['shop' => ['catalog' => ['lamp' => '2']]]));
foreach ($tree as $_) { }
echo 'closed=', $tree->leaves, "\n";
Ожидаемый результат
closed=2

Это удобно для генераторов закрывающих тегов, если каждый beginChildren имеет парный выход.

Скачать самостоятельный пример с fixtures, результатом и README

Два close соответствуют завершению cache и app после обработки их детей.

Записать порядок выхода из конфигурацииСамостоятельный пример
<?php
class LeaveDepthTree extends RecursiveTreeIterator {
    public array $events = [];
    public function endChildren(): void { $this->events[] = 'close'; }
}
$tree = new LeaveDepthTree(new RecursiveArrayIterator(['app' => ['cache' => ['driver' => 'file'], 'debug' => 'on']]));
foreach ($tree as $_) { }
echo implode(' > ', $tree->events), "\n";
Ожидаемый результат
close > close

Сам hook не сообщает бизнес-имя закрываемого parent; при необходимости подкласс хранит собственный стек.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveTreeIterator::endChildren

(PHP 5 >= 5.3.0, PHP 7, PHP 8) RecursiveTreeIterator::endChildren — End children

Description

public function RecursiveTreeIterator::endChildren(): void

Called when end recursing one level.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

No value is returned.

Связанные карточки: RecursiveTreeIterator::beginChildren, RecursiveTreeIterator::beginIteration, RecursiveTreeIterator::callGetChildren, RecursiveTreeIterator::callHasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveTreeIterator::endIterationRecursiveTreeIterator::endIteration: Hook срабатывает после исчерпания полного обхода, когда valid() стал false. Работа с текстового дерева.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveTreeIterator::endIteration(): void

RecursiveTreeIterator::endIteration. Hook срабатывает после исчерпания полного обхода, когда valid() стал false. endIteration() вызывается, когда valid() впервые становится false после app/debug. Во второй независимой ситуации: nextElement считает три готовых SELF_FIRST узла, endIteration печатает итог. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveTreeIterator::endIteration(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Точный тип возврата, особые значения и изменения по версиям перечислены в таблице и полном официальном контракте.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

endIteration() вызывается, когда valid() впервые становится false после app/debug.

Закрыть дерево после последнего узлаСамостоятельный пример
<?php
class ConfigTreeEnd extends RecursiveTreeIterator {
    public function endIteration(): void { echo "TREE END\n"; }
}
$tree = new ConfigTreeEnd(new RecursiveArrayIterator(['app' => ['debug' => 'on']]));
foreach ($tree as $key => $_) echo $key, "\n";
Ожидаемый результат
app
debug
TREE END

Финальный маркер относится ко всему дереву. При преждевременном break полный финальный путь вызовов может отличаться.

Скачать самостоятельный пример с fixtures, результатом и README

nextElement считает три готовых SELF_FIRST узла, endIteration печатает итог.

Вывести итоговое число строк дереваСамостоятельный пример
<?php
class CountTreeEnd extends RecursiveTreeIterator {
    public int $nodes = 0;
    public function nextElement(): void { $this->nodes++; }
    public function endIteration(): void { echo 'nodes=', $this->nodes, "\n"; }
}
$tree = new CountTreeEnd(new RecursiveArrayIterator(['shop' => ['cart' => '0'], 'status' => 'open']));
foreach ($tree as $_) { }
Ожидаемый результат
nodes=3

Счётчик хранится в объекте обхода и не требует глобальной переменной.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveTreeIterator::endIteration

(PHP 5 >= 5.3.0, PHP 7, PHP 8) RecursiveTreeIterator::endIteration — End iteration

Description

public function RecursiveTreeIterator::endIteration(): void

Called when the iteration ends (when RecursiveTreeIterator::valid() first returns false)

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

No value is returned.

Связанные карточки: RecursiveTreeIterator::beginChildren, RecursiveTreeIterator::beginIteration, RecursiveTreeIterator::callGetChildren, RecursiveTreeIterator::callHasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveTreeIterator::getEntryRecursiveTreeIterator::getEntry: Возвращается строковая часть текущего узла без линий prefix и без postfix. Работа с текстового дерева.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveTreeIterator::getEntry(): string

RecursiveTreeIterator::getEntry. Возвращается строковая часть текущего узла без линий prefix и без postfix. getEntry() возвращает строковую часть текущего исходного значения без prefix/postfix. Во второй независимой ситуации: В SELF_FIRST текущий parent group имеет строковое entry Array, потому что исходное значение — массив. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveTreeIterator::getEntry(): string
Результатstring: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Точный тип возврата, особые значения и изменения по версиям перечислены в таблице и полном официальном контракте.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

getEntry() возвращает строковую часть текущего исходного значения без prefix/postfix.

Извлечь часть строки без ветвейСамостоятельный пример
<?php
$tree = new RecursiveTreeIterator(
    new RecursiveArrayIterator(['group' => ['item' => 'value']]),
    RecursiveTreeIterator::BYPASS_KEY,
    CachingIterator::CATCH_GET_CHILD,
    RecursiveTreeIterator::LEAVES_ONLY
);
$tree->rewind();
echo 'entry=', $tree->getEntry(), '; current=', $tree->current(), "\n";
Ожидаемый результат
entry=value; current=  \-value

В данном leaf это value; current() дополнительно содержит \-.

Скачать самостоятельный пример с fixtures, результатом и README

В SELF_FIRST текущий parent group имеет строковое entry Array, потому что исходное значение — массив.

Получить entry для родительского массиваСамостоятельный пример
<?php
$tree = new RecursiveTreeIterator(new RecursiveArrayIterator(['group' => ['item' => 'value']]));
$tree->rewind();
echo 'key=', $tree->key(), '; entry=', $tree->getEntry(), "\n";
Ожидаемый результат
key=group; entry=Array

Для понятной подписи parent используйте key() или собственный formatter, а не слово Array.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveTreeIterator::getEntry

(PHP 5 >= 5.3.0, PHP 7, PHP 8) RecursiveTreeIterator::getEntry — Get current entry

Description

public function RecursiveTreeIterator::getEntry(): string

Gets the part of the tree built for the current element.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

Returns the part of the tree built for the current element.

Связанные карточки: RecursiveTreeIterator::beginChildren, RecursiveTreeIterator::beginIteration, RecursiveTreeIterator::callGetChildren, RecursiveTreeIterator::callHasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveTreeIterator::getPostfixRecursiveTreeIterator::getPostfix: Возвращается точная общая строка после entry Работа с текстового дерева.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveTreeIterator::getPostfix(): string

RecursiveTreeIterator::getPostfix. Возвращается точная общая строка после entry; по умолчанию она пуста. По умолчанию getPostfix() возвращает пустую строку длины 0. Во второй независимой ситуации: После setPostfix() метод возвращает точную строку с ведущим пробелом. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveTreeIterator::getPostfix(): string
Результатstring: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Точный тип возврата, особые значения и изменения по версиям перечислены в таблице и полном официальном контракте.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

По умолчанию getPostfix() возвращает пустую строку длины 0.

Проверить пустой postfix по умолчаниюСамостоятельный пример
<?php
$tree = new RecursiveTreeIterator(new RecursiveArrayIterator(['status' => 'open']));
$tree->rewind();
echo 'length=', strlen($tree->getPostfix()), "\n";
Ожидаемый результат
length=0

Новая строка также не добавляется автоматически: её печатает echo или задаёт setPostfix().

Скачать самостоятельный пример с fixtures, результатом и README

После setPostfix() метод возвращает точную строку с ведущим пробелом.

Прочитать настроенный суффикс строкиСамостоятельный пример
<?php
$tree = new RecursiveTreeIterator(new RecursiveArrayIterator(['status' => 'open']));
$tree->setPostfix(' <end>');
$tree->rewind();
echo json_encode($tree->getPostfix()), "\n";
Ожидаемый результат
" <end>"

Суффикс общий для всех узлов этого объекта, а не вычисляется отдельно по типу значения.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveTreeIterator::getPostfix

(PHP 5 >= 5.3.0, PHP 7, PHP 8) RecursiveTreeIterator::getPostfix — Get the postfix

Description

public function RecursiveTreeIterator::getPostfix(): string

Gets the string to place after the current element.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

Returns the string to place after the current element.

Связанные карточки: RecursiveTreeIterator::beginChildren, RecursiveTreeIterator::beginIteration, RecursiveTreeIterator::callGetChildren, RecursiveTreeIterator::callHasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveTreeIterator::getPrefixRecursiveTreeIterator::getPrefix: Возвращаются только линии и окончания ветви, вычисленные из позиции и соседей. Работа с текстового дерева.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveTreeIterator::getPrefix(): string

RecursiveTreeIterator::getPrefix. Возвращаются только линии и окончания ветви, вычисленные из позиции и соседей. getPrefix() показывает только графическую часть: |- для элемента с соседом и \- для последнего. Во второй независимой ситуации: У x prefix содержит вертикальное продолжение корневого соседа right и окончание глубокой ветви. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveTreeIterator::getPrefix(): string
Результатstring: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Точный тип возврата, особые значения и изменения по версиям перечислены в таблице и полном официальном контракте.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

getPrefix() показывает только графическую часть: |- для элемента с соседом и \- для последнего.

Разделить префикс и значение листаСамостоятельный пример
<?php
$tree = new RecursiveTreeIterator(
    new RecursiveArrayIterator(['group' => ['first' => 'A', 'last' => 'B']]),
    RecursiveTreeIterator::BYPASS_KEY,
    CachingIterator::CATCH_GET_CHILD,
    RecursiveTreeIterator::LEAVES_ONLY
);
foreach ($tree as $key => $_) echo $key, ': prefix=', json_encode($tree->getPrefix()), "\n";
Ожидаемый результат
first: prefix="  |-"
last: prefix="  \\-"

json_encode используется, чтобы обратная косая черта была видна однозначно.

Скачать самостоятельный пример с fixtures, результатом и README

У x prefix содержит вертикальное продолжение корневого соседа right и окончание глубокой ветви.

Увидеть вертикальную линию глубокой ветвиСамостоятельный пример
<?php
$tree = new RecursiveTreeIterator(
    new RecursiveArrayIterator(['left' => ['deep' => ['x' => '1']], 'right' => '2']),
    RecursiveTreeIterator::BYPASS_KEY,
    CachingIterator::CATCH_GET_CHILD,
    RecursiveTreeIterator::LEAVES_ONLY
);
foreach ($tree as $key => $_) echo $key, ':', json_encode($tree->getPrefix()), "\n";
Ожидаемый результат
x:"|   \\-"
right:"\\-"

Префикс вычисляется из положения; он не гарантирует универсальный формат обмена.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveTreeIterator::getPrefix

(PHP 5 >= 5.3.0, PHP 7, PHP 8) RecursiveTreeIterator::getPrefix — Get the prefix

Description

public function RecursiveTreeIterator::getPrefix(): string

Gets the string to place in front of current element

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

Returns the string to place in front of current element

Связанные карточки: RecursiveTreeIterator::beginChildren, RecursiveTreeIterator::beginIteration, RecursiveTreeIterator::callGetChildren, RecursiveTreeIterator::callHasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveTreeIterator::keyRecursiveTreeIterator::key: Метод читает идентификатор текущей позиции Работа с текстового дерева.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveTreeIterator::key(): mixed

RecursiveTreeIterator::key. Метод читает идентификатор текущей позиции; форма зависит от флагов и уровня. BYPASS_KEY оставляет key() исходным: first и last без линий дерева. Во второй независимой ситуации: BYPASS_CURRENT оставляет значения исходными, поэтому графический prefix применяется к key(). Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveTreeIterator::key(): mixed
Результатmixed: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Ключ одного уровня не всегда уникален во всём дереве; при необходимости собирайте полный путь.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

BYPASS_KEY оставляет key() исходным: first и last без линий дерева.

Оставить ключи чистыми через BYPASS_KEYСамостоятельный пример
<?php
$tree = new RecursiveTreeIterator(
    new RecursiveArrayIterator(['group' => ['first' => 'A', 'last' => 'B']]),
    RecursiveTreeIterator::BYPASS_KEY,
    CachingIterator::CATCH_GET_CHILD,
    RecursiveTreeIterator::LEAVES_ONLY
);
foreach ($tree as $_) echo $tree->key(), "\n";
Ожидаемый результат
first
last

Это удобно, если ключ затем используется программой, а украшение нужно только current().

Скачать самостоятельный пример с fixtures, результатом и README

BYPASS_CURRENT оставляет значения исходными, поэтому графический prefix применяется к key().

Получить украшенные ключи без BYPASS_KEYСамостоятельный пример
<?php
$flags = RecursiveTreeIterator::BYPASS_CURRENT;
$tree = new RecursiveTreeIterator(
    new RecursiveArrayIterator(['group' => ['first' => 'A', 'last' => 'B']]),
    $flags,
    CachingIterator::CATCH_GET_CHILD,
    RecursiveTreeIterator::LEAVES_ONLY
);
foreach ($tree as $_) echo $tree->key(), "\n";
Ожидаемый результат
  |-first
  \-last

Украшенный ключ годится для показа, но его нельзя без очистки использовать как ключ исходного массива.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveTreeIterator::key

(PHP 5 >= 5.3.0, PHP 7, PHP 8) RecursiveTreeIterator::key — Get the key of the current element

Description

public function RecursiveTreeIterator::key(): mixed

Gets the current key prefixed and postfixed.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

Returns the current key prefixed and postfixed.

Связанные карточки: RecursiveTreeIterator::beginChildren, RecursiveTreeIterator::beginIteration, RecursiveTreeIterator::callGetChildren, RecursiveTreeIterator::callHasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveTreeIterator::nextRecursiveTreeIterator::next: Метод меняет состояние курсора и не возвращает следующий элемент как значение. Работа с текстового дерева.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveTreeIterator::next(): void

RecursiveTreeIterator::next. Метод меняет состояние курсора и не возвращает следующий элемент как значение. next() перемещает рекурсивный стек и одновременно меняет префикс с «есть следующий» на «последний». Во второй независимой ситуации: После x next() закрывает внутреннюю ветвь и ставит курсор на outside корневого уровня. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveTreeIterator::next(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Без valid() после продвижения нельзя безопасно читать current/key.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

next() перемещает рекурсивный стек и одновременно меняет префикс с «есть следующий» на «последний».

Перейти к следующей строке дереваСамостоятельный пример
<?php
$tree = new RecursiveTreeIterator(
    new RecursiveArrayIterator(['group' => ['first' => 'A', 'last' => 'B']]),
    RecursiveTreeIterator::BYPASS_KEY,
    CachingIterator::CATCH_GET_CHILD,
    RecursiveTreeIterator::LEAVES_ONLY
);
$tree->rewind();
echo $tree->key(), ':', $tree->current(), "\n";
$tree->next();
echo $tree->key(), ':', $tree->current(), "\n";
Ожидаемый результат
first:  |-A
last:  \-B

Возвращаемого значения нет; следующая строка читается через key/current.

Скачать самостоятельный пример с fixtures, результатом и README

После x next() закрывает внутреннюю ветвь и ставит курсор на outside корневого уровня.

Перейти из вложенного листа к корневомуСамостоятельный пример
<?php
$tree = new RecursiveTreeIterator(
    new RecursiveArrayIterator(['inside' => ['x' => '1'], 'outside' => '2']),
    RecursiveTreeIterator::BYPASS_KEY,
    CachingIterator::CATCH_GET_CHILD,
    RecursiveTreeIterator::LEAVES_ONLY
);
$tree->rewind();
echo $tree->key(), '; depth=', $tree->getDepth(), "\n";
$tree->next();
echo $tree->key(), '; depth=', $tree->getDepth(), "\n";
Ожидаемый результат
x; depth=1
outside; depth=0

RecursiveTreeIterator наследует стек переходов от RecursiveIteratorIterator.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveTreeIterator::next

(PHP 5 >= 5.3.0, PHP 7, PHP 8) RecursiveTreeIterator::next — Move to next element

Description

public function RecursiveTreeIterator::next(): void

Moves forward to the next element.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

No value is returned.

Связанные карточки: RecursiveTreeIterator::beginChildren, RecursiveTreeIterator::beginIteration, RecursiveTreeIterator::callGetChildren, RecursiveTreeIterator::callHasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveTreeIterator::nextElementRecursiveTreeIterator::nextElement: Hook вызывается для каждого узла, готового к выдаче выбранным режимом. Работа с текстового дерева.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveTreeIterator::nextElement(): void

RecursiveTreeIterator::nextElement. Hook вызывается для каждого узла, готового к выдаче выбранным режимом. В SELF_FIRST готовыми становятся parent menu и два leaf — три вызова nextElement(). Во второй независимой ситуации: SELF_FIRST выдаёт group на глубине 0, inside на 1 и outside на 0. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveTreeIterator::nextElement(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Точный тип возврата, особые значения и изменения по версиям перечислены в таблице и полном официальном контракте.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

В SELF_FIRST готовыми становятся parent menu и два leaf — три вызова nextElement().

Посчитать готовые строки дерева менюСамостоятельный пример
<?php
class ReadyTree extends RecursiveTreeIterator {
    public int $ready = 0;
    public function nextElement(): void { $this->ready++; }
}
$tree = new ReadyTree(new RecursiveArrayIterator(['menu' => ['catalog' => 'yes', 'cart' => 'yes']]));
foreach ($tree as $_) { }
echo 'ready=', $tree->ready, "\n";
Ожидаемый результат
ready=3

Hook срабатывает до выдачи каждого элемента и должен оставаться дешёвым.

Скачать самостоятельный пример с fixtures, результатом и README

SELF_FIRST выдаёт group на глубине 0, inside на 1 и outside на 0.

Собрать глубины готовых строк отчётаСамостоятельный пример
<?php
class ReadyDepthTree extends RecursiveTreeIterator {
    public array $depths = [];
    public function nextElement(): void { $this->depths[] = $this->getDepth(); }
}
$tree = new ReadyDepthTree(new RecursiveArrayIterator(['group' => ['inside' => 'x'], 'outside' => 'y']));
foreach ($tree as $_) { }
echo implode(', ', $tree->depths), "\n";
Ожидаемый результат
0, 1, 0

Это подтверждает, что nextElement относится к готовой строке, а не только к листьям.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveTreeIterator::nextElement

(PHP 5 >= 5.3.0, PHP 7, PHP 8) RecursiveTreeIterator::nextElement — Next element

Description

public function RecursiveTreeIterator::nextElement(): void

Called when the next element is available.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

No value is returned.

Связанные карточки: RecursiveTreeIterator::beginChildren, RecursiveTreeIterator::beginIteration, RecursiveTreeIterator::callGetChildren, RecursiveTreeIterator::callHasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveTreeIterator::rewindRecursiveTreeIterator::rewind: Метод заново устанавливает первый доступный элемент всего соответствующего обхода. Работа с текстового дерева.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveTreeIterator::rewind(): void

RecursiveTreeIterator::rewind. Метод заново устанавливает первый доступный элемент всего соответствующего обхода. rewind() сбрасывает внутренний стек и кэш позиции, затем готовит первую строку first. Во второй независимой ситуации: Два явных rewind дают по два SELF_FIRST узла: app и debug. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveTreeIterator::rewind(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Повторяемость наследуется от источника; завершённый Generator не обязан перематываться.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

rewind() сбрасывает внутренний стек и кэш позиции, затем готовит первую строку first.

Вернуться к первой строке дереваСамостоятельный пример
<?php
$tree = new RecursiveTreeIterator(
    new RecursiveArrayIterator(['group' => ['first' => 'A', 'last' => 'B']]),
    RecursiveTreeIterator::BYPASS_KEY,
    CachingIterator::CATCH_GET_CHILD,
    RecursiveTreeIterator::LEAVES_ONLY
);
$tree->rewind();
$tree->next();
echo 'До: ', $tree->key(), "\n";
$tree->rewind();
echo 'После: ', $tree->key(), "\n";
Ожидаемый результат
До: last
После: first

Настроенные prefix parts и postfix остаются свойствами объекта и не сбрасываются.

Скачать самостоятельный пример с fixtures, результатом и README

Два явных rewind дают по два SELF_FIRST узла: app и debug.

Повторно вывести одну и ту же структуруСамостоятельный пример
<?php
$tree = new RecursiveTreeIterator(new RecursiveArrayIterator(['app' => ['debug' => 'on']]));
$counts = [];
for ($pass = 0; $pass < 2; $pass++) {
    $tree->rewind();
    $count = 0;
    while ($tree->valid()) { $count++; $tree->next(); }
    $counts[] = $count;
}
echo implode(', ', $counts), "\n";
Ожидаемый результат
2, 2

Дерево повторяемо потому, что массивный источник поддерживает перемотку.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveTreeIterator::rewind

(PHP 5 >= 5.3.0, PHP 7, PHP 8) RecursiveTreeIterator::rewind — Rewind iterator

Description

public function RecursiveTreeIterator::rewind(): void

Rewinds the iterator to the first element of the top level inner iterator.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

No value is returned.

Связанные карточки: RecursiveTreeIterator::beginChildren, RecursiveTreeIterator::beginIteration, RecursiveTreeIterator::callGetChildren, RecursiveTreeIterator::callHasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveTreeIterator::setPostfixRecursiveTreeIterator::setPostfix: Метод меняет только отображение всех последующих строк этого объекта. Работа с текстового дерева.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveTreeIterator::setPostfix(string $postfix): void

RecursiveTreeIterator::setPostfix. Метод меняет только отображение всех последующих строк этого объекта. setPostfix("\n") делает каждый decorated current готовой строкой для echo без дополнительного разделителя. Во второй независимой ситуации: Строка postfix присоединяется после entry каждого узла. Здесь виден маркер . Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
postfixТочная строка, добавляемая после entry каждого узла, например перевод строки или текстовый маркер.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveTreeIterator::setPostfix(string $postfix): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Точный тип возврата, особые значения и изменения по версиям перечислены в таблице и полном официальном контракте.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

setPostfix("\n") делает каждый decorated current готовой строкой для echo без дополнительного разделителя.

Добавить перевод строки после каждого узлаСамостоятельный пример
<?php
$tree = new RecursiveTreeIterator(
    new RecursiveArrayIterator(['group' => ['first' => 'A', 'last' => 'B']]),
    RecursiveTreeIterator::BYPASS_KEY,
    CachingIterator::CATCH_GET_CHILD,
    RecursiveTreeIterator::LEAVES_ONLY
);
$tree->setPostfix("\n");
foreach ($tree as $line) echo $line;
Ожидаемый результат
  |-A
  \-B

Метод меняет представление объекта, но не исходные A/B.

Скачать самостоятельный пример с fixtures, результатом и README

Строка postfix присоединяется после entry каждого узла. Здесь виден маркер .

Добавить текстовый маркер концаСамостоятельный пример
<?php
$tree = new RecursiveTreeIterator(
    new RecursiveArrayIterator(['status' => 'open']),
    RecursiveTreeIterator::BYPASS_KEY,
    CachingIterator::CATCH_GET_CHILD,
    RecursiveTreeIterator::LEAVES_ONLY
);
$tree->setPostfix(' <end>');
foreach ($tree as $line) echo $line, "\n";
Ожидаемый результат
\-open <end>

Для HTML разметки значения и postfix нужно экранировать; этот CLI-пример выводит обычный текст.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveTreeIterator::setPostfix

(PHP 5 >= 5.5.3, PHP 7, PHP 8) RecursiveTreeIterator::setPostfix — Set postfix

Description

public function RecursiveTreeIterator::setPostfix(string $postfix): void

Sets postfix as used in RecursiveTreeIterator::getPostfix().

WarningThis function is currently not documented; only its argument list is available.

Parameters

postfix

Return Values

No value is returned.

Связанные карточки: RecursiveTreeIterator::beginChildren, RecursiveTreeIterator::beginIteration, RecursiveTreeIterator::callGetChildren, RecursiveTreeIterator::callHasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveTreeIterator::setPrefixPartRecursiveTreeIterator::setPrefixPart: Меняется одна позиционная часть схемы Работа с текстового дерева.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveTreeIterator::setPrefixPart(int $part, string $value): void

RecursiveTreeIterator::setPrefixPart. Меняется одна позиционная часть схемы; остальные части сохраняются. setPrefixPart меняет только выбранные части: окончание с соседом и окончание последнего узла. Во второй независимой ситуации: PREFIX_MID_HAS_NEXT рисует вертикальное продолжение на промежуточном уровне, PREFIX_END_LAST — конец текущей ветви. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
partОдна из констант PREFIX_*: конкретный фрагмент начала, середины, окончания или правой части ветви.
valueНовая строка выбранной части префикса. Она влияет только на представление дерева.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveTreeIterator::setPrefixPart(int $part, string $value): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Неверный номер части вызывает ValueError; случайные символы могут визуально исказить структуру.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

setPrefixPart меняет только выбранные части: окончание с соседом и окончание последнего узла.

Заменить окончания ветвей на Unicode-символыСамостоятельный пример
<?php
$tree = new RecursiveTreeIterator(
    new RecursiveArrayIterator(['group' => ['first' => 'A', 'last' => 'B']]),
    RecursiveTreeIterator::BYPASS_KEY,
    CachingIterator::CATCH_GET_CHILD,
    RecursiveTreeIterator::LEAVES_ONLY
);
$tree->setPrefixPart(RecursiveTreeIterator::PREFIX_END_HAS_NEXT, '├─');
$tree->setPrefixPart(RecursiveTreeIterator::PREFIX_END_LAST, '└─');
foreach ($tree as $line) echo $line, "\n";
Ожидаемый результат
  ├─A
  └─B

Unicode делает схему читаемой, но терминал и шрифт должны поддерживать эти символы.

Скачать самостоятельный пример с fixtures, результатом и README

PREFIX_MID_HAS_NEXT рисует вертикальное продолжение на промежуточном уровне, PREFIX_END_LAST — конец текущей ветви.

Заменить вертикальное продолжение глубокой ветвиСамостоятельный пример
<?php
$tree = new RecursiveTreeIterator(
    new RecursiveArrayIterator(['left' => ['deep' => ['x' => '1']], 'right' => '2']),
    RecursiveTreeIterator::BYPASS_KEY,
    CachingIterator::CATCH_GET_CHILD,
    RecursiveTreeIterator::LEAVES_ONLY
);
$tree->setPrefixPart(RecursiveTreeIterator::PREFIX_MID_HAS_NEXT, '│ ');
$tree->setPrefixPart(RecursiveTreeIterator::PREFIX_END_LAST, '└─');
foreach ($tree as $key => $line) echo $key, ':', $line, "\n";
Ожидаемый результат
x:│   └─1
right:└─2

Части префикса имеют позиционное значение; произвольное сочетание может сделать дерево визуально ложным.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveTreeIterator::setPrefixPart

(PHP 5 >= 5.3.0, PHP 7, PHP 8) RecursiveTreeIterator::setPrefixPart — Set a part of the prefix

Description

public function RecursiveTreeIterator::setPrefixPart(int $part, string $value): void

Sets a part of the prefix used in the graphic tree.

WarningThis function is currently not documented; only its argument list is available.

Parameters

part

One of the RecursiveTreeIterator::PREFIX_* constants.

value

The value to assign to the part of the prefix specified in part.

Return Values

No value is returned.

Связанные карточки: RecursiveTreeIterator::beginChildren, RecursiveTreeIterator::beginIteration, RecursiveTreeIterator::callGetChildren, RecursiveTreeIterator::callHasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

RecursiveTreeIterator::validRecursiveTreeIterator::valid: false означает отсутствие текущей позиции Работа с текстового дерева.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function RecursiveTreeIterator::valid(): bool

RecursiveTreeIterator::valid. false означает отсутствие текущей позиции; это обязательная граница перед current/key. valid() защищает current() в ручном протоколе. После B следующий вызов next исчерпывает дерево. Во второй независимой ситуации: Пустой источник после rewind сразу делает valid() ложным. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function RecursiveTreeIterator::valid(): bool
Результатbool: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения внутреннего источника не превращаются в пустой результат. Точный тип возврата, особые значения и изменения по версиям перечислены в таблице и полном официальном контракте.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

valid() защищает current() в ручном протоколе. После B следующий вызов next исчерпывает дерево.

Остановить ручной вывод дереваСамостоятельный пример
<?php
$tree = new RecursiveTreeIterator(
    new RecursiveArrayIterator(['items' => ['A', 'B']]),
    RecursiveTreeIterator::BYPASS_KEY,
    CachingIterator::CATCH_GET_CHILD,
    RecursiveTreeIterator::LEAVES_ONLY
);
$tree->rewind();
while ($tree->valid()) {
    echo $tree->current(), "\n";
    $tree->next();
}
echo 'valid=false', "\n";
Ожидаемый результат
  |-A
  \-B
valid=false

false означает конец строк, а не пустое значение текущего узла.

Скачать самостоятельный пример с fixtures, результатом и README

Пустой источник после rewind сразу делает valid() ложным.

Проверить пустое дерево до чтенияСамостоятельный пример
<?php
$tree = new RecursiveTreeIterator(new RecursiveArrayIterator([]));
$tree->rewind();
echo $tree->valid() ? 'есть узел' : 'дерево пусто', "\n";
Ожидаемый результат
дерево пусто

Проверка предотвращает чтение current/key на несуществующей позиции.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

RecursiveTreeIterator::valid

(PHP 5 >= 5.3.0, PHP 7, PHP 8) RecursiveTreeIterator::valid — Check validity

Description

public function RecursiveTreeIterator::valid(): bool

Check whether the current position is valid.

WarningThis function is currently not documented; only its argument list is available.

Parameters

This function has no parameters.

Return Values

true if the current position is valid, otherwise false

Связанные карточки: RecursiveTreeIterator::beginChildren, RecursiveTreeIterator::beginIteration, RecursiveTreeIterator::callGetChildren, RecursiveTreeIterator::callHasChildren.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

DirectoryIterator::__constructDirectoryIterator::__construct: создать и настроить объект для дальнейшего обхода

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function DirectoryIterator::__construct(string $directory)

DirectoryIterator::__construct нужен, чтобы создать и настроить объект для дальнейшего обхода. В этой задаче DirectoryIterator помогает прочитать записи одной локальной папки и для каждой получить имя, расширение и тип. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
directoryПуть к собственной локальной учебной папке. Примеры используют __DIR__ и приложенные fixtures.
Часть контрактаЧто важно
Сигнатураpublic function DirectoryIterator::__construct(string $directory)
РезультатКонструктор не возвращает прикладное значение; выражение new создаёт объект, который затем сохраняется в переменной.
Ошибки и особые значенияПустая строка пути вызывает ValueError (с PHP 8.0); отсутствующая или недоступная папка вызывает UnexpectedValueException. Ошибка возникает при new, до начала foreach.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Нужно построить локальный индекс вложений каталога, не заходя в подпапку sub. Порядок файловой системы заранее неизвестен, поэтому результат явно сортируется по имени.

Собрать предсказуемый список файлов одной папкиСамостоятельный пример
<?php
declare(strict_types=1);

$directory = new DirectoryIterator(__DIR__ . '/fixtures/catalog');
$rows = [];
$directory->rewind();
while ($directory->valid()) {
    if (!$directory->isDot()) {
        $entry = $directory->current();
        $filename = $entry->getFilename();
        $basename = $entry->getBasename();
        if ($filename !== $basename) {
            throw new RuntimeException('Unexpected basename');
        }
        $rows[] = [
            $filename,
            $entry->getExtension(),
            $entry->isDir() ? 'dir' : 'file',
        ];
    }
    $directory->next();
}
usort($rows, fn(array $left, array $right): int => $left[0] <=> $right[0]);
foreach ($rows as [$name, $extension, $type]) {
    echo $name, '|', $extension, '|', $type, "\n";
}
Ожидаемый результат
.env|env|file
README||file
photo.final.jpg|jpg|file
report.csv|csv|file
sub||dir

Конструктор открыл одну папку. На каждой допустимой позиции current() вернул тот же объект DirectoryIterator с данными текущей записи; getFilename()/getBasename()/getExtension() выделили части имени. У .env расширением считается env. Каталог sub виден как запись, но его содержимое не обходилось.

Скачать самостоятельный пример с fixtures, результатом и README

Путь к папке приходит из настройки приложения. Нужно отделить ошибку конфигурации «пусто» от пути, которого нет.

Различить пустой и несуществующий путьСамостоятельный пример
<?php
declare(strict_types=1);

foreach (['empty' => '', 'missing' => __DIR__ . '/fixtures/not-created'] as $label => $path) {
    try {
        new DirectoryIterator($path);
        echo $label, "=opened\n";
    } catch (Throwable $error) {
        echo $label, '=', $error::class, "\n";
    }
}
$valid = new DirectoryIterator(__DIR__ . '/fixtures/existing');
echo 'existing=', $valid->valid() ? 'opened' : 'empty', "\n";
Ожидаемый результат
empty=ValueError
missing=UnexpectedValueException
existing=opened

В PHP 8.5 пустая строка привела к ValueError, отсутствующая папка — к UnexpectedValueException. Для существующей папки объект создался; valid() относится к позиции обхода и не заменяет обработку ошибки конструктора.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

DirectoryIterator::__construct

(PHP 5, PHP 7, PHP 8) DirectoryIterator::__construct — Constructs a new directory iterator from a path

Description

public function DirectoryIterator::__construct(string $directory)

Constructs a new directory iterator from a path.

Parameters

directory

The path of the directory to traverse.

Errors/Exceptions

Throws an UnexpectedValueException if the directory does not exist.

Throws a ValueError if the directory is an empty string.

Changelog

Version Description

8.0.0

Now throws a ValueError if directory is an empty string; previously it threw a RuntimeException.

See Also

SplFileInfo

Iterator

Связанные карточки: FilesystemIterator::__construct, RecursiveDirectoryIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

DirectoryIterator::currentDirectoryIterator::current: получить текущее значение без продвижения курсора

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function DirectoryIterator::current(): mixed

DirectoryIterator::current нужен, чтобы получить текущее значение без продвижения курсора. В этой задаче DirectoryIterator помогает прочитать записи одной локальной папки и для каждой получить имя, расширение и тип. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function DirectoryIterator::current(): mixed
Результатmixed: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияСначала вызывайте valid(). На недействительном курсоре особое значение зависит от класса и не должно смешиваться с настоящим null.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Нужно построить локальный индекс вложений каталога, не заходя в подпапку sub. Порядок файловой системы заранее неизвестен, поэтому результат явно сортируется по имени.

Собрать предсказуемый список файлов одной папкиСамостоятельный пример
<?php
declare(strict_types=1);

$directory = new DirectoryIterator(__DIR__ . '/fixtures/catalog');
$rows = [];
$directory->rewind();
while ($directory->valid()) {
    if (!$directory->isDot()) {
        $entry = $directory->current();
        $filename = $entry->getFilename();
        $basename = $entry->getBasename();
        if ($filename !== $basename) {
            throw new RuntimeException('Unexpected basename');
        }
        $rows[] = [
            $filename,
            $entry->getExtension(),
            $entry->isDir() ? 'dir' : 'file',
        ];
    }
    $directory->next();
}
usort($rows, fn(array $left, array $right): int => $left[0] <=> $right[0]);
foreach ($rows as [$name, $extension, $type]) {
    echo $name, '|', $extension, '|', $type, "\n";
}
Ожидаемый результат
.env|env|file
README||file
photo.final.jpg|jpg|file
report.csv|csv|file
sub||dir

Конструктор открыл одну папку. На каждой допустимой позиции current() вернул тот же объект DirectoryIterator с данными текущей записи; getFilename()/getBasename()/getExtension() выделили части имени. У .env расширением считается env. Каталог sub виден как запись, но его содержимое не обходилось.

Скачать самостоятельный пример с fixtures, результатом и README

Инструмент диагностики должен вручную поставить курсор на известный файл, прочитать запись и понять, когда элементы закончились.

Найти запись, прочитать current() и увидеть конец курсораСамостоятельный пример
<?php
declare(strict_types=1);

$directory = new DirectoryIterator(__DIR__ . '/fixtures/one');
$filePosition = null;
foreach ($directory as $position => $entry) {
    if ($entry->getFilename() === 'only.txt') {
        $filePosition = $position;
        break;
    }
}
if (!is_int($filePosition)) {
    throw new RuntimeException('Fixture not found');
}
$directory->seek($filePosition);
$current = $directory->current();
echo 'keyIsInt=', is_int($directory->key()) ? 'yes' : 'no', "\n";
echo 'class=', $current::class, "\n";
echo 'sameObject=', $current === $directory ? 'yes' : 'no', "\n";
echo 'name=', (string) $current, "\n";
$directory->next();
echo 'afterFileValid=', $directory->valid() ? 'yes' : 'no', "\n";
$directory->rewind();
echo 'rewindIsDot=', $directory->isDot() ? 'yes' : 'no', "\n";
Ожидаемый результат
keyIsInt=yes
class=DirectoryIterator
sameObject=yes
name=only.txt
afterFileValid=no
rewindIsDot=yes

Сначала имя было найдено без предположения о позиции. seek() вернул тот же курсор к сохранённому целочисленному месту. current() не создал независимую копию: он вернул сам DirectoryIterator в состоянии only.txt. После next() valid() стал false; rewind() вернул позицию 0 — служебную точку.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

DirectoryIterator::current

(PHP 5, PHP 7, PHP 8) DirectoryIterator::current — Return the current DirectoryIterator item

Description

public function DirectoryIterator::current(): mixed

Get the current DirectoryIterator item.

Parameters

This function has no parameters.

Return Values

The current DirectoryIterator item.

See Also

DirectoryIterator::key() - Return the key for the current DirectoryIterator item

DirectoryIterator::next() - Move forward to next DirectoryIterator item

DirectoryIterator::rewind() - Rewind the DirectoryIterator back to the start

DirectoryIterator::valid() - Check whether current DirectoryIterator position is a valid file

Iterator::current() - Return the current element

Связанные карточки: FilesystemIterator::__construct, RecursiveDirectoryIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

DirectoryIterator::getBasenameDirectoryIterator::getBasename: получить имя текущей записи без пути и, при необходимости, без указанного суффикса

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function DirectoryIterator::getBasename(string $suffix = ''): string

DirectoryIterator::getBasename нужен, чтобы получить имя текущей записи без пути и, при необходимости, без указанного суффикса. В этой задаче DirectoryIterator помогает прочитать записи одной локальной папки и для каждой получить имя, расширение и тип. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
suffixНеобязательная точная строка в конце имени. Если совпадения в конце нет, имя возвращается без изменения; это не общий фильтр расширений.
Часть контрактаЧто важно
Сигнатураpublic function DirectoryIterator::getBasename(string $suffix = ''): string
Результатstring: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения вложенного источника не скрываются. Особые значения, предупреждения и версии перечислены в полном официальном контракте ниже.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Загрузчик должен показать исходное имя, убрать разрешённый суффикс .jpg только там, где он действительно стоит в конце, и отдельно определить расширение.

Разобрать имя, точный суффикс и последнее расширениеСамостоятельный пример
<?php
declare(strict_types=1);

$directory = new DirectoryIterator(__DIR__ . '/fixtures/names');
$rows = [];
foreach ($directory as $entry) {
    if ($entry->isDot()) {
        continue;
    }
    $rows[] = [
        (string) $entry,
        $entry->getBasename('.jpg'),
        $entry->getExtension(),
    ];
}
usort($rows, fn(array $a, array $b): int => $a[0] <=> $b[0]);
foreach ($rows as $row) {
    echo implode('|', $row), "\n";
}
Ожидаемый результат
README|README|
archive.tar.gz|archive.tar.gz|gz
photo.jpg|photo|jpg

__toString() и getFilename() дают текущее имя. getBasename(".jpg") удалил точный конечный суффикс только у photo.jpg. getExtension() вернул последнюю часть после точки: для archive.tar.gz это gz, а не tar.gz.

Скачать самостоятельный пример с fixtures, результатом и README

Нужно построить локальный индекс вложений каталога, не заходя в подпапку sub. Порядок файловой системы заранее неизвестен, поэтому результат явно сортируется по имени.

Собрать предсказуемый список файлов одной папкиСамостоятельный пример
<?php
declare(strict_types=1);

$directory = new DirectoryIterator(__DIR__ . '/fixtures/catalog');
$rows = [];
$directory->rewind();
while ($directory->valid()) {
    if (!$directory->isDot()) {
        $entry = $directory->current();
        $filename = $entry->getFilename();
        $basename = $entry->getBasename();
        if ($filename !== $basename) {
            throw new RuntimeException('Unexpected basename');
        }
        $rows[] = [
            $filename,
            $entry->getExtension(),
            $entry->isDir() ? 'dir' : 'file',
        ];
    }
    $directory->next();
}
usort($rows, fn(array $left, array $right): int => $left[0] <=> $right[0]);
foreach ($rows as [$name, $extension, $type]) {
    echo $name, '|', $extension, '|', $type, "\n";
}
Ожидаемый результат
.env|env|file
README||file
photo.final.jpg|jpg|file
report.csv|csv|file
sub||dir

Конструктор открыл одну папку. На каждой допустимой позиции current() вернул тот же объект DirectoryIterator с данными текущей записи; getFilename()/getBasename()/getExtension() выделили части имени. У .env расширением считается env. Каталог sub виден как запись, но его содержимое не обходилось.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

DirectoryIterator::getBasename

(PHP 5 >= 5.2.2, PHP 7, PHP 8) DirectoryIterator::getBasename — Get base name of current DirectoryIterator item

Description

public function DirectoryIterator::getBasename(string $suffix = ""): string

Get the base name of the current DirectoryIterator item.

Parameters

suffix

If the base name ends in suffix, this will be cut.

Return Values

The base name of the current DirectoryIterator item.

See Also

DirectoryIterator::getFilename() - Return file name of current DirectoryIterator item

DirectoryIterator::getPath()

DirectoryIterator::getPathname()

basename() - Returns trailing name component of path

pathinfo() - Returns information about a file path

Связанные карточки: FilesystemIterator::__construct, RecursiveDirectoryIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

DirectoryIterator::getExtensionDirectoryIterator::getExtension: получить расширение имени текущей записи без ведущей точки

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function DirectoryIterator::getExtension(): string

DirectoryIterator::getExtension нужен, чтобы получить расширение имени текущей записи без ведущей точки. В этой задаче DirectoryIterator помогает прочитать записи одной локальной папки и для каждой получить имя, расширение и тип. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function DirectoryIterator::getExtension(): string
Результатstring: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения вложенного источника не скрываются. Особые значения, предупреждения и версии перечислены в полном официальном контракте ниже.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Загрузчик должен показать исходное имя, убрать разрешённый суффикс .jpg только там, где он действительно стоит в конце, и отдельно определить расширение.

Разобрать имя, точный суффикс и последнее расширениеСамостоятельный пример
<?php
declare(strict_types=1);

$directory = new DirectoryIterator(__DIR__ . '/fixtures/names');
$rows = [];
foreach ($directory as $entry) {
    if ($entry->isDot()) {
        continue;
    }
    $rows[] = [
        (string) $entry,
        $entry->getBasename('.jpg'),
        $entry->getExtension(),
    ];
}
usort($rows, fn(array $a, array $b): int => $a[0] <=> $b[0]);
foreach ($rows as $row) {
    echo implode('|', $row), "\n";
}
Ожидаемый результат
README|README|
archive.tar.gz|archive.tar.gz|gz
photo.jpg|photo|jpg

__toString() и getFilename() дают текущее имя. getBasename(".jpg") удалил точный конечный суффикс только у photo.jpg. getExtension() вернул последнюю часть после точки: для archive.tar.gz это gz, а не tar.gz.

Скачать самостоятельный пример с fixtures, результатом и README

Нужно построить локальный индекс вложений каталога, не заходя в подпапку sub. Порядок файловой системы заранее неизвестен, поэтому результат явно сортируется по имени.

Собрать предсказуемый список файлов одной папкиСамостоятельный пример
<?php
declare(strict_types=1);

$directory = new DirectoryIterator(__DIR__ . '/fixtures/catalog');
$rows = [];
$directory->rewind();
while ($directory->valid()) {
    if (!$directory->isDot()) {
        $entry = $directory->current();
        $filename = $entry->getFilename();
        $basename = $entry->getBasename();
        if ($filename !== $basename) {
            throw new RuntimeException('Unexpected basename');
        }
        $rows[] = [
            $filename,
            $entry->getExtension(),
            $entry->isDir() ? 'dir' : 'file',
        ];
    }
    $directory->next();
}
usort($rows, fn(array $left, array $right): int => $left[0] <=> $right[0]);
foreach ($rows as [$name, $extension, $type]) {
    echo $name, '|', $extension, '|', $type, "\n";
}
Ожидаемый результат
.env|env|file
README||file
photo.final.jpg|jpg|file
report.csv|csv|file
sub||dir

Конструктор открыл одну папку. На каждой допустимой позиции current() вернул тот же объект DirectoryIterator с данными текущей записи; getFilename()/getBasename()/getExtension() выделили части имени. У .env расширением считается env. Каталог sub виден как запись, но его содержимое не обходилось.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

DirectoryIterator::getExtension

(PHP 5 >= 5.3.6, PHP 7, PHP 8) DirectoryIterator::getExtension — Gets the file extension

Description

public function DirectoryIterator::getExtension(): string

Retrieves the file extension.

Parameters

This function has no parameters.

Return Values

Returns a string containing the file extension, or an empty string if the file has no extension.

Notes

Note:

Another way of getting the extension is to use the pathinfo() function.

<?php $extension = pathinfo($fileinfo->getFilename(), PATHINFO_EXTENSION); ?>

See Also

DirectoryIterator::getFilename() - Return file name of current DirectoryIterator item

DirectoryIterator::getBasename() - Get base name of current DirectoryIterator item

pathinfo() - Returns information about a file path

Связанные карточки: FilesystemIterator::__construct, RecursiveDirectoryIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

DirectoryIterator::getFilenameDirectoryIterator::getFilename: получить только имя текущей записи без родительского пути

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function DirectoryIterator::getFilename(): string

DirectoryIterator::getFilename нужен, чтобы получить только имя текущей записи без родительского пути. В этой задаче DirectoryIterator помогает прочитать записи одной локальной папки и для каждой получить имя, расширение и тип. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function DirectoryIterator::getFilename(): string
Результатstring: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения вложенного источника не скрываются. Особые значения, предупреждения и версии перечислены в полном официальном контракте ниже.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Нужно построить локальный индекс вложений каталога, не заходя в подпапку sub. Порядок файловой системы заранее неизвестен, поэтому результат явно сортируется по имени.

Собрать предсказуемый список файлов одной папкиСамостоятельный пример
<?php
declare(strict_types=1);

$directory = new DirectoryIterator(__DIR__ . '/fixtures/catalog');
$rows = [];
$directory->rewind();
while ($directory->valid()) {
    if (!$directory->isDot()) {
        $entry = $directory->current();
        $filename = $entry->getFilename();
        $basename = $entry->getBasename();
        if ($filename !== $basename) {
            throw new RuntimeException('Unexpected basename');
        }
        $rows[] = [
            $filename,
            $entry->getExtension(),
            $entry->isDir() ? 'dir' : 'file',
        ];
    }
    $directory->next();
}
usort($rows, fn(array $left, array $right): int => $left[0] <=> $right[0]);
foreach ($rows as [$name, $extension, $type]) {
    echo $name, '|', $extension, '|', $type, "\n";
}
Ожидаемый результат
.env|env|file
README||file
photo.final.jpg|jpg|file
report.csv|csv|file
sub||dir

Конструктор открыл одну папку. На каждой допустимой позиции current() вернул тот же объект DirectoryIterator с данными текущей записи; getFilename()/getBasename()/getExtension() выделили части имени. У .env расширением считается env. Каталог sub виден как запись, но его содержимое не обходилось.

Скачать самостоятельный пример с fixtures, результатом и README

При чтении папки нужно пропустить специальные переходы «эта папка» и «родительская папка», но оставить реальный конфигурационный файл с точкой в начале имени.

Отличить служебные точки от файла .envСамостоятельный пример
<?php
declare(strict_types=1);

$directory = new DirectoryIterator(__DIR__ . '/fixtures/dots');
$dotEntries = 0;
$ordinaryNames = [];
foreach ($directory as $entry) {
    if ($entry->isDot()) {
        $dotEntries++;
        continue;
    }
    $ordinaryNames[] = $entry->getFilename();
}
sort($ordinaryNames);
echo 'dotEntries=', $dotEntries, "\n";
echo 'ordinary=', implode(',', $ordinaryNames), "\n";
Ожидаемый результат
dotEntries=2
ordinary=.env,public.txt

isDot() вернул true только для записей . и ... Файл .env начинается с точки, но является обычной записью и не был потерян. Поэтому проверка имени на первый символ была бы ошибочной.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

DirectoryIterator::getFilename

(PHP 5, PHP 7, PHP 8) DirectoryIterator::getFilename — Return file name of current DirectoryIterator item

Description

public function DirectoryIterator::getFilename(): string

Get the file name of the current DirectoryIterator item.

Parameters

This function has no parameters.

Return Values

Returns the file name of the current DirectoryIterator item.

See Also

DirectoryIterator::getBasename() - Get base name of current DirectoryIterator item

DirectoryIterator::getPath()

DirectoryIterator::getPathname()

pathinfo() - Returns information about a file path

Связанные карточки: FilesystemIterator::__construct, RecursiveDirectoryIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

DirectoryIterator::isDotDirectoryIterator::isDot: распознать специальные записи текущей и родительской папки

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function DirectoryIterator::isDot(): bool

DirectoryIterator::isDot нужен, чтобы распознать специальные записи текущей и родительской папки. В этой задаче DirectoryIterator помогает прочитать записи одной локальной папки и для каждой получить имя, расширение и тип. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function DirectoryIterator::isDot(): bool
Результатbool: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения вложенного источника не скрываются. Особые значения, предупреждения и версии перечислены в полном официальном контракте ниже.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

При чтении папки нужно пропустить специальные переходы «эта папка» и «родительская папка», но оставить реальный конфигурационный файл с точкой в начале имени.

Отличить служебные точки от файла .envСамостоятельный пример
<?php
declare(strict_types=1);

$directory = new DirectoryIterator(__DIR__ . '/fixtures/dots');
$dotEntries = 0;
$ordinaryNames = [];
foreach ($directory as $entry) {
    if ($entry->isDot()) {
        $dotEntries++;
        continue;
    }
    $ordinaryNames[] = $entry->getFilename();
}
sort($ordinaryNames);
echo 'dotEntries=', $dotEntries, "\n";
echo 'ordinary=', implode(',', $ordinaryNames), "\n";
Ожидаемый результат
dotEntries=2
ordinary=.env,public.txt

isDot() вернул true только для записей . и ... Файл .env начинается с точки, но является обычной записью и не был потерян. Поэтому проверка имени на первый символ была бы ошибочной.

Скачать самостоятельный пример с fixtures, результатом и README

Проверка и обработка запускаются двумя отдельными проходами по одной небольшой локальной папке.

Повторить чтение одной папки после rewind()Самостоятельный пример
<?php
declare(strict_types=1);

function readNames(DirectoryIterator $directory): array
{
    $names = [];
    $directory->rewind();
    while ($directory->valid()) {
        if (!$directory->isDot()) {
            $names[] = $directory->getFilename();
        }
        $directory->next();
    }
    sort($names);
    return $names;
}

$directory = new DirectoryIterator(__DIR__ . '/fixtures/repeat');
$first = readNames($directory);
$second = readNames($directory);
echo 'first=', implode(',', $first), "\n";
echo 'second=', implode(',', $second), "\n";
echo 'same=', $first === $second ? 'yes' : 'no', "\n";
Ожидаемый результат
first=a.txt,b.txt
second=a.txt,b.txt
same=yes

После первого while курсор находился за концом. Явный rewind() внутри readNames() начал следующий проход заново. valid() защищал чтение, next() продвигал позицию, а сортировка отделила бизнес-порядок от порядка файловой системы.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

DirectoryIterator::isDot

(PHP 5, PHP 7, PHP 8) DirectoryIterator::isDot — Determine if current DirectoryIterator item is '.' or '..'

Description

public function DirectoryIterator::isDot(): bool

Determines if the current DirectoryIterator item is a directory and either . or ..

Parameters

This function has no parameters.

Return Values

true if the entry is . or .., otherwise false

See Also

DirectoryIterator::getType()

DirectoryIterator::isDir()

DirectoryIterator::isFile()

DirectoryIterator::isLink()

Связанные карточки: FilesystemIterator::__construct, RecursiveDirectoryIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

DirectoryIterator::keyDirectoryIterator::key: получить ключ или позицию текущего элемента

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function DirectoryIterator::key(): mixed

DirectoryIterator::key нужен, чтобы получить ключ или позицию текущего элемента. В этой задаче DirectoryIterator помогает прочитать записи одной локальной папки и для каждой получить имя, расширение и тип. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function DirectoryIterator::key(): mixed
Результатmixed: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияСначала вызывайте valid(). Ключ может быть int, string или составным массивом и не обязан быть бизнес-идентификатором.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Инструмент диагностики должен вручную поставить курсор на известный файл, прочитать запись и понять, когда элементы закончились.

Найти запись, прочитать current() и увидеть конец курсораСамостоятельный пример
<?php
declare(strict_types=1);

$directory = new DirectoryIterator(__DIR__ . '/fixtures/one');
$filePosition = null;
foreach ($directory as $position => $entry) {
    if ($entry->getFilename() === 'only.txt') {
        $filePosition = $position;
        break;
    }
}
if (!is_int($filePosition)) {
    throw new RuntimeException('Fixture not found');
}
$directory->seek($filePosition);
$current = $directory->current();
echo 'keyIsInt=', is_int($directory->key()) ? 'yes' : 'no', "\n";
echo 'class=', $current::class, "\n";
echo 'sameObject=', $current === $directory ? 'yes' : 'no', "\n";
echo 'name=', (string) $current, "\n";
$directory->next();
echo 'afterFileValid=', $directory->valid() ? 'yes' : 'no', "\n";
$directory->rewind();
echo 'rewindIsDot=', $directory->isDot() ? 'yes' : 'no', "\n";
Ожидаемый результат
keyIsInt=yes
class=DirectoryIterator
sameObject=yes
name=only.txt
afterFileValid=no
rewindIsDot=yes

Сначала имя было найдено без предположения о позиции. seek() вернул тот же курсор к сохранённому целочисленному месту. current() не создал независимую копию: он вернул сам DirectoryIterator в состоянии only.txt. После next() valid() стал false; rewind() вернул позицию 0 — служебную точку.

Скачать самостоятельный пример с fixtures, результатом и README

Во время одного короткого обхода интерфейс запомнил позиции двух записей и позже захотел открыть их тем же итератором.

Сохранить позиции и вернуться к выбранным файламСамостоятельный пример
<?php
declare(strict_types=1);

$directory = new DirectoryIterator(__DIR__ . '/fixtures/seek');
$positions = [];
foreach ($directory as $position => $entry) {
    if (!$entry->isDot()) {
        $positions[$entry->getFilename()] = $position;
    }
}
ksort($positions);
foreach ($positions as $expectedName => $position) {
    $directory->seek($position);
    echo $expectedName, '=>', $directory->getFilename(), "\n";
}
try {
    $directory->seek(999);
} catch (OutOfBoundsException $error) {
    echo 'missing=', $error::class, "\n";
}
Ожидаемый результат
alpha.txt=>alpha.txt
beta.txt=>beta.txt
missing=OutOfBoundsException

Ключ DirectoryIterator — позиция обхода от нуля, а не имя и не стабильный ID файла. seek() принимает именно такую позицию. Код не предполагает, где файловая система разместила alpha.txt; недоступная позиция 999 дала OutOfBoundsException.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

DirectoryIterator::key

(PHP 5, PHP 7, PHP 8) DirectoryIterator::key — Return the key for the current DirectoryIterator item

Description

public function DirectoryIterator::key(): mixed

Get the key for the current DirectoryIterator item.

Parameters

This function has no parameters.

Return Values

The key for the current DirectoryIterator item as an int.

Changelog

Version Description

8.1.0

When the iterator is uninitialized, an Error is thrown now. Previously, the method returned false.

See Also

DirectoryIterator::current() - Return the current DirectoryIterator item

DirectoryIterator::next() - Move forward to next DirectoryIterator item

DirectoryIterator::rewind() - Rewind the DirectoryIterator back to the start

DirectoryIterator::valid() - Check whether current DirectoryIterator position is a valid file

Iterator::key() - Return the key of the current element

Связанные карточки: FilesystemIterator::__construct, RecursiveDirectoryIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

DirectoryIterator::nextDirectoryIterator::next: перевести курсор к следующему элементу

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function DirectoryIterator::next(): void

DirectoryIterator::next нужен, чтобы перевести курсор к следующему элементу. В этой задаче DirectoryIterator помогает прочитать записи одной локальной папки и для каждой получить имя, расширение и тип. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function DirectoryIterator::next(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияПродвижение одноразового источника нельзя отменить. Исключение из вложенного источника передаётся вызывающему коду.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Инструмент диагностики должен вручную поставить курсор на известный файл, прочитать запись и понять, когда элементы закончились.

Найти запись, прочитать current() и увидеть конец курсораСамостоятельный пример
<?php
declare(strict_types=1);

$directory = new DirectoryIterator(__DIR__ . '/fixtures/one');
$filePosition = null;
foreach ($directory as $position => $entry) {
    if ($entry->getFilename() === 'only.txt') {
        $filePosition = $position;
        break;
    }
}
if (!is_int($filePosition)) {
    throw new RuntimeException('Fixture not found');
}
$directory->seek($filePosition);
$current = $directory->current();
echo 'keyIsInt=', is_int($directory->key()) ? 'yes' : 'no', "\n";
echo 'class=', $current::class, "\n";
echo 'sameObject=', $current === $directory ? 'yes' : 'no', "\n";
echo 'name=', (string) $current, "\n";
$directory->next();
echo 'afterFileValid=', $directory->valid() ? 'yes' : 'no', "\n";
$directory->rewind();
echo 'rewindIsDot=', $directory->isDot() ? 'yes' : 'no', "\n";
Ожидаемый результат
keyIsInt=yes
class=DirectoryIterator
sameObject=yes
name=only.txt
afterFileValid=no
rewindIsDot=yes

Сначала имя было найдено без предположения о позиции. seek() вернул тот же курсор к сохранённому целочисленному месту. current() не создал независимую копию: он вернул сам DirectoryIterator в состоянии only.txt. После next() valid() стал false; rewind() вернул позицию 0 — служебную точку.

Скачать самостоятельный пример с fixtures, результатом и README

Проверка и обработка запускаются двумя отдельными проходами по одной небольшой локальной папке.

Повторить чтение одной папки после rewind()Самостоятельный пример
<?php
declare(strict_types=1);

function readNames(DirectoryIterator $directory): array
{
    $names = [];
    $directory->rewind();
    while ($directory->valid()) {
        if (!$directory->isDot()) {
            $names[] = $directory->getFilename();
        }
        $directory->next();
    }
    sort($names);
    return $names;
}

$directory = new DirectoryIterator(__DIR__ . '/fixtures/repeat');
$first = readNames($directory);
$second = readNames($directory);
echo 'first=', implode(',', $first), "\n";
echo 'second=', implode(',', $second), "\n";
echo 'same=', $first === $second ? 'yes' : 'no', "\n";
Ожидаемый результат
first=a.txt,b.txt
second=a.txt,b.txt
same=yes

После первого while курсор находился за концом. Явный rewind() внутри readNames() начал следующий проход заново. valid() защищал чтение, next() продвигал позицию, а сортировка отделила бизнес-порядок от порядка файловой системы.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

DirectoryIterator::next

(PHP 5, PHP 7, PHP 8) DirectoryIterator::next — Move forward to next DirectoryIterator item

Description

public function DirectoryIterator::next(): void

Move forward to the next DirectoryIterator item.

Parameters

This function has no parameters.

Return Values

No value is returned.

See Also

DirectoryIterator::current() - Return the current DirectoryIterator item

DirectoryIterator::key() - Return the key for the current DirectoryIterator item

DirectoryIterator::rewind() - Rewind the DirectoryIterator back to the start

DirectoryIterator::valid() - Check whether current DirectoryIterator position is a valid file

Iterator::next() - Move forward to next element

Связанные карточки: FilesystemIterator::__construct, RecursiveDirectoryIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

DirectoryIterator::rewindDirectoryIterator::rewind: попытаться установить курсор на первый элемент

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function DirectoryIterator::rewind(): void

DirectoryIterator::rewind нужен, чтобы попытаться установить курсор на первый элемент. В этой задаче DirectoryIterator помогает прочитать записи одной локальной папки и для каждой получить имя, расширение и тип. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function DirectoryIterator::rewind(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияНе каждый Traversable можно повторить. NoRewindIterator намеренно игнорирует повторную перемотку, а Generator после завершения может выбросить исключение.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Инструмент диагностики должен вручную поставить курсор на известный файл, прочитать запись и понять, когда элементы закончились.

Найти запись, прочитать current() и увидеть конец курсораСамостоятельный пример
<?php
declare(strict_types=1);

$directory = new DirectoryIterator(__DIR__ . '/fixtures/one');
$filePosition = null;
foreach ($directory as $position => $entry) {
    if ($entry->getFilename() === 'only.txt') {
        $filePosition = $position;
        break;
    }
}
if (!is_int($filePosition)) {
    throw new RuntimeException('Fixture not found');
}
$directory->seek($filePosition);
$current = $directory->current();
echo 'keyIsInt=', is_int($directory->key()) ? 'yes' : 'no', "\n";
echo 'class=', $current::class, "\n";
echo 'sameObject=', $current === $directory ? 'yes' : 'no', "\n";
echo 'name=', (string) $current, "\n";
$directory->next();
echo 'afterFileValid=', $directory->valid() ? 'yes' : 'no', "\n";
$directory->rewind();
echo 'rewindIsDot=', $directory->isDot() ? 'yes' : 'no', "\n";
Ожидаемый результат
keyIsInt=yes
class=DirectoryIterator
sameObject=yes
name=only.txt
afterFileValid=no
rewindIsDot=yes

Сначала имя было найдено без предположения о позиции. seek() вернул тот же курсор к сохранённому целочисленному месту. current() не создал независимую копию: он вернул сам DirectoryIterator в состоянии only.txt. После next() valid() стал false; rewind() вернул позицию 0 — служебную точку.

Скачать самостоятельный пример с fixtures, результатом и README

Проверка и обработка запускаются двумя отдельными проходами по одной небольшой локальной папке.

Повторить чтение одной папки после rewind()Самостоятельный пример
<?php
declare(strict_types=1);

function readNames(DirectoryIterator $directory): array
{
    $names = [];
    $directory->rewind();
    while ($directory->valid()) {
        if (!$directory->isDot()) {
            $names[] = $directory->getFilename();
        }
        $directory->next();
    }
    sort($names);
    return $names;
}

$directory = new DirectoryIterator(__DIR__ . '/fixtures/repeat');
$first = readNames($directory);
$second = readNames($directory);
echo 'first=', implode(',', $first), "\n";
echo 'second=', implode(',', $second), "\n";
echo 'same=', $first === $second ? 'yes' : 'no', "\n";
Ожидаемый результат
first=a.txt,b.txt
second=a.txt,b.txt
same=yes

После первого while курсор находился за концом. Явный rewind() внутри readNames() начал следующий проход заново. valid() защищал чтение, next() продвигал позицию, а сортировка отделила бизнес-порядок от порядка файловой системы.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

DirectoryIterator::rewind

(PHP 5, PHP 7, PHP 8) DirectoryIterator::rewind — Rewind the DirectoryIterator back to the start

Description

public function DirectoryIterator::rewind(): void

Rewind the DirectoryIterator back to the start.

Parameters

This function has no parameters.

Return Values

No value is returned.

See Also

DirectoryIterator::current() - Return the current DirectoryIterator item

DirectoryIterator::key() - Return the key for the current DirectoryIterator item

DirectoryIterator::next() - Move forward to next DirectoryIterator item

DirectoryIterator::valid() - Check whether current DirectoryIterator position is a valid file

Iterator::rewind() - Rewind the Iterator to the first element

Связанные карточки: FilesystemIterator::__construct, RecursiveDirectoryIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

DirectoryIterator::seekDirectoryIterator::seek: перейти к заданной позиции обхода

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function DirectoryIterator::seek(int $offset): void

DirectoryIterator::seek нужен, чтобы перейти к заданной позиции обхода. В этой задаче DirectoryIterator помогает прочитать записи одной локальной папки и для каждой получить имя, расширение и тип. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
offsetПозиция от нуля. Это место в порядке обхода, а не бизнес-ID записи.
Часть контрактаЧто важно
Сигнатураpublic function DirectoryIterator::seek(int $offset): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияНедоступная позиция вызывает OutOfBoundsException. Позиция относится к текущему порядку записей, включая . и ..; после изменения папки не храните её как постоянный идентификатор.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Во время одного короткого обхода интерфейс запомнил позиции двух записей и позже захотел открыть их тем же итератором.

Сохранить позиции и вернуться к выбранным файламСамостоятельный пример
<?php
declare(strict_types=1);

$directory = new DirectoryIterator(__DIR__ . '/fixtures/seek');
$positions = [];
foreach ($directory as $position => $entry) {
    if (!$entry->isDot()) {
        $positions[$entry->getFilename()] = $position;
    }
}
ksort($positions);
foreach ($positions as $expectedName => $position) {
    $directory->seek($position);
    echo $expectedName, '=>', $directory->getFilename(), "\n";
}
try {
    $directory->seek(999);
} catch (OutOfBoundsException $error) {
    echo 'missing=', $error::class, "\n";
}
Ожидаемый результат
alpha.txt=>alpha.txt
beta.txt=>beta.txt
missing=OutOfBoundsException

Ключ DirectoryIterator — позиция обхода от нуля, а не имя и не стабильный ID файла. seek() принимает именно такую позицию. Код не предполагает, где файловая система разместила alpha.txt; недоступная позиция 999 дала OutOfBoundsException.

Скачать самостоятельный пример с fixtures, результатом и README

Инструмент диагностики должен вручную поставить курсор на известный файл, прочитать запись и понять, когда элементы закончились.

Найти запись, прочитать current() и увидеть конец курсораСамостоятельный пример
<?php
declare(strict_types=1);

$directory = new DirectoryIterator(__DIR__ . '/fixtures/one');
$filePosition = null;
foreach ($directory as $position => $entry) {
    if ($entry->getFilename() === 'only.txt') {
        $filePosition = $position;
        break;
    }
}
if (!is_int($filePosition)) {
    throw new RuntimeException('Fixture not found');
}
$directory->seek($filePosition);
$current = $directory->current();
echo 'keyIsInt=', is_int($directory->key()) ? 'yes' : 'no', "\n";
echo 'class=', $current::class, "\n";
echo 'sameObject=', $current === $directory ? 'yes' : 'no', "\n";
echo 'name=', (string) $current, "\n";
$directory->next();
echo 'afterFileValid=', $directory->valid() ? 'yes' : 'no', "\n";
$directory->rewind();
echo 'rewindIsDot=', $directory->isDot() ? 'yes' : 'no', "\n";
Ожидаемый результат
keyIsInt=yes
class=DirectoryIterator
sameObject=yes
name=only.txt
afterFileValid=no
rewindIsDot=yes

Сначала имя было найдено без предположения о позиции. seek() вернул тот же курсор к сохранённому целочисленному месту. current() не создал независимую копию: он вернул сам DirectoryIterator в состоянии only.txt. После next() valid() стал false; rewind() вернул позицию 0 — служебную точку.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

DirectoryIterator::seek

(PHP 5 >= 5.3.0, PHP 7, PHP 8) DirectoryIterator::seek — Seek to a DirectoryIterator item

Description

public function DirectoryIterator::seek(int $offset): void

Seek to a given position in the DirectoryIterator.

Parameters

offset

The zero-based numeric position to seek to.

Return Values

No value is returned.

See Also

DirectoryIterator::rewind() - Rewind the DirectoryIterator back to the start

DirectoryIterator::next() - Move forward to next DirectoryIterator item

SeekableIterator::seek() - Seeks to a position

Связанные карточки: FilesystemIterator::__construct, RecursiveDirectoryIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

DirectoryIterator::__toStringDirectoryIterator::__toString: получить строковое представление текущего элемента

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function DirectoryIterator::__toString(): string

DirectoryIterator::__toString нужен, чтобы получить строковое представление текущего элемента. В этой задаче DirectoryIterator помогает прочитать записи одной локальной папки и для каждой получить имя, расширение и тип. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function DirectoryIterator::__toString(): string
Результатstring: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияTypeError и исключения вложенного источника не скрываются. Особые значения, предупреждения и версии перечислены в полном официальном контракте ниже.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Загрузчик должен показать исходное имя, убрать разрешённый суффикс .jpg только там, где он действительно стоит в конце, и отдельно определить расширение.

Разобрать имя, точный суффикс и последнее расширениеСамостоятельный пример
<?php
declare(strict_types=1);

$directory = new DirectoryIterator(__DIR__ . '/fixtures/names');
$rows = [];
foreach ($directory as $entry) {
    if ($entry->isDot()) {
        continue;
    }
    $rows[] = [
        (string) $entry,
        $entry->getBasename('.jpg'),
        $entry->getExtension(),
    ];
}
usort($rows, fn(array $a, array $b): int => $a[0] <=> $b[0]);
foreach ($rows as $row) {
    echo implode('|', $row), "\n";
}
Ожидаемый результат
README|README|
archive.tar.gz|archive.tar.gz|gz
photo.jpg|photo|jpg

__toString() и getFilename() дают текущее имя. getBasename(".jpg") удалил точный конечный суффикс только у photo.jpg. getExtension() вернул последнюю часть после точки: для archive.tar.gz это gz, а не tar.gz.

Скачать самостоятельный пример с fixtures, результатом и README

Инструмент диагностики должен вручную поставить курсор на известный файл, прочитать запись и понять, когда элементы закончились.

Найти запись, прочитать current() и увидеть конец курсораСамостоятельный пример
<?php
declare(strict_types=1);

$directory = new DirectoryIterator(__DIR__ . '/fixtures/one');
$filePosition = null;
foreach ($directory as $position => $entry) {
    if ($entry->getFilename() === 'only.txt') {
        $filePosition = $position;
        break;
    }
}
if (!is_int($filePosition)) {
    throw new RuntimeException('Fixture not found');
}
$directory->seek($filePosition);
$current = $directory->current();
echo 'keyIsInt=', is_int($directory->key()) ? 'yes' : 'no', "\n";
echo 'class=', $current::class, "\n";
echo 'sameObject=', $current === $directory ? 'yes' : 'no', "\n";
echo 'name=', (string) $current, "\n";
$directory->next();
echo 'afterFileValid=', $directory->valid() ? 'yes' : 'no', "\n";
$directory->rewind();
echo 'rewindIsDot=', $directory->isDot() ? 'yes' : 'no', "\n";
Ожидаемый результат
keyIsInt=yes
class=DirectoryIterator
sameObject=yes
name=only.txt
afterFileValid=no
rewindIsDot=yes

Сначала имя было найдено без предположения о позиции. seek() вернул тот же курсор к сохранённому целочисленному месту. current() не создал независимую копию: он вернул сам DirectoryIterator в состоянии only.txt. После next() valid() стал false; rewind() вернул позицию 0 — служебную точку.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

DirectoryIterator::__toString

(PHP 5, PHP 7, PHP 8) DirectoryIterator::__toString — Get file name as a string

Description

public function DirectoryIterator::__toString(): string

Get the file name of the current DirectoryIterator item.

Parameters

This function has no parameters.

Return Values

Returns the file name of the current DirectoryIterator item.

See Also

DirectoryIterator::getFilename() - Return file name of current DirectoryIterator item

The __toString() magic method

Связанные карточки: FilesystemIterator::__construct, RecursiveDirectoryIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

DirectoryIterator::validDirectoryIterator::valid: проверить, указывает ли курсор на существующий элемент

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function DirectoryIterator::valid(): bool

DirectoryIterator::valid нужен, чтобы проверить, указывает ли курсор на существующий элемент. В этой задаче DirectoryIterator помогает прочитать записи одной локальной папки и для каждой получить имя, расширение и тип. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function DirectoryIterator::valid(): bool
Результатbool: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияfalse означает отсутствие текущего элемента, а не ошибку бизнес-данных. Ошибки источника могут возникнуть отдельно.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Инструмент диагностики должен вручную поставить курсор на известный файл, прочитать запись и понять, когда элементы закончились.

Найти запись, прочитать current() и увидеть конец курсораСамостоятельный пример
<?php
declare(strict_types=1);

$directory = new DirectoryIterator(__DIR__ . '/fixtures/one');
$filePosition = null;
foreach ($directory as $position => $entry) {
    if ($entry->getFilename() === 'only.txt') {
        $filePosition = $position;
        break;
    }
}
if (!is_int($filePosition)) {
    throw new RuntimeException('Fixture not found');
}
$directory->seek($filePosition);
$current = $directory->current();
echo 'keyIsInt=', is_int($directory->key()) ? 'yes' : 'no', "\n";
echo 'class=', $current::class, "\n";
echo 'sameObject=', $current === $directory ? 'yes' : 'no', "\n";
echo 'name=', (string) $current, "\n";
$directory->next();
echo 'afterFileValid=', $directory->valid() ? 'yes' : 'no', "\n";
$directory->rewind();
echo 'rewindIsDot=', $directory->isDot() ? 'yes' : 'no', "\n";
Ожидаемый результат
keyIsInt=yes
class=DirectoryIterator
sameObject=yes
name=only.txt
afterFileValid=no
rewindIsDot=yes

Сначала имя было найдено без предположения о позиции. seek() вернул тот же курсор к сохранённому целочисленному месту. current() не создал независимую копию: он вернул сам DirectoryIterator в состоянии only.txt. После next() valid() стал false; rewind() вернул позицию 0 — служебную точку.

Скачать самостоятельный пример с fixtures, результатом и README

Проверка и обработка запускаются двумя отдельными проходами по одной небольшой локальной папке.

Повторить чтение одной папки после rewind()Самостоятельный пример
<?php
declare(strict_types=1);

function readNames(DirectoryIterator $directory): array
{
    $names = [];
    $directory->rewind();
    while ($directory->valid()) {
        if (!$directory->isDot()) {
            $names[] = $directory->getFilename();
        }
        $directory->next();
    }
    sort($names);
    return $names;
}

$directory = new DirectoryIterator(__DIR__ . '/fixtures/repeat');
$first = readNames($directory);
$second = readNames($directory);
echo 'first=', implode(',', $first), "\n";
echo 'second=', implode(',', $second), "\n";
echo 'same=', $first === $second ? 'yes' : 'no', "\n";
Ожидаемый результат
first=a.txt,b.txt
second=a.txt,b.txt
same=yes

После первого while курсор находился за концом. Явный rewind() внутри readNames() начал следующий проход заново. valid() защищал чтение, next() продвигал позицию, а сортировка отделила бизнес-порядок от порядка файловой системы.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

DirectoryIterator::valid

(PHP 5, PHP 7, PHP 8) DirectoryIterator::valid — Check whether current DirectoryIterator position is a valid file

Description

public function DirectoryIterator::valid(): bool

Check whether current DirectoryIterator position is a valid file.

Parameters

This function has no parameters.

Return Values

Returns true if the position is valid, otherwise false

See Also

DirectoryIterator::current() - Return the current DirectoryIterator item

DirectoryIterator::key() - Return the key for the current DirectoryIterator item

DirectoryIterator::next() - Move forward to next DirectoryIterator item

DirectoryIterator::rewind() - Rewind the DirectoryIterator back to the start

Iterator::valid() - Checks if current position is valid

Связанные карточки: FilesystemIterator::__construct, RecursiveDirectoryIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

FilesystemIterator::__constructFilesystemIterator::__construct: создать и настроить объект для дальнейшего обхода

PHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.2.0, 8.2) · SPL

public function FilesystemIterator::__construct(string $directory, int $flags = 4096)

FilesystemIterator::__construct нужен, чтобы создать и настроить объект для дальнейшего обхода. В этой задаче FilesystemIterator помогает обойти одну папку и заранее выбрать, что считать ключом и текущим значением. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
directoryПуть к собственной локальной учебной папке. Примеры используют __DIR__ и приложенные fixtures.
flagsБитовая маска режима. Оператор | объединяет совместимые константы; setFlags заменяет прежнюю маску целиком.
Часть контрактаЧто важно
Сигнатураpublic function FilesystemIterator::__construct(string $directory, int $flags = 4096)
РезультатКонструктор не возвращает прикладное значение; выражение new создаёт объект, который затем сохраняется в переменной.
Ошибки и особые значенияПустая строка вызывает ValueError; отсутствующая или недоступная папка — UnexpectedValueException. С PHP 8.2 SKIP_DOTS можно снять, поэтому не полагайтесь на прежнее неотключаемое поведение.
ВерсииPHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.2.0, 8.2)

Шаблонизатору нужен короткий ключ для подписи и полный путь-строка для передачи функции чтения файла.

Получить имя-ключ и строку полного путиСамостоятельный пример
<?php
declare(strict_types=1);

$flags = FilesystemIterator::KEY_AS_FILENAME
    | FilesystemIterator::CURRENT_AS_PATHNAME
    | FilesystemIterator::SKIP_DOTS;
$iterator = new FilesystemIterator(__DIR__ . '/fixtures/storage', $flags);
$rows = [];
foreach ($iterator as $key => $current) {
    $rows[] = $key . '|current=' . get_debug_type($current)
        . '|basename=' . basename($current);
}
sort($rows);
echo implode("\n", $rows), "\n";
Ожидаемый результат
.env|current=string|basename=.env
a.txt|current=string|basename=a.txt
b.log|current=string|basename=b.log
data|current=string|basename=data

KEY_AS_FILENAME сделал ключом только имя, CURRENT_AS_PATHNAME сделал текущим значением строку пути. Флаги из разных групп объединены оператором |; SKIP_DOTS убрал только . и ...

Скачать самостоятельный пример с fixtures, результатом и README

Папка импорта задаётся конфигурацией и может быть пустой строкой, удалённым путём или рабочим каталогом.

Обработать неверную настройку папкиСамостоятельный пример
<?php
declare(strict_types=1);

foreach (['empty' => '', 'missing' => __DIR__ . '/fixtures/not-created'] as $label => $path) {
    try {
        new FilesystemIterator($path);
        echo $label, "=opened\n";
    } catch (Throwable $error) {
        echo $label, '=', $error::class, "\n";
    }
}
$iterator = new FilesystemIterator(__DIR__ . '/fixtures/existing');
echo 'existingEntries=', iterator_count($iterator), "\n";
Ожидаемый результат
empty=ValueError
missing=UnexpectedValueException
existingEntries=1

Конструктор отказал до начала обхода: пустое значение вызвало ValueError, отсутствующий путь — UnexpectedValueException. Рабочая папка открылась; iterator_count() здесь считает её единственную нескрытую служебными точками запись.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

FilesystemIterator::__construct

(PHP 5 >= 5.3.0, PHP 7, PHP 8) FilesystemIterator::__construct — Constructs a new filesystem iterator

Description

public function FilesystemIterator::__construct(string $directory, int $flags = FilesystemIterator::KEY_AS_PATHNAME | FilesystemIterator::CURRENT_AS_FILEINFO | FilesystemIterator::SKIP_DOTS)

Constructs a new filesystem iterator from the directory.

Parameters

directory

The path of the filesystem item to be iterated over.

flags

Flags may be provided which will affect the behavior of some methods. A list of the flags can found under FilesystemIterator predefined constants. They can also be set later with FilesystemIterator::setFlags()

Errors/Exceptions

Throws an UnexpectedValueException if the directory does not exist.

Throws a ValueError if the directory is an empty string.

Changelog

Version Description

8.2.0

Prior to PHP 8.2.0, FilesystemIterator::SKIP_DOTS was always set and could not be removed.

8.0.0

Now throws a ValueError if directory is an empty string; previously it threw a RuntimeException.

See Also

FilesystemIterator::setFlags() - Sets handling flags

DirectoryIterator::__construct() - Constructs a new directory iterator from a path

Связанные карточки: DirectoryIterator::current, GlobIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

FilesystemIterator::currentFilesystemIterator::current: получить текущее значение без продвижения курсора

PHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.2) · SPL

public function FilesystemIterator::current(): SplFileInfo|FilesystemIterator|string

FilesystemIterator::current нужен, чтобы получить текущее значение без продвижения курсора. В этой задаче FilesystemIterator помогает обойти одну папку и заранее выбрать, что считать ключом и текущим значением. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function FilesystemIterator::current(): SplFileInfo|FilesystemIterator|string
Результатstring|SplFileInfo|FilesystemIterator: точный тип выбирает группа CURRENT_*; три самостоятельных примера показывают каждую форму и её последствия.
Ошибки и особые значенияСначала вызывайте valid(). На недействительном курсоре особое значение зависит от класса и не должно смешиваться с настоящим null.
ВерсииPHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.2)

Шаблонизатору нужен короткий ключ для подписи и полный путь-строка для передачи функции чтения файла.

Получить имя-ключ и строку полного путиСамостоятельный пример
<?php
declare(strict_types=1);

$flags = FilesystemIterator::KEY_AS_FILENAME
    | FilesystemIterator::CURRENT_AS_PATHNAME
    | FilesystemIterator::SKIP_DOTS;
$iterator = new FilesystemIterator(__DIR__ . '/fixtures/storage', $flags);
$rows = [];
foreach ($iterator as $key => $current) {
    $rows[] = $key . '|current=' . get_debug_type($current)
        . '|basename=' . basename($current);
}
sort($rows);
echo implode("\n", $rows), "\n";
Ожидаемый результат
.env|current=string|basename=.env
a.txt|current=string|basename=a.txt
b.log|current=string|basename=b.log
data|current=string|basename=data

KEY_AS_FILENAME сделал ключом только имя, CURRENT_AS_PATHNAME сделал текущим значением строку пути. Флаги из разных групп объединены оператором |; SKIP_DOTS убрал только . и ...

Скачать самостоятельный пример с fixtures, результатом и README

Перед отправкой файлов нужно узнать их размер, не открывая содержимое.

Читать размер через объекты SplFileInfoСамостоятельный пример
<?php
declare(strict_types=1);

$flags = FilesystemIterator::KEY_AS_FILENAME
    | FilesystemIterator::CURRENT_AS_FILEINFO
    | FilesystemIterator::SKIP_DOTS;
$iterator = new FilesystemIterator(__DIR__ . '/fixtures/files', $flags);
$rows = [];
foreach ($iterator as $name => $file) {
    if ($file->isFile()) {
        $rows[] = $name . '|class=' . $file::class . '|bytes=' . $file->getSize();
    }
}
sort($rows);
echo implode("\n", $rows), "\n";
Ожидаемый результат
a.txt|class=SplFileInfo|bytes=3
b.log|class=SplFileInfo|bytes=5

CURRENT_AS_FILEINFO вернул для каждой позиции SplFileInfo. Объект дал isFile() и getSize(); значение 0 этой константы проверяют сравнением маски режима, а не условием if ($flags & CURRENT_AS_FILEINFO).

Скачать самостоятельный пример с fixtures, результатом и README

Низкоуровневый обработчик хочет работать с одним объектом-курсором и читать у него унаследованные методы SplFileInfo.

Получить сам курсор как текущее значениеСамостоятельный пример
<?php
declare(strict_types=1);

$flags = FilesystemIterator::KEY_AS_FILENAME
    | FilesystemIterator::CURRENT_AS_SELF
    | FilesystemIterator::SKIP_DOTS;
$iterator = new FilesystemIterator(__DIR__ . '/fixtures/self', $flags);
$rows = [];
foreach ($iterator as $name => $current) {
    $rows[] = $name . '|class=' . $current::class
        . '|same=' . ($current === $iterator ? 'yes' : 'no');
}
sort($rows);
echo implode("\n", $rows), "\n";
Ожидаемый результат
first.txt|class=FilesystemIterator|same=yes
second.txt|class=FilesystemIterator|same=yes

CURRENT_AS_SELF вернул один и тот же FilesystemIterator, состояние которого меняется на каждой позиции. Сохранять такой current() в массив как независимый снимок нельзя; для снимков выбирают CURRENT_AS_FILEINFO или извлекают нужные скаляры.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

FilesystemIterator::current

(PHP 5 >= 5.3.0, PHP 7, PHP 8) FilesystemIterator::current — The current file

Description

public function FilesystemIterator::current(): string|SplFileInfo|FilesystemIterator

Get file information of the current element.

Parameters

This function has no parameters.

Return Values

The filename, file information, or $this depending on the set flags. See the FilesystemIterator constants.

See Also

FilesystemIterator constants

DirectoryIterator::current() - Return the current DirectoryIterator item

DirectoryIterator::getFileName() - Return file name of current DirectoryIterator item

Связанные карточки: DirectoryIterator::current, GlobIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

FilesystemIterator::getFlagsFilesystemIterator::getFlags: прочитать действующую битовую маску режима объекта

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function FilesystemIterator::getFlags(): int

FilesystemIterator::getFlags нужен, чтобы прочитать действующую битовую маску режима объекта. В этой задаче FilesystemIterator помогает обойти одну папку и заранее выбрать, что считать ключом и текущим значением. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function FilesystemIterator::getFlags(): int
Результатint: полная битовая маска. Режим с нулевой константой, например CURRENT_AS_FILEINFO, проверяют как ($flags & CURRENT_MODE_MASK) === CURRENT_AS_FILEINFO.
Ошибки и особые значенияTypeError и исключения вложенного источника не скрываются. Особые значения, предупреждения и версии перечислены в полном официальном контракте ниже.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Код меняет форму current(), но должен понимать, почему после небрежной смены режима внезапно появились . и ...

Показать, что setFlags() заменяет маску целикомСамостоятельный пример
<?php
declare(strict_types=1);

$initial = FilesystemIterator::KEY_AS_FILENAME
    | FilesystemIterator::CURRENT_AS_PATHNAME
    | FilesystemIterator::SKIP_DOTS;
$iterator = new FilesystemIterator(__DIR__ . '/fixtures/flags', $initial);
echo 'initialSkip=', ($iterator->getFlags() & FilesystemIterator::SKIP_DOTS) !== 0 ? 'yes' : 'no', "\n";

$iterator->setFlags(
    FilesystemIterator::KEY_AS_FILENAME
    | FilesystemIterator::CURRENT_AS_PATHNAME
);
echo 'afterReplaceSkip=', ($iterator->getFlags() & FilesystemIterator::SKIP_DOTS) !== 0 ? 'yes' : 'no', "\n";
$dotEntries = 0;
foreach ($iterator as $entry) {
    if ($iterator->isDot()) {
        $dotEntries++;
    }
}
echo 'dotEntries=', $dotEntries, "\n";

$iterator->setFlags(
    FilesystemIterator::KEY_AS_FILENAME
    | FilesystemIterator::CURRENT_AS_FILEINFO
    | FilesystemIterator::SKIP_DOTS
);
$mode = $iterator->getFlags() & FilesystemIterator::CURRENT_MODE_MASK;
echo 'fileInfoMode=', $mode === FilesystemIterator::CURRENT_AS_FILEINFO ? 'yes' : 'no', "\n";
Ожидаемый результат
initialSkip=yes
afterReplaceSkip=no
dotEntries=2
fileInfoMode=yes

Первый setFlags() получил новую полную маску без SKIP_DOTS, поэтому служебные точки вернулись. Второй вызов явно собрал все требуемые группы. CURRENT_AS_FILEINFO равен 0, поэтому текущий режим извлечён через CURRENT_MODE_MASK и проверен строгим равенством.

Скачать самостоятельный пример с fixtures, результатом и README

Первый потребитель индексирует записи по полному пути, второй формирует короткий список имён для интерфейса.

Переключить ключ с полного пути на имя файлаСамостоятельный пример
<?php
declare(strict_types=1);

$pathMode = FilesystemIterator::KEY_AS_PATHNAME
    | FilesystemIterator::CURRENT_AS_FILEINFO
    | FilesystemIterator::SKIP_DOTS;
$iterator = new FilesystemIterator(__DIR__ . '/fixtures/keys', $pathMode);
$pathRows = [];
$iterator->rewind();
foreach ($iterator as $key => $file) {
    $pathRows[] = basename($key) . '|hasParent=' . ($key !== basename($key) ? 'yes' : 'no');
}
sort($pathRows);
echo 'pathnameKeys=', implode(',', $pathRows), "\n";

$iterator->setFlags(
    FilesystemIterator::KEY_AS_FILENAME
    | FilesystemIterator::CURRENT_AS_PATHNAME
    | FilesystemIterator::SKIP_DOTS
);
$nameRows = [];
$iterator->rewind();
foreach ($iterator as $key => $path) {
    $nameRows[] = $key . '|current=' . get_debug_type($path);
}
sort($nameRows);
echo 'filenameKeys=', implode(',', $nameRows), "\n";
Ожидаемый результат
pathnameKeys=a.txt|hasParent=yes,b.txt|hasParent=yes
filenameKeys=a.txt|current=string,b.txt|current=string

KEY_AS_PATHNAME и KEY_AS_FILENAME меняют только key(). Независимая группа CURRENT_* задаёт current(). setFlags() во второй половине одновременно и явно выбрал обе формы и сохранил SKIP_DOTS.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

FilesystemIterator::getFlags

(PHP 5 >= 5.3.0, PHP 7, PHP 8) FilesystemIterator::getFlags — Get the handling flags

Description

public function FilesystemIterator::getFlags(): int

Gets the handling flags, as set in FilesystemIterator::__construct() or FilesystemIterator::setFlags().

Parameters

This function has no parameters.

Return Values

The integer value of the set flags.

See Also

FilesystemIterator::__construct() - Constructs a new filesystem iterator

FilesystemIterator::setFlags() - Sets handling flags

Связанные карточки: DirectoryIterator::current, GlobIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

FilesystemIterator::keyFilesystemIterator::key: получить ключ или позицию текущего элемента

PHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.2) · SPL

public function FilesystemIterator::key(): string

FilesystemIterator::key нужен, чтобы получить ключ или позицию текущего элемента. В этой задаче FilesystemIterator помогает обойти одну папку и заранее выбрать, что считать ключом и текущим значением. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function FilesystemIterator::key(): string
Результатstring: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование.
Ошибки и особые значенияСначала вызывайте valid(). Ключ может быть int, string или составным массивом и не обязан быть бизнес-идентификатором.
ВерсииPHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.2)

Шаблонизатору нужен короткий ключ для подписи и полный путь-строка для передачи функции чтения файла.

Получить имя-ключ и строку полного путиСамостоятельный пример
<?php
declare(strict_types=1);

$flags = FilesystemIterator::KEY_AS_FILENAME
    | FilesystemIterator::CURRENT_AS_PATHNAME
    | FilesystemIterator::SKIP_DOTS;
$iterator = new FilesystemIterator(__DIR__ . '/fixtures/storage', $flags);
$rows = [];
foreach ($iterator as $key => $current) {
    $rows[] = $key . '|current=' . get_debug_type($current)
        . '|basename=' . basename($current);
}
sort($rows);
echo implode("\n", $rows), "\n";
Ожидаемый результат
.env|current=string|basename=.env
a.txt|current=string|basename=a.txt
b.log|current=string|basename=b.log
data|current=string|basename=data

KEY_AS_FILENAME сделал ключом только имя, CURRENT_AS_PATHNAME сделал текущим значением строку пути. Флаги из разных групп объединены оператором |; SKIP_DOTS убрал только . и ...

Скачать самостоятельный пример с fixtures, результатом и README

Первый потребитель индексирует записи по полному пути, второй формирует короткий список имён для интерфейса.

Переключить ключ с полного пути на имя файлаСамостоятельный пример
<?php
declare(strict_types=1);

$pathMode = FilesystemIterator::KEY_AS_PATHNAME
    | FilesystemIterator::CURRENT_AS_FILEINFO
    | FilesystemIterator::SKIP_DOTS;
$iterator = new FilesystemIterator(__DIR__ . '/fixtures/keys', $pathMode);
$pathRows = [];
$iterator->rewind();
foreach ($iterator as $key => $file) {
    $pathRows[] = basename($key) . '|hasParent=' . ($key !== basename($key) ? 'yes' : 'no');
}
sort($pathRows);
echo 'pathnameKeys=', implode(',', $pathRows), "\n";

$iterator->setFlags(
    FilesystemIterator::KEY_AS_FILENAME
    | FilesystemIterator::CURRENT_AS_PATHNAME
    | FilesystemIterator::SKIP_DOTS
);
$nameRows = [];
$iterator->rewind();
foreach ($iterator as $key => $path) {
    $nameRows[] = $key . '|current=' . get_debug_type($path);
}
sort($nameRows);
echo 'filenameKeys=', implode(',', $nameRows), "\n";
Ожидаемый результат
pathnameKeys=a.txt|hasParent=yes,b.txt|hasParent=yes
filenameKeys=a.txt|current=string,b.txt|current=string

KEY_AS_PATHNAME и KEY_AS_FILENAME меняют только key(). Независимая группа CURRENT_* задаёт current(). setFlags() во второй половине одновременно и явно выбрал обе формы и сохранил SKIP_DOTS.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

FilesystemIterator::key

(PHP 5 >= 5.3.0, PHP 7, PHP 8) FilesystemIterator::key — Retrieve the key for the current file

Description

public function FilesystemIterator::key(): string

Parameters

This function has no parameters.

Return Values

Returns the pathname or filename depending on the set flags. See the FilesystemIterator constants.

See Also

FilesystemIterator constants

DirectoryIterator::key() - Return the key for the current DirectoryIterator item

DirectoryIterator::getFilename() - Return file name of current DirectoryIterator item

DirectoryIterator::getPathname()

Связанные карточки: DirectoryIterator::current, GlobIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

FilesystemIterator::nextFilesystemIterator::next: перевести курсор к следующему элементу

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function FilesystemIterator::next(): void

FilesystemIterator::next нужен, чтобы перевести курсор к следующему элементу. В этой задаче FilesystemIterator помогает обойти одну папку и заранее выбрать, что считать ключом и текущим значением. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function FilesystemIterator::next(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияПродвижение одноразового источника нельзя отменить. Исключение из вложенного источника передаётся вызывающему коду.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Фоновая задача сначала проверяет список, затем повторно обрабатывает ту же маленькую папку.

Пройти курсор вручную и повторить проходСамостоятельный пример
<?php
declare(strict_types=1);

function collect(FilesystemIterator $iterator): array
{
    $rows = [];
    $iterator->rewind();
    while ($iterator->valid()) {
        $rows[] = $iterator->key() . '=' . basename((string) $iterator->current());
        $iterator->next();
    }
    sort($rows);
    return $rows;
}

$flags = FilesystemIterator::KEY_AS_FILENAME
    | FilesystemIterator::CURRENT_AS_PATHNAME
    | FilesystemIterator::SKIP_DOTS;
$iterator = new FilesystemIterator(__DIR__ . '/fixtures/cursor', $flags);
$first = collect($iterator);
$second = collect($iterator);
echo implode(',', $first), "\n";
echo 'sameAfterRewind=', $first === $second ? 'yes' : 'no', "\n";
Ожидаемый результат
a.txt=a.txt,b.txt=b.txt
sameAfterRewind=yes

Явная последовательность rewind → valid → key/current → next соответствует тому, что делает foreach. После конца новый rewind() разрешил второй проход; сортировка используется только для предсказуемого отчёта.

Скачать самостоятельный пример с fixtures, результатом и README

Сканер конфигурации должен пропустить переходы . и .., но прочитать реальный файл .env.

Не потерять .env при включённом SKIP_DOTSСамостоятельный пример
<?php
declare(strict_types=1);

$flags = FilesystemIterator::KEY_AS_FILENAME
    | FilesystemIterator::CURRENT_AS_FILEINFO
    | FilesystemIterator::SKIP_DOTS;
$iterator = new FilesystemIterator(__DIR__ . '/fixtures/hidden', $flags);
$names = [];
$dotEntries = 0;
$iterator->rewind();
while ($iterator->valid()) {
    $names[] = $iterator->key();
    $dotEntries += $iterator->isDot() ? 1 : 0;
    $iterator->next();
}
sort($names);
echo 'names=', implode(',', $names), "\n";
echo 'serviceDotEntries=', $dotEntries, "\n";
Ожидаемый результат
names=.env,public.txt
serviceDotEntries=0

SKIP_DOTS относится только к двум служебным записям. Он не является фильтром скрытых или начинающихся с точки файлов: .env остался в результате. Для отдельной политики скрытых файлов проверяйте имя самостоятельно.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

FilesystemIterator::next

(PHP 5 >= 5.3.0, PHP 7, PHP 8) FilesystemIterator::next — Move to the next file

Description

public function FilesystemIterator::next(): void

Move to the next file.

Parameters

This function has no parameters.

Return Values

No value is returned.

See Also

DirectoryIterator::next() - Move forward to next DirectoryIterator item

Связанные карточки: DirectoryIterator::current, GlobIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

FilesystemIterator::rewindFilesystemIterator::rewind: попытаться установить курсор на первый элемент

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function FilesystemIterator::rewind(): void

FilesystemIterator::rewind нужен, чтобы попытаться установить курсор на первый элемент. В этой задаче FilesystemIterator помогает обойти одну папку и заранее выбрать, что считать ключом и текущим значением. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function FilesystemIterator::rewind(): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияНе каждый Traversable можно повторить. NoRewindIterator намеренно игнорирует повторную перемотку, а Generator после завершения может выбросить исключение.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Фоновая задача сначала проверяет список, затем повторно обрабатывает ту же маленькую папку.

Пройти курсор вручную и повторить проходСамостоятельный пример
<?php
declare(strict_types=1);

function collect(FilesystemIterator $iterator): array
{
    $rows = [];
    $iterator->rewind();
    while ($iterator->valid()) {
        $rows[] = $iterator->key() . '=' . basename((string) $iterator->current());
        $iterator->next();
    }
    sort($rows);
    return $rows;
}

$flags = FilesystemIterator::KEY_AS_FILENAME
    | FilesystemIterator::CURRENT_AS_PATHNAME
    | FilesystemIterator::SKIP_DOTS;
$iterator = new FilesystemIterator(__DIR__ . '/fixtures/cursor', $flags);
$first = collect($iterator);
$second = collect($iterator);
echo implode(',', $first), "\n";
echo 'sameAfterRewind=', $first === $second ? 'yes' : 'no', "\n";
Ожидаемый результат
a.txt=a.txt,b.txt=b.txt
sameAfterRewind=yes

Явная последовательность rewind → valid → key/current → next соответствует тому, что делает foreach. После конца новый rewind() разрешил второй проход; сортировка используется только для предсказуемого отчёта.

Скачать самостоятельный пример с fixtures, результатом и README

Первый потребитель индексирует записи по полному пути, второй формирует короткий список имён для интерфейса.

Переключить ключ с полного пути на имя файлаСамостоятельный пример
<?php
declare(strict_types=1);

$pathMode = FilesystemIterator::KEY_AS_PATHNAME
    | FilesystemIterator::CURRENT_AS_FILEINFO
    | FilesystemIterator::SKIP_DOTS;
$iterator = new FilesystemIterator(__DIR__ . '/fixtures/keys', $pathMode);
$pathRows = [];
$iterator->rewind();
foreach ($iterator as $key => $file) {
    $pathRows[] = basename($key) . '|hasParent=' . ($key !== basename($key) ? 'yes' : 'no');
}
sort($pathRows);
echo 'pathnameKeys=', implode(',', $pathRows), "\n";

$iterator->setFlags(
    FilesystemIterator::KEY_AS_FILENAME
    | FilesystemIterator::CURRENT_AS_PATHNAME
    | FilesystemIterator::SKIP_DOTS
);
$nameRows = [];
$iterator->rewind();
foreach ($iterator as $key => $path) {
    $nameRows[] = $key . '|current=' . get_debug_type($path);
}
sort($nameRows);
echo 'filenameKeys=', implode(',', $nameRows), "\n";
Ожидаемый результат
pathnameKeys=a.txt|hasParent=yes,b.txt|hasParent=yes
filenameKeys=a.txt|current=string,b.txt|current=string

KEY_AS_PATHNAME и KEY_AS_FILENAME меняют только key(). Независимая группа CURRENT_* задаёт current(). setFlags() во второй половине одновременно и явно выбрал обе формы и сохранил SKIP_DOTS.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

FilesystemIterator::rewind

(PHP 5 >= 5.3.0, PHP 7, PHP 8) FilesystemIterator::rewind — Rewinds back to the beginning

Description

public function FilesystemIterator::rewind(): void

Rewinds the directory back to the start.

Parameters

This function has no parameters.

Return Values

No value is returned.

See Also

DirectoryIterator::rewind() - Rewind the DirectoryIterator back to the start

Связанные карточки: DirectoryIterator::current, GlobIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

FilesystemIterator::setFlagsFilesystemIterator::setFlags: заменить действующую битовую маску режима

PHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.2) · SPL

public function FilesystemIterator::setFlags(int $flags): void

FilesystemIterator::setFlags нужен, чтобы заменить действующую битовую маску режима. В этой задаче FilesystemIterator помогает обойти одну папку и заранее выбрать, что считать ключом и текущим значением. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
flagsБитовая маска режима. Оператор | объединяет совместимые константы; setFlags заменяет прежнюю маску целиком.
Часть контрактаЧто важно
Сигнатураpublic function FilesystemIterator::setFlags(int $flags): void
Результатvoid: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет.
Ошибки и особые значенияМетод принимает int и заменяет всю маску. Забытый SKIP_DOTS возвращает . и ..; несовместимая форма current/key ломает ожидания потребителя даже без исключения.
ВерсииPHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.2)

Код меняет форму current(), но должен понимать, почему после небрежной смены режима внезапно появились . и ...

Показать, что setFlags() заменяет маску целикомСамостоятельный пример
<?php
declare(strict_types=1);

$initial = FilesystemIterator::KEY_AS_FILENAME
    | FilesystemIterator::CURRENT_AS_PATHNAME
    | FilesystemIterator::SKIP_DOTS;
$iterator = new FilesystemIterator(__DIR__ . '/fixtures/flags', $initial);
echo 'initialSkip=', ($iterator->getFlags() & FilesystemIterator::SKIP_DOTS) !== 0 ? 'yes' : 'no', "\n";

$iterator->setFlags(
    FilesystemIterator::KEY_AS_FILENAME
    | FilesystemIterator::CURRENT_AS_PATHNAME
);
echo 'afterReplaceSkip=', ($iterator->getFlags() & FilesystemIterator::SKIP_DOTS) !== 0 ? 'yes' : 'no', "\n";
$dotEntries = 0;
foreach ($iterator as $entry) {
    if ($iterator->isDot()) {
        $dotEntries++;
    }
}
echo 'dotEntries=', $dotEntries, "\n";

$iterator->setFlags(
    FilesystemIterator::KEY_AS_FILENAME
    | FilesystemIterator::CURRENT_AS_FILEINFO
    | FilesystemIterator::SKIP_DOTS
);
$mode = $iterator->getFlags() & FilesystemIterator::CURRENT_MODE_MASK;
echo 'fileInfoMode=', $mode === FilesystemIterator::CURRENT_AS_FILEINFO ? 'yes' : 'no', "\n";
Ожидаемый результат
initialSkip=yes
afterReplaceSkip=no
dotEntries=2
fileInfoMode=yes

Первый setFlags() получил новую полную маску без SKIP_DOTS, поэтому служебные точки вернулись. Второй вызов явно собрал все требуемые группы. CURRENT_AS_FILEINFO равен 0, поэтому текущий режим извлечён через CURRENT_MODE_MASK и проверен строгим равенством.

Скачать самостоятельный пример с fixtures, результатом и README

Первый потребитель индексирует записи по полному пути, второй формирует короткий список имён для интерфейса.

Переключить ключ с полного пути на имя файлаСамостоятельный пример
<?php
declare(strict_types=1);

$pathMode = FilesystemIterator::KEY_AS_PATHNAME
    | FilesystemIterator::CURRENT_AS_FILEINFO
    | FilesystemIterator::SKIP_DOTS;
$iterator = new FilesystemIterator(__DIR__ . '/fixtures/keys', $pathMode);
$pathRows = [];
$iterator->rewind();
foreach ($iterator as $key => $file) {
    $pathRows[] = basename($key) . '|hasParent=' . ($key !== basename($key) ? 'yes' : 'no');
}
sort($pathRows);
echo 'pathnameKeys=', implode(',', $pathRows), "\n";

$iterator->setFlags(
    FilesystemIterator::KEY_AS_FILENAME
    | FilesystemIterator::CURRENT_AS_PATHNAME
    | FilesystemIterator::SKIP_DOTS
);
$nameRows = [];
$iterator->rewind();
foreach ($iterator as $key => $path) {
    $nameRows[] = $key . '|current=' . get_debug_type($path);
}
sort($nameRows);
echo 'filenameKeys=', implode(',', $nameRows), "\n";
Ожидаемый результат
pathnameKeys=a.txt|hasParent=yes,b.txt|hasParent=yes
filenameKeys=a.txt|current=string,b.txt|current=string

KEY_AS_PATHNAME и KEY_AS_FILENAME меняют только key(). Независимая группа CURRENT_* задаёт current(). setFlags() во второй половине одновременно и явно выбрал обе формы и сохранил SKIP_DOTS.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

FilesystemIterator::setFlags

(PHP 5 >= 5.3.0, PHP 7, PHP 8) FilesystemIterator::setFlags — Sets handling flags

Description

public function FilesystemIterator::setFlags(int $flags): void

Sets handling flags.

Parameters

flags

The handling flags to set. See the FilesystemIterator constants.

Return Values

No value is returned.

See Also

FilesystemIterator::__construct() - Constructs a new filesystem iterator

FilesystemIterator::getFlags() - Get the handling flags

Связанные карточки: DirectoryIterator::current, GlobIterator::__construct.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

GlobIterator::__constructGlobIterator::__construct: создать и настроить объект для дальнейшего обхода

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function GlobIterator::__construct(string $pattern, int $flags = 0)

GlobIterator::__construct нужен, чтобы создать и настроить объект для дальнейшего обхода. В этой задаче GlobIterator помогает получить только локальные пути, совпавшие с файловой маской, и узнать их число. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
patternСтрока пути с синтаксисом glob: * — любое число символов в одном компоненте, ? — один символ. Пример привязывает маску к __DIR__.
flagsБитовая маска поддерживаемых констант FilesystemIterator для формы key/current и файлового поведения; это не произвольный набор флагов glob().
Часть контрактаЧто важно
Сигнатураpublic function GlobIterator::__construct(string $pattern, int $flags = 0)
РезультатКонструктор не возвращает прикладное значение; выражение new создаёт объект, который затем сохраняется в переменной.
Ошибки и особые значенияПустая строка вызывает ValueError; ошибочный или недоступный путь может вызвать UnexpectedValueException. Ноль совпадений в существующей папке является допустимым пустым итератором.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Генератор превью должен взять только JPG непосредственно из uploads и не читать notes.txt или вложенную папку.

Выбрать только JPG текущей папкиСамостоятельный пример
<?php
declare(strict_types=1);

$pattern = __DIR__ . '/fixtures/uploads/*.jpg';
$iterator = new GlobIterator($pattern, FilesystemIterator::KEY_AS_FILENAME);
$names = [];
foreach ($iterator as $name => $file) {
    $names[] = $name;
}
sort($names);
echo 'matched=', $iterator->count(), "\n";
echo 'names=', implode(',', $names), "\n";
echo 'nestedIncluded=', in_array('deep.jpg', $names, true) ? 'yes' : 'no', "\n";
Ожидаемый результат
matched=2
names=hero.jpg,thumb.jpg
nestedIncluded=no

Шаблон *.jpg сопоставился с двумя именами одного уровня. count() вернул число совпавших путей. GlobIterator не выполняет рекурсивный поиск: sub/deep.jpg не попал в список.

Скачать самостоятельный пример с fixtures, результатом и README

Папка существует, но сегодня XML-файлов нет. Это нормальный пустой результат, а не повод падать.

Отличить ноль совпадений от ошибки конструктораСамостоятельный пример
<?php
declare(strict_types=1);

$iterator = new GlobIterator(
    __DIR__ . '/fixtures/documents/*.xml',
    FilesystemIterator::KEY_AS_FILENAME
);
$iterations = 0;
foreach ($iterator as $file) {
    $iterations++;
}
echo 'matched=', $iterator->count(), "\n";
echo 'iterations=', $iterations, "\n";
Ожидаемый результат
matched=0
iterations=0

Конструктор создал допустимый GlobIterator. count() вернул 0, foreach не выполнил тело ни разу. Отсутствующий каталог и пустой результат маски — разные состояния, их не следует объединять в одно сообщение.

Скачать самостоятельный пример с fixtures, результатом и README

Архиватор ищет файлы выбранного года, у которых после дефиса ровно два символа месяца.

Отобрать резервные копии с двухзначным месяцемСамостоятельный пример
<?php
declare(strict_types=1);

$pattern = __DIR__ . '/fixtures/backups/report-2026-??.csv';
$iterator = new GlobIterator($pattern, FilesystemIterator::KEY_AS_FILENAME);
$names = [];
foreach ($iterator as $name => $file) {
    $names[] = $name;
}
sort($names);
echo 'matched=', count($iterator), "\n";
echo implode("\n", $names), "\n";
Ожидаемый результат
matched=2
report-2026-01.csv
report-2026-10.csv

Каждый знак ? в glob-шаблоне соответствует одному символу имени. Поэтому два цифровых по факту имени совпали, а report-2026-final.csv и файл другого года — нет. Маска не проверяет, что символы являются цифрами; строгую проверку можно добавить после отбора.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

GlobIterator::__construct

(PHP 5 >= 5.3.0, PHP 7, PHP 8) GlobIterator::__construct — Construct a directory using glob

Description

public function GlobIterator::__construct(string $pattern, int $flags = FilesystemIterator::KEY_AS_PATHNAME | FilesystemIterator::CURRENT_AS_FILEINFO)

Constructs a new directory iterator from a glob expression.

Parameters

pattern

A glob() pattern.

flags

Option flags, the flags may be a bitmask of the FilesystemIterator constants.

Errors/Exceptions

Throws an UnexpectedValueException if the directory does not exist.

Throws a ValueError if the directory is an empty string.

Changelog

Version Description

8.0.0

Now throws a ValueError if directory is an empty string; previously it threw a RuntimeException.

See Also

DirectoryIterator::__construct() - Constructs a new directory iterator from a path

GlobIterator::count() - Get the number of directories and files

glob() - Find pathnames matching a pattern

Связанные карточки: FilesystemIterator::__construct, FilesystemIterator::key.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

GlobIterator::countGlobIterator::count: получить число элементов, которое определяет этот класс

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function GlobIterator::count(): int

GlobIterator::count нужен, чтобы получить число элементов, которое определяет этот класс. В этой задаче GlobIterator помогает получить только локальные пути, совпавшие с файловой маской, и узнать их число. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function GlobIterator::count(): int
Результатint: число путей, совпавших с маской. Ноль означает пустой результат, а не автоматически ошибку файловой системы.
Ошибки и особые значенияTypeError и исключения вложенного источника не скрываются. Особые значения, предупреждения и версии перечислены в полном официальном контракте ниже.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Генератор превью должен взять только JPG непосредственно из uploads и не читать notes.txt или вложенную папку.

Выбрать только JPG текущей папкиСамостоятельный пример
<?php
declare(strict_types=1);

$pattern = __DIR__ . '/fixtures/uploads/*.jpg';
$iterator = new GlobIterator($pattern, FilesystemIterator::KEY_AS_FILENAME);
$names = [];
foreach ($iterator as $name => $file) {
    $names[] = $name;
}
sort($names);
echo 'matched=', $iterator->count(), "\n";
echo 'names=', implode(',', $names), "\n";
echo 'nestedIncluded=', in_array('deep.jpg', $names, true) ? 'yes' : 'no', "\n";
Ожидаемый результат
matched=2
names=hero.jpg,thumb.jpg
nestedIncluded=no

Шаблон *.jpg сопоставился с двумя именами одного уровня. count() вернул число совпавших путей. GlobIterator не выполняет рекурсивный поиск: sub/deep.jpg не попал в список.

Скачать самостоятельный пример с fixtures, результатом и README

Папка существует, но сегодня XML-файлов нет. Это нормальный пустой результат, а не повод падать.

Отличить ноль совпадений от ошибки конструктораСамостоятельный пример
<?php
declare(strict_types=1);

$iterator = new GlobIterator(
    __DIR__ . '/fixtures/documents/*.xml',
    FilesystemIterator::KEY_AS_FILENAME
);
$iterations = 0;
foreach ($iterator as $file) {
    $iterations++;
}
echo 'matched=', $iterator->count(), "\n";
echo 'iterations=', $iterations, "\n";
Ожидаемый результат
matched=0
iterations=0

Конструктор создал допустимый GlobIterator. count() вернул 0, foreach не выполнил тело ни разу. Отсутствующий каталог и пустой результат маски — разные состояния, их не следует объединять в одно сообщение.

Скачать самостоятельный пример с fixtures, результатом и README

Архиватор ищет файлы выбранного года, у которых после дефиса ровно два символа месяца.

Отобрать резервные копии с двухзначным месяцемСамостоятельный пример
<?php
declare(strict_types=1);

$pattern = __DIR__ . '/fixtures/backups/report-2026-??.csv';
$iterator = new GlobIterator($pattern, FilesystemIterator::KEY_AS_FILENAME);
$names = [];
foreach ($iterator as $name => $file) {
    $names[] = $name;
}
sort($names);
echo 'matched=', count($iterator), "\n";
echo implode("\n", $names), "\n";
Ожидаемый результат
matched=2
report-2026-01.csv
report-2026-10.csv

Каждый знак ? в glob-шаблоне соответствует одному символу имени. Поэтому два цифровых по факту имени совпали, а report-2026-final.csv и файл другого года — нет. Маска не проверяет, что символы являются цифрами; строгую проверку можно добавить после отбора.

Скачать самостоятельный пример с fixtures, результатом и README

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Нормативные правила и версии сохранены; учебные программы написаны заново и проверяются отдельно.

GlobIterator::count

(PHP 5 >= 5.3.0, PHP 7, PHP 8) GlobIterator::count — Get the number of directories and files

Description

public function GlobIterator::count(): int

Gets the number of directories and files found by the glob expression.

Parameters

This function has no parameters.

Return Values

The number of returned directories and files, as an int.

See Also

GlobIterator::__construct() - Construct a directory using glob

count() - Counts all elements in an array or in a Countable object

glob() - Find pathnames matching a pattern

Связанные карточки: FilesystemIterator::__construct, FilesystemIterator::key.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileInfo::__constructСоздать карточку пути, затем открыть настоящий файл.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileInfo::__construct(string $filename)

Конструктор принимает имя даже отсутствующего/недоступного файла. Сведения о пути и чтение содержимого — отдельные действия.

ПараметрЧто означает в задаче
filenameПуть к файлу. В архиве это input/receipt.txt рядом с example.php; __DIR__ привязывает путь к папке программы.
Часть контрактаЧто важно
Сигнатураpublic function SplFileInfo::__construct(string $filename)
РезультатСтрока пути/имени; конструктор создаёт объект.
Ошибки и особые значенияДля этих операций строкового пути файл может отсутствовать. Ошибки фактического открытия обрабатываются отдельно; NUL в пути недопустим.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Файл input/receipt.txt уже приложен. chdir(__DIR__) делает папку программы текущей: относительный путь input/receipt.txt теперь однозначен. new SplFileInfo создаёт карточку пути, а не открывает содержимое; -> вызывает действие этой карточки. Конструктор принимает имя даже отсутствующего/недоступного файла. Сведения о пути и чтение содержимого — отдельные действия.

Путь и подпись документаСамостоятельный пример
<?php
declare(strict_types=1);

chdir(__DIR__);
$info = new SplFileInfo('input/receipt.txt');
echo $info->getFilename() . "\n";
echo $info->openFile('rb')->fgets();
Ожидаемый результат
receipt.txt
Заказ 42

Полученное значение можно использовать как подпись или известный локальный путь.

Конструктору передаём ещё не существующий new-receipt.txt. isFile проверяет наличие обычного файла. Само создание карточки ничего на диск не записывает.

Пограничный случай имени или чтение по путиСамостоятельный пример
<?php
declare(strict_types=1);

chdir(__DIR__);
$draft = new SplFileInfo('new-receipt.txt');
echo 'Планируемый путь: ' . $draft->getPathname() . "\n";
if (!$draft->isFile()) { echo "Документ пока не создан.\n"; }
Ожидаемый результат
Планируемый путь: new-receipt.txt
Документ пока не создан.

Имя и расположение не смешиваются с содержимым документа.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileInfo::__construct

(PHP 5 >= 5.1.2, PHP 7, PHP 8) SplFileInfo::__construct — Construct a new SplFileInfo object

Description

public function SplFileInfo::__construct(string $filename)

Creates a new SplFileInfo object for the file_name specified. The file does not need to exist, or be readable.

Parameters

filename

Path to the file.

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileInfo::getATimeПоказать время последнего доступа и принять решение о документе.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileInfo::getATime(): int|false

Возвращается Unix timestamp — секунды от начала эпохи. date форматирует число в выбранном часовом поясе. Входной файл специально получает фиксированные учебные времена через touch.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileInfo::getATime(): int|false
Результатint timestamp либо false при неудаче.
Ошибки и особые значенияfalse или RuntimeException при невозможности получить сведения; точность времени зависит от файловой системы.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Файл input/receipt.txt уже приложен. chdir(__DIR__) делает папку программы текущей: относительный путь input/receipt.txt теперь однозначен. new SplFileInfo создаёт карточку пути, а не открывает содержимое; -> вызывает действие этой карточки. touch(path, mtime, atime) задаёт времена нашей копии; clearstatcache обновляет кэш. date_default_timezone_set выбирает UTC для одинакового вывода.

Показать время в UTCСамостоятельный пример
<?php
declare(strict_types=1);

chdir(__DIR__);
$info = new SplFileInfo('input/receipt.txt');
date_default_timezone_set('UTC');
touch('input/receipt.txt', 1640995200, 1609459200);
clearstatcache(true, 'input/receipt.txt');
echo 'Время последнего доступа: ' . date('Y-m-d H:i:s', $info->getATime()) . " UTC
";
echo $info->openFile('rb')->fgets();
Ожидаемый результат
Время последнего доступа: 2021-01-01 00:00:00 UTC
Заказ 42

Дата относится к именно этой учебной квитанции, а не к текущему времени компьютера.

Контрольная дата 1704067200 — 2024-01-01 UTC. Сравниваем целые timestamps; затем выводим документ, который попал в выборку. Реального удаления или перемещения нет.

Отобрать старый документ к проверкеСамостоятельный пример
<?php
declare(strict_types=1);

chdir(__DIR__);
$info = new SplFileInfo('input/receipt.txt');
touch('input/receipt.txt', 1640995200, 1609459200);
clearstatcache(true, 'input/receipt.txt');
$stamp = $info->getATime();
if ($stamp === false) { throw new RuntimeException('Нет времени файла'); }
if ($stamp < 1704067200) { echo "Документ до контрольной даты: перенести в архив после проверки.
"; }
echo file_get_contents('input/receipt.txt');
Ожидаемый результат
Документ до контрольной даты: перенести в архив после проверки.
Заказ 42
Кисть — 2 шт.
Итого: 300 руб.

Метаданные помогают найти документ; решение об удалении требует политики хранения и не выполняется в примере.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileInfo::getATime

(PHP 5 >= 5.1.2, PHP 7, PHP 8) SplFileInfo::getATime — Gets last access time of the file

Description

public function SplFileInfo::getATime(): int|false

Gets the last access time for the file.

Parameters

This function has no parameters.

Return Values

Returns the time the file was last accessed on success, or false on failure.

Errors/Exceptions

Throws RuntimeException on error.

See Also

fileatime() - Gets last access time of file

SplFileInfo::getCTime() - Gets the inode change time

SplFileInfo::getMTime() - Gets the last modified time

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileInfo::getBasenameУбрать каталог и известный суффикс из имени.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileInfo::getBasename(string $suffix = ''): string

Необязательный suffix удаляется только с конца возвращаемого имени. Файл на диске не переименовывается; обработка многобайтовых имён зависит от locale.

ПараметрЧто означает в задаче
suffixТочный суффикс, который нужно убрать с конца имени; точка входит в строку ".txt". Исходный файл не переименовывается.
Часть контрактаЧто важно
Сигнатураpublic function SplFileInfo::getBasename(string $suffix = ''): string
РезультатСтрока пути/имени; конструктор создаёт объект.
Ошибки и особые значенияДля этих операций строкового пути файл может отсутствовать. Ошибки фактического открытия обрабатываются отдельно; NUL в пути недопустим.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Файл input/receipt.txt уже приложен. chdir(__DIR__) делает папку программы текущей: относительный путь input/receipt.txt теперь однозначен. new SplFileInfo создаёт карточку пути, а не открывает содержимое; -> вызывает действие этой карточки. Необязательный suffix удаляется только с конца возвращаемого имени. Файл на диске не переименовывается; обработка многобайтовых имён зависит от locale.

Путь и подпись документаСамостоятельный пример
<?php
declare(strict_types=1);

chdir(__DIR__);
$info = new SplFileInfo('input/receipt.txt');
echo $info->getBasename() . "\n";
echo $info->getBasename('.txt') . "\n";
Ожидаемый результат
receipt.txt
receipt

Полученное значение можно использовать как подпись или известный локальный путь.

Второе имя заканчивается на .bak. Удалять .csv из середины имени getBasename не будет: suffix должен совпасть с концом.

Пограничный случай имени или чтение по путиСамостоятельный пример
<?php
declare(strict_types=1);

foreach (['input/report.csv', 'input/report.csv.bak'] as $path) {
    $info = new SplFileInfo($path);
    echo $info->getBasename('.csv') . "\n";
}
Ожидаемый результат
report
report.csv.bak

Имя и расположение не смешиваются с содержимым документа.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileInfo::getBasename

(PHP 5 >= 5.2.2, PHP 7, PHP 8) SplFileInfo::getBasename — Gets the base name of the file

Description

public function SplFileInfo::getBasename(string $suffix = ""): string

This method returns the base name of the file, directory, or link without path info.

Caution

SplFileInfo::getBasename() is locale aware, so for it to see the correct basename with multibyte character paths, the matching locale must be set using the setlocale() function.

Parameters

suffix

Optional suffix to omit from the base name returned.

Return Values

Returns the base name without path information.

See Also

SplFileInfo::getFilename() - Gets the filename

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileInfo::getCTimeОтличить изменение метаданных от изменения текста.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileInfo::getCTime(): int|false

На Unix ctime — время изменения inode (сведений о файле), а не дата создания. На Windows filectime соответствует времени создания. Поэтому переносимый код не должен называть ctime датой создания без указания платформы.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileInfo::getCTime(): int|false
РезультатUnix timestamp int либо false; RuntimeException при ошибке.
Ошибки и особые значенияRuntimeException или false при ошибке stat. Не использовать ctime как универсальную дату рождения файла.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

В собственной папке создаём новый new-note.txt и запоминаем время перед созданием. Допуск две секунды учитывает грубую точность некоторых файловых систем.

Найти только что подготовленный документСамостоятельный пример
<?php
declare(strict_types=1);

$started = time();
file_put_contents(__DIR__ . '/new-note.txt', "Заказ 42 готов
");
$info = new SplFileInfo(__DIR__ . '/new-note.txt');
$changed = $info->getCTime();
if ($changed === false) { throw new RuntimeException('Нет времени метаданных'); }
if ($changed >= $started - 2) {
    echo "Свежая карточка файла:
";
    echo $info->openFile()->fgets();
}
Ожидаемый результат
Свежая карточка файла:
Заказ 42 готов

Показан документ с недавно созданной/изменённой карточкой. Это не доказательство неизменности его содержимого.

PHP_OS_FAMILY сообщает семейство ОС. Условие ? : выбирает корректную подпись поля; в показанном запуске используется Windows. В Unix первая строка будет «Поле ctime: изменение inode в Unix».

Объяснить поле времени в отчётеСамостоятельный пример
<?php
declare(strict_types=1);

chdir(__DIR__);
$info = new SplFileInfo('input/receipt.txt');
$stamp = $info->getCTime();
if ($stamp === false) { throw new RuntimeException('Нет ctime'); }
$meaning = PHP_OS_FAMILY === 'Windows' ? 'создание файла в Windows' : 'изменение inode в Unix';
echo 'Поле ctime: ' . $meaning . "
";
echo $info->openFile()->fgets();
Ожидаемый результат
Поле ctime: создание файла в Windows
Заказ 42

Один и тот же API требует понятной подписи с учётом платформы.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileInfo::getCTime

(PHP 5 >= 5.1.2, PHP 7, PHP 8) SplFileInfo::getCTime — Gets the inode change time

Description

public function SplFileInfo::getCTime(): int|false

Returns the inode change time for the file. The time returned is a Unix timestamp.

Parameters

This function has no parameters.

Return Values

The last change time, in a Unix timestamp on success, or false on failure.

Errors/Exceptions

Throws RuntimeException on error.

See Also

filectime() - Gets inode change time of file

SplFileInfo::getATime() - Gets last access time of the file

SplFileInfo::getMTime() - Gets the last modified time

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileInfo::getExtensionПолучить расширение для маршрута обработки.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileInfo::getExtension(): string

Расширение — часть после последней точки; при отсутствии расширения возвращается пустая строка. Это имя, а не доказательство типа содержимого.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileInfo::getExtension(): string
РезультатСтрока пути/имени; конструктор создаёт объект.
Ошибки и особые значенияДля этих операций строкового пути файл может отсутствовать. Ошибки фактического открытия обрабатываются отдельно; NUL в пути недопустим.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Файл input/receipt.txt уже приложен. chdir(__DIR__) делает папку программы текущей: относительный путь input/receipt.txt теперь однозначен. new SplFileInfo создаёт карточку пути, а не открывает содержимое; -> вызывает действие этой карточки. Расширение — часть после последней точки; при отсутствии расширения возвращается пустая строка. Это имя, а не доказательство типа содержимого.

Путь и подпись документаСамостоятельный пример
<?php
declare(strict_types=1);

chdir(__DIR__);
$info = new SplFileInfo('input/receipt.txt');
echo 'Формат: ' . $info->getExtension() . "\n";
Ожидаемый результат
Формат: txt

Полученное значение можно использовать как подпись или известный локальный путь.

foreach последовательно берёт три известных имени из массива. Эти файлы не нужны на диске: мы разбираем только строку пути. Условие ? : подставляет понятную подпись для пустого результата.

Пограничный случай имени или чтение по путиСамостоятельный пример
<?php
declare(strict_types=1);

foreach (['orders.csv', 'backup.tar.gz', 'README'] as $path) {
    $info = new SplFileInfo($path);
    $ext = $info->getExtension();
    echo $path . ': ' . ($ext === '' ? 'без расширения' : $ext) . "\n";
}
Ожидаемый результат
orders.csv: csv
backup.tar.gz: gz
README: без расширения

Имя и расположение не смешиваются с содержимым документа.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileInfo::getExtension

(PHP 5 >= 5.3.6, PHP 7, PHP 8) SplFileInfo::getExtension — Gets the file extension

Description

public function SplFileInfo::getExtension(): string

Retrieves the file extension.

Parameters

This function has no parameters.

Return Values

Returns a string containing the file extension, or an empty string if the file has no extension.

Notes

Note:

Another way of getting the extension is to use the pathinfo() function.

<?php $extension = pathinfo($info->getFilename(), PATHINFO_EXTENSION); ?>

See Also

SplFileInfo::getFilename() - Gets the filename

SplFileInfo::getBasename() - Gets the base name of the file

pathinfo() - Returns information about a file path

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileInfo::getFileInfoПолучить подходящий объект для пути или открытого файла.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileInfo::getFileInfo(?string $class = null): SplFileInfo

getFileInfo создаёт карточку того же файла, getPathInfo — родителя. setInfoClass задаёт совместимый подкласс SplFileInfo для этих фабрик; setFileClass — подкласс SplFileObject для openFile. Существующий объект не превращается в другой класс.

ПараметрЧто означает в задаче
classИмя совместимого класса: запись ReportInfo::class получает имя класса, а не создаёт объект. getFileInfo/getPathInfo принимают null для настроенного класса.
Часть контрактаЧто важно
Сигнатураpublic function SplFileInfo::getFileInfo(?string $class = null): SplFileInfo
РезультатgetFileInfo: SplFileInfo; getPathInfo: SplFileInfo|null; openFile: SplFileObject; setters ничего не возвращают.
Ошибки и особые значенияopenFile: RuntimeException при отказе открытия. getPathInfo может вернуть null. Несовместимый или отсутствующий класс приводит к исключению/Error; не принимать имя класса от пользователя.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Файл input/receipt.txt уже приложен. chdir(__DIR__) делает папку программы текущей: относительный путь input/receipt.txt теперь однозначен. new SplFileInfo создаёт карточку пути, а не открывает содержимое; -> вызывает действие этой карточки. DocumentInfo extends SplFileInfo наследует операции пути и добавляет label. TaggedDocumentInfo наследует уже DocumentInfo и добавляет tag. После setInfoClass(DocumentInfo::class) явный класс фабрики должен быть этим классом или его потомком; передать обратно базовый SplFileInfo нельзя. ::class получает безопасное имя известного класса.

Применить карточку или фабрику к квитанцииСамостоятельный пример
<?php
declare(strict_types=1);

class DocumentInfo extends SplFileInfo {
    public function label(): string { return 'Документ: ' . $this->getFilename(); }
}
chdir(__DIR__);
$info = new SplFileInfo('input/receipt.txt');
$copy = $info->getFileInfo(DocumentInfo::class);
echo $copy->label() . "\n";
echo $copy->openFile()->fgets();
Ожидаемый результат
Документ: receipt.txt
Заказ 42

Полученный объект выполняет полезное действие: показывает подпись или читает квитанцию.

DocumentInfo extends SplFileInfo наследует операции пути и добавляет label. TaggedDocumentInfo наследует уже DocumentInfo и добавляет tag. После setInfoClass(DocumentInfo::class) явный класс фабрики должен быть этим классом или его потомком; передать обратно базовый SplFileInfo нельзя. ::class получает безопасное имя известного класса.

Другой режим или явный класс результатаСамостоятельный пример
<?php
declare(strict_types=1);

class DocumentInfo extends SplFileInfo {
    public function label(): string { return 'Документ: ' . $this->getFilename(); }
}
class TaggedDocumentInfo extends DocumentInfo {
    public function tag(): string { return 'Тег: ' . $this->getFilename(); }
}
chdir(__DIR__);
$info = new SplFileInfo('input/receipt.txt');
$info->setInfoClass(DocumentInfo::class);
$parent = $info->getPathInfo();
if ($parent === null) { throw new RuntimeException('Нет родителя'); }
echo $parent->label() . "\n";
$specific = $info->getFileInfo(TaggedDocumentInfo::class);
echo $specific->tag() . "\n";
Ожидаемый результат
Документ: input
Тег: receipt.txt

Имя класса служит выбором поведения, а результат показан данными документа.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileInfo::getFileInfo

(PHP 5 >= 5.1.2, PHP 7, PHP 8) SplFileInfo::getFileInfo — Gets an SplFileInfo object for the file

Description

public function SplFileInfo::getFileInfo(?string $class = null): SplFileInfo

This method gets an SplFileInfo object for the referenced file.

Parameters

class

Name of an SplFileInfo derived class to use.

Return Values

An SplFileInfo object created for the file.

Changelog

Version Description

8.0.0

class is now nullable.

See Also

SplFileInfo::setInfoClass() - Sets the class used with SplFileInfo::getFileInfo and SplFileInfo::getPathInfo

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileInfo::getFilenameПолучить имя для подписи ссылки.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileInfo::getFilename(): string

Возвращается последняя часть пути вместе с расширением.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileInfo::getFilename(): string
РезультатСтрока пути/имени; конструктор создаёт объект.
Ошибки и особые значенияДля этих операций строкового пути файл может отсутствовать. Ошибки фактического открытия обрабатываются отдельно; NUL в пути недопустим.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Файл input/receipt.txt уже приложен. chdir(__DIR__) делает папку программы текущей: относительный путь input/receipt.txt теперь однозначен. new SplFileInfo создаёт карточку пути, а не открывает содержимое; -> вызывает действие этой карточки. Возвращается последняя часть пути вместе с расширением.

Путь и подпись документаСамостоятельный пример
<?php
declare(strict_types=1);

chdir(__DIR__);
$info = new SplFileInfo('input/receipt.txt');
echo 'Документ: ' . $info->getFilename() . "\n";
Ожидаемый результат
Документ: receipt.txt

Полученное значение можно использовать как подпись или известный локальный путь.

Два документа могут иметь одинаковое имя в разных каталогах. Добавляем getPath к подписи, чтобы человек мог отличить их.

Пограничный случай имени или чтение по путиСамостоятельный пример
<?php
declare(strict_types=1);

foreach (['inbox/report.txt', 'archive/report.txt'] as $path) {
    $info = new SplFileInfo($path);
    echo $info->getFilename() . ' — ' . $info->getPath() . "\n";
}
Ожидаемый результат
report.txt — inbox
report.txt — archive

Имя и расположение не смешиваются с содержимым документа.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileInfo::getFilename

(PHP 5 >= 5.1.2, PHP 7, PHP 8) SplFileInfo::getFilename — Gets the filename

Description

public function SplFileInfo::getFilename(): string

Gets the filename without any path information.

Parameters

This function has no parameters.

Return Values

The filename.

See Also

SplFileInfo::getBasename() - Gets the base name of the file

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileInfo::getGroupПолучить числовой идентификатор группы для отчёта.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileInfo::getGroup(): int|false

Метод возвращает идентификатор, а не имя пользователя/группы. На Unix имена можно получать соответствующими posix-функциями; расширение POSIX и доступность записи проверяются отдельно.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileInfo::getGroup(): int|false
Результатint идентификатор либо false; RuntimeException при ошибке.
Ошибки и особые значенияRuntimeException или false при невозможности stat; ID может отсутствовать в базе имён пользователей.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Файл input/receipt.txt уже приложен. chdir(__DIR__) делает папку программы текущей: относительный путь input/receipt.txt теперь однозначен. new SplFileInfo создаёт карточку пути, а не открывает содержимое; -> вызывает действие этой карточки. Показан запуск Windows. В Unix строка будет содержать числовой ID локального владельца/группы, который зависит от машины.

Метаданные и реальный документСамостоятельный пример
<?php
declare(strict_types=1);

chdir(__DIR__);
$info = new SplFileInfo('input/receipt.txt');
$id = $info->getGroup();
if ($id === false) { throw new RuntimeException('Нет идентификатора группы'); }
if (PHP_OS_FAMILY === 'Windows') { echo "Windows: gid=0 не описывает ACL.
"; }
else { echo 'ID группы: ' . $id . "
"; }
echo $info->openFile()->fgets();
Ожидаемый результат
Windows: gid=0 не описывает ACL.
Заказ 42

Содержимое прочитано отдельной операцией: ID не подменяет проверку успешного чтения.

Файл input/receipt.txt уже приложен. chdir(__DIR__) делает папку программы текущей: относительный путь input/receipt.txt теперь однозначен. new SplFileInfo создаёт карточку пути, а не открывает содержимое; -> вызывает действие этой карточки. Два приложенных файла созданы одним процессом. Сравниваем поле владельца/группы для отчёта и перечисляем конкретные имена.

Сгруппировать локальные документыСамостоятельный пример
<?php
declare(strict_types=1);

chdir(__DIR__);
$info = new SplFileInfo('input/receipt.txt');
$other = new SplFileInfo('input/bytes.txt');
if ($info->getGroup() === $other->getGroup()) {
    echo "Одна группа по полю gid:
";
    echo $info->getFilename() . "
" . $other->getFilename() . "
";
}
echo "Проверка чтения отдельно: " . $info->openFile()->fgets();
Ожидаемый результат
Одна группа по полю gid:
receipt.txt
bytes.txt
Проверка чтения отдельно: Заказ 42

Это группировка метаданных, не схема авторизации; чтение проверено фактическим открытием.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileInfo::getGroup

(PHP 5 >= 5.1.2, PHP 7, PHP 8) SplFileInfo::getGroup — Gets the file group

Description

public function SplFileInfo::getGroup(): int|false

Gets the file group. The group ID is returned in numerical format.

Parameters

This function has no parameters.

Return Values

The group id in numerical format on success, or false on failure.

Errors/Exceptions

Throws RuntimeException on error.

See Also

filegroup() - Gets file group

posix_getgrgid() - Return info about a group by group id

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileInfo::getInodeРаспознать одинаковый файловый объект за разными путями.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileInfo::getInode(): int|false

Inode — идентификатор объекта внутри файловой системы; для глобального сравнения нужен также номер устройства dev из stat. На Windows с PHP 7.4 возвращается идентификатор файла, а не постоянный ноль.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileInfo::getInode(): int|false
Результатint идентификатор либо false; RuntimeException при ошибке.
Ошибки и особые значенияfalse/RuntimeException при ошибке; идентификатор устройства/файла может переполнять представление int на отдельных платформах.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

input/./receipt.txt и input/receipt.txt указывают на один объект. Массив $seen запоминает пару dev:inode; isset проверяет, встречалась ли она.

Два написания пути читаются один разСамостоятельный пример
<?php
declare(strict_types=1);

chdir(__DIR__);
$seen = [];
foreach (['input/receipt.txt', 'input/./receipt.txt'] as $path) {
    $info = new SplFileInfo($path);
    $stat = stat($path);
    $key = $stat['dev'] . ':' . $info->getInode();
    if (isset($seen[$key])) { echo "Повтор того же документа пропущен.
"; continue; }
    $seen[$key] = true;
    echo $info->openFile()->fgets();
}
Ожидаемый результат
Заказ 42
Повтор того же документа пропущен.

Один документ не оказался в отчёте дважды из-за разных строк пути.

Оба файла находятся в одной учебной папке на одном томе, поэтому сравнение inode здесь достаточно для демонстрации.

Разные файлы с разным содержимымСамостоятельный пример
<?php
declare(strict_types=1);

chdir(__DIR__);
$first = new SplFileInfo('input/receipt.txt');
$second = new SplFileInfo('input/bytes.txt');
if ($first->getInode() !== $second->getInode()) {
    echo 'Первый: ' . $first->openFile()->fgets();
    echo 'Второй: ' . $second->openFile()->fgets() . "
";
}
Ожидаемый результат
Первый: Заказ 42
Второй: ABCDEF

Одинаковый размер или похожее имя не были бы доказательством идентичности.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileInfo::getInode

(PHP 5 >= 5.1.2, PHP 7, PHP 8) SplFileInfo::getInode — Gets the inode for the file

Description

public function SplFileInfo::getInode(): int|false

Gets the inode number for the filesystem object.

Parameters

This function has no parameters.

Return Values

Returns the inode number for the filesystem object on success, or false on failure.

Errors/Exceptions

Throws RuntimeException on error.

See Also

fileinode() - Gets file inode

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileInfo::getLinkTargetПрочитать записанную в символической ссылке цель, не смешивая её с каноническим путём.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileInfo::getLinkTarget(): string|false

getLinkTarget возвращает текст цели ссылки: он может быть относительным, например receipt.txt. Это не обязательно абсолютный путь. getRealPath отдельно пытается разрешить всю цепочку до существующего объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileInfo::getLinkTarget(): string|false
РезультатСтрока цели ссылки; в объявленном типе также false. Официальная страница отдельно указывает RuntimeException при ошибке.
Ошибки и особые значенияДля не-ссылки или ошибки следуйте официальному договору string|false и RuntimeException; предварительная isLink-проверка делает намерение явным, но не устраняет гонку файловой системы.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Проверка isLink защищает ветку getLinkTarget. Для обычного приложенного файла программа не вызывает метод, которому нужна ссылка, и продолжает полезное чтение.

Не вызывать link-only метод для обычного файлаСамостоятельный пример
<?php
declare(strict_types=1);

$info = new SplFileInfo(__DIR__ . '/input/receipt.txt');
if (!$info->isLink()) {
    echo "receipt.txt — обычный файл; цель ссылки отсутствует.
";
    echo $info->openFile('rb')->fgets();
} else {
    $target = $info->getLinkTarget();
    echo 'Цель: ' . ($target === false ? 'не прочитана' : $target) . "
";
}
Ожидаемый результат
receipt.txt — обычный файл; цель ссылки отсутствует.
Заказ 42

Читатель видит и тип пути, и содержимое документа, без ложной «цели».

Это настоящий symlink-сценарий для среды с поддержкой: ссылка хранит относительное receipt.txt, а getRealPath даёт абсолютное разрешение. В текущем Windows-стенде он оставлен условным после зафиксированного Permission denied.

Сравнить текст цели и реально разрешённый файлФрагмент или команда
$target = __DIR__ . '/input/receipt.txt';
$link = __DIR__ . '/input/current-receipt.txt';
if (!is_link($link) && !@symlink('receipt.txt', $link)) {
    throw new RuntimeException('Среда не разрешила создать учебную символическую ссылку');
}
$info = new SplFileInfo($link);
if (!$info->isLink()) { throw new RuntimeException('Ожидалась ссылка'); }
$stored = $info->getLinkTarget();
$resolved = $info->getRealPath();
if ($stored === false || $resolved === false) { throw new RuntimeException('Ссылка не разрешена'); }
echo 'В ссылке записано: ' . $stored . "
";
echo 'Разрешённый файл: ' . basename($resolved) . "
";
echo $info->openFile('rb')->fgets();

При поддержке видны три результата: записанная цель, имя разрешённого файла и первая строка его содержимого. При запрете полномочий создание честно прерывается.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileInfo::getLinkTarget

(PHP 5 >= 5.2.2, PHP 7, PHP 8) SplFileInfo::getLinkTarget — Gets the target of a link

Description

public function SplFileInfo::getLinkTarget(): string|false

Gets the target of a filesystem link.

Note:

The target may not be the real path on the filesystem. Use SplFileInfo::getRealPath() to determine the true path on the filesystem.

Parameters

This function has no parameters.

Return Values

Returns the target of the filesystem link on success, or false on failure.

Errors/Exceptions

Throws RuntimeException on error.

See Also

SplFileInfo::isLink() - Tells if the file is a link

SplFileInfo::getRealPath() - Gets absolute path to file

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileInfo::getMTimeПоказать время изменения содержимого и принять решение о документе.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileInfo::getMTime(): int|false

Возвращается Unix timestamp — секунды от начала эпохи. date форматирует число в выбранном часовом поясе. Входной файл специально получает фиксированные учебные времена через touch.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileInfo::getMTime(): int|false
Результатint timestamp либо false при неудаче.
Ошибки и особые значенияfalse или RuntimeException при невозможности получить сведения; точность времени зависит от файловой системы.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Файл input/receipt.txt уже приложен. chdir(__DIR__) делает папку программы текущей: относительный путь input/receipt.txt теперь однозначен. new SplFileInfo создаёт карточку пути, а не открывает содержимое; -> вызывает действие этой карточки. touch(path, mtime, atime) задаёт времена нашей копии; clearstatcache обновляет кэш. date_default_timezone_set выбирает UTC для одинакового вывода.

Показать время в UTCСамостоятельный пример
<?php
declare(strict_types=1);

chdir(__DIR__);
$info = new SplFileInfo('input/receipt.txt');
date_default_timezone_set('UTC');
touch('input/receipt.txt', 1640995200, 1609459200);
clearstatcache(true, 'input/receipt.txt');
echo 'Время изменения содержимого: ' . date('Y-m-d H:i:s', $info->getMTime()) . " UTC
";
echo $info->openFile('rb')->fgets();
Ожидаемый результат
Время изменения содержимого: 2022-01-01 00:00:00 UTC
Заказ 42

Дата относится к именно этой учебной квитанции, а не к текущему времени компьютера.

Контрольная дата 1704067200 — 2024-01-01 UTC. Сравниваем целые timestamps; затем выводим документ, который попал в выборку. Реального удаления или перемещения нет.

Отобрать старый документ к проверкеСамостоятельный пример
<?php
declare(strict_types=1);

chdir(__DIR__);
$info = new SplFileInfo('input/receipt.txt');
touch('input/receipt.txt', 1640995200, 1609459200);
clearstatcache(true, 'input/receipt.txt');
$stamp = $info->getMTime();
if ($stamp === false) { throw new RuntimeException('Нет времени файла'); }
if ($stamp < 1704067200) { echo "Документ до контрольной даты: перенести в архив после проверки.
"; }
echo file_get_contents('input/receipt.txt');
Ожидаемый результат
Документ до контрольной даты: перенести в архив после проверки.
Заказ 42
Кисть — 2 шт.
Итого: 300 руб.

Метаданные помогают найти документ; решение об удалении требует политики хранения и не выполняется в примере.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileInfo::getMTime

(PHP 5 >= 5.1.2, PHP 7, PHP 8) SplFileInfo::getMTime — Gets the last modified time

Description

public function SplFileInfo::getMTime(): int|false

Returns the time when the contents of the file were changed. The time returned is a Unix timestamp.

Parameters

This function has no parameters.

Return Values

Returns the last modified time for the file, in a Unix timestamp on success, or false on failure.

See Also

filemtime() - Gets file modification time

SplFileInfo::getATime() - Gets last access time of the file

SplFileInfo::getCTime() - Gets the inode change time

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileInfo::getOwnerПолучить числовой идентификатор владельца для отчёта.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileInfo::getOwner(): int|false

Метод возвращает идентификатор, а не имя пользователя/группы. На Unix имена можно получать соответствующими posix-функциями; расширение POSIX и доступность записи проверяются отдельно.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileInfo::getOwner(): int|false
Результатint идентификатор либо false; RuntimeException при ошибке.
Ошибки и особые значенияRuntimeException или false при невозможности stat; ID может отсутствовать в базе имён пользователей.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Файл input/receipt.txt уже приложен. chdir(__DIR__) делает папку программы текущей: относительный путь input/receipt.txt теперь однозначен. new SplFileInfo создаёт карточку пути, а не открывает содержимое; -> вызывает действие этой карточки. Показан запуск Windows. В Unix строка будет содержать числовой ID локального владельца/группы, который зависит от машины.

Метаданные и реальный документСамостоятельный пример
<?php
declare(strict_types=1);

chdir(__DIR__);
$info = new SplFileInfo('input/receipt.txt');
$id = $info->getOwner();
if ($id === false) { throw new RuntimeException('Нет идентификатора владельца'); }
if (PHP_OS_FAMILY === 'Windows') { echo "Windows: uid=0 не описывает ACL.
"; }
else { echo 'ID владельца: ' . $id . "
"; }
echo $info->openFile()->fgets();
Ожидаемый результат
Windows: uid=0 не описывает ACL.
Заказ 42

Содержимое прочитано отдельной операцией: ID не подменяет проверку успешного чтения.

Файл input/receipt.txt уже приложен. chdir(__DIR__) делает папку программы текущей: относительный путь input/receipt.txt теперь однозначен. new SplFileInfo создаёт карточку пути, а не открывает содержимое; -> вызывает действие этой карточки. Два приложенных файла созданы одним процессом. Сравниваем поле владельца/группы для отчёта и перечисляем конкретные имена.

Сгруппировать локальные документыСамостоятельный пример
<?php
declare(strict_types=1);

chdir(__DIR__);
$info = new SplFileInfo('input/receipt.txt');
$other = new SplFileInfo('input/bytes.txt');
if ($info->getOwner() === $other->getOwner()) {
    echo "Одна группа по полю uid:
";
    echo $info->getFilename() . "
" . $other->getFilename() . "
";
}
echo "Проверка чтения отдельно: " . $info->openFile()->fgets();
Ожидаемый результат
Одна группа по полю uid:
receipt.txt
bytes.txt
Проверка чтения отдельно: Заказ 42

Это группировка метаданных, не схема авторизации; чтение проверено фактическим открытием.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileInfo::getOwner

(PHP 5 >= 5.1.2, PHP 7, PHP 8) SplFileInfo::getOwner — Gets the owner of the file

Description

public function SplFileInfo::getOwner(): int|false

Gets the file owner. The owner ID is returned in numerical format.

Parameters

This function has no parameters.

Return Values

The owner id in numerical format on success, or false on failure.

Errors/Exceptions

Throws RuntimeException on error.

See Also

posix_getpwuid() - Return info about a user by user id

SplFileInfo::getGroup() - Gets the file group

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileInfo::getPathУзнать каталог без имени файла.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileInfo::getPath(): string

Возвращается часть пути без имени и без завершающего разделителя; она может быть относительной или пустой.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileInfo::getPath(): string
РезультатСтрока пути/имени; конструктор создаёт объект.
Ошибки и особые значенияДля этих операций строкового пути файл может отсутствовать. Ошибки фактического открытия обрабатываются отдельно; NUL в пути недопустим.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Файл input/receipt.txt уже приложен. chdir(__DIR__) делает папку программы текущей: относительный путь input/receipt.txt теперь однозначен. new SplFileInfo создаёт карточку пути, а не открывает содержимое; -> вызывает действие этой карточки. Возвращается часть пути без имени и без завершающего разделителя; она может быть относительной или пустой.

Путь и подпись документаСамостоятельный пример
<?php
declare(strict_types=1);

chdir(__DIR__);
$info = new SplFileInfo('input/receipt.txt');
echo 'Каталог: ' . $info->getPath() . "\n";
Ожидаемый результат
Каталог: input

Полученное значение можно использовать как подпись или известный локальный путь.

Путь без каталога даёт пустую строку getPath. Показываем человеку «текущий каталог» вместо пустой подписи.

Пограничный случай имени или чтение по путиСамостоятельный пример
<?php
declare(strict_types=1);

foreach (['receipt.txt', 'input/receipt.txt'] as $path) {
    $info = new SplFileInfo($path);
    $parent = $info->getPath();
    echo $info->getFilename() . ': ' . ($parent === '' ? 'текущий каталог' : $parent) . "\n";
}
Ожидаемый результат
receipt.txt: текущий каталог
receipt.txt: input

Имя и расположение не смешиваются с содержимым документа.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileInfo::getPath

(PHP 5 >= 5.1.2, PHP 7, PHP 8) SplFileInfo::getPath — Gets the path without filename

Description

public function SplFileInfo::getPath(): string

Returns the path to the file, omitting the filename and any trailing slash.

Parameters

This function has no parameters.

Return Values

Returns the path to the file.

See Also

SplFileInfo::getRealPath() - Gets absolute path to file

SplFileInfo::getFilename() - Gets the filename

SplFileInfo::getPathInfo() - Gets an SplFileInfo object for the path

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileInfo::getPathInfoПолучить подходящий объект для пути или открытого файла.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileInfo::getPathInfo(?string $class = null): ?SplFileInfo

getFileInfo создаёт карточку того же файла, getPathInfo — родителя. setInfoClass задаёт совместимый подкласс SplFileInfo для этих фабрик; setFileClass — подкласс SplFileObject для openFile. Существующий объект не превращается в другой класс.

ПараметрЧто означает в задаче
classИмя совместимого класса: запись ReportInfo::class получает имя класса, а не создаёт объект. getFileInfo/getPathInfo принимают null для настроенного класса.
Часть контрактаЧто важно
Сигнатураpublic function SplFileInfo::getPathInfo(?string $class = null): ?SplFileInfo
РезультатgetFileInfo: SplFileInfo; getPathInfo: SplFileInfo|null; openFile: SplFileObject; setters ничего не возвращают.
Ошибки и особые значенияopenFile: RuntimeException при отказе открытия. getPathInfo может вернуть null. Несовместимый или отсутствующий класс приводит к исключению/Error; не принимать имя класса от пользователя.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Файл input/receipt.txt уже приложен. chdir(__DIR__) делает папку программы текущей: относительный путь input/receipt.txt теперь однозначен. new SplFileInfo создаёт карточку пути, а не открывает содержимое; -> вызывает действие этой карточки. Получаем карточку родительского пути input. Во втором примере имя DocumentInfo::class выбирает подкласс с собственным методом label; подпись у него учебная, объект всё равно описывает каталог.

Применить карточку или фабрику к квитанцииСамостоятельный пример
<?php
declare(strict_types=1);

chdir(__DIR__);
$info = new SplFileInfo('input/receipt.txt');
$parent = $info->getPathInfo();
if ($parent === null) { throw new RuntimeException('Нет родителя'); }
echo 'Родитель: ' . $parent->getFilename() . "\n";
Ожидаемый результат
Родитель: input

Полученный объект выполняет полезное действие: показывает подпись или читает квитанцию.

Получаем карточку родительского пути input. Во втором примере имя DocumentInfo::class выбирает подкласс с собственным методом label; подпись у него учебная, объект всё равно описывает каталог.

Другой режим или явный класс результатаСамостоятельный пример
<?php
declare(strict_types=1);

class DocumentInfo extends SplFileInfo {
    public function label(): string { return 'Документ: ' . $this->getFilename(); }
}
chdir(__DIR__);
$info = new SplFileInfo('input/receipt.txt');
$parent = $info->getPathInfo(DocumentInfo::class);
if ($parent === null) { throw new RuntimeException('Нет родителя'); }
echo $parent->label() . "\n";
Ожидаемый результат
Документ: input

Имя класса служит выбором поведения, а результат показан данными документа.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileInfo::getPathInfo

(PHP 5 >= 5.1.2, PHP 7, PHP 8) SplFileInfo::getPathInfo — Gets an SplFileInfo object for the path

Description

public function SplFileInfo::getPathInfo(?string $class = null): ?SplFileInfo

Gets an SplFileInfo object for the parent of the current file.

Parameters

class

Name of an SplFileInfo derived class to use, or itself if null.

Return Values

Returns an SplFileInfo object for the parent path of the file on success, or null on failure.

Changelog

Version Description

8.0.0

class is now nullable.

See Also

SplFileInfo::setInfoClass() - Sets the class used with SplFileInfo::getFileInfo and SplFileInfo::getPathInfo

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileInfo::getPathnameПередать исходный путь следующей операции.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileInfo::getPathname(): string

Возвращается путь в том виде, который хранит объект, вместе с именем; это не обязательно абсолютный канонический путь.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileInfo::getPathname(): string
РезультатСтрока пути/имени; конструктор создаёт объект.
Ошибки и особые значенияДля этих операций строкового пути файл может отсутствовать. Ошибки фактического открытия обрабатываются отдельно; NUL в пути недопустим.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Файл input/receipt.txt уже приложен. chdir(__DIR__) делает папку программы текущей: относительный путь input/receipt.txt теперь однозначен. new SplFileInfo создаёт карточку пути, а не открывает содержимое; -> вызывает действие этой карточки. Возвращается путь в том виде, который хранит объект, вместе с именем; это не обязательно абсолютный канонический путь.

Путь и подпись документаСамостоятельный пример
<?php
declare(strict_types=1);

chdir(__DIR__);
$info = new SplFileInfo('input/receipt.txt');
echo $info->getPathname() . "\n";
echo file_get_contents($info->getPathname());
Ожидаемый результат
input/receipt.txt
Заказ 42
Кисть — 2 шт.
Итого: 300 руб.

Полученное значение можно использовать как подпись или известный локальный путь.

Файл input/receipt.txt уже приложен. chdir(__DIR__) делает папку программы текущей: относительный путь input/receipt.txt теперь однозначен. new SplFileInfo создаёт карточку пути, а не открывает содержимое; -> вызывает действие этой карточки. (string) явно получает строку пути для конструктора SplFileObject; затем файл действительно читается.

Пограничный случай имени или чтение по путиСамостоятельный пример
<?php
declare(strict_types=1);

chdir(__DIR__);
$info = new SplFileInfo('input/receipt.txt');
$file = new SplFileObject((string) $info->getPathname(), 'rb');
echo $file->fgets();
Ожидаемый результат
Заказ 42

Имя и расположение не смешиваются с содержимым документа.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileInfo::getPathname

(PHP 5 >= 5.1.2, PHP 7, PHP 8) SplFileInfo::getPathname — Gets the path to the file

Description

public function SplFileInfo::getPathname(): string

Returns the path to the file.

Parameters

This function has no parameters.

Return Values

The path to the file.

See Also

SplFileInfo::getRealPath() - Gets absolute path to file

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileInfo::getPermsПрочитать биты режима и проверить запись отдельно.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileInfo::getPerms(): int|false

Метод возвращает битовую маску: в ней есть тип объекта и биты прав. Маска & 0777 оставляет обычные rwx-права; восьмеричная запись начинается с 0.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileInfo::getPerms(): int|false
Результатint маска либо false.
Ошибки и особые значенияfalse или ошибка stat; права могут измениться между проверкой и записью.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Файл input/receipt.txt уже приложен. chdir(__DIR__) делает папку программы текущей: относительный путь input/receipt.txt теперь однозначен. new SplFileInfo создаёт карточку пути, а не открывает содержимое; -> вызывает действие этой карточки. 0200 — бит записи владельца. & выделяет этот бит; результат используется для подписи отчёта.

Проверить наличие бита записи владельцаСамостоятельный пример
<?php
declare(strict_types=1);

chdir(__DIR__);
$info = new SplFileInfo('input/receipt.txt');
$mode = $info->getPerms();
if ($mode === false) { throw new RuntimeException('Нет режима'); }
if (($mode & 0200) !== 0) { echo "В режиме файла установлен бит записи владельца.
"; }
echo $info->openFile()->fgets();
Ожидаемый результат
В режиме файла установлен бит записи владельца.
Заказ 42

Это сообщение о режиме файла, а не разрешение выполнять произвольную запись.

Создаём собственный work.txt. Получаем режим, отдельно проверяем isWritable, но окончательное подтверждение — фактически записанная строка ready.

Подготовить записываемый рабочий документСамостоятельный пример
<?php
declare(strict_types=1);

$path = __DIR__ . '/work.txt';
file_put_contents($path, "draft
");
$info = new SplFileInfo($path);
$mode = $info->getPerms();
if ($mode === false || !$info->isWritable()) { throw new RuntimeException('Рабочий файл недоступен для записи'); }
$file = $info->openFile('ab');
if ($file->fwrite("ready
") !== 6) { throw new RuntimeException('Запись не выполнена'); }
$file->fflush();
echo file_get_contents($path);
Ожидаемый результат
draft
ready

В файле две строки. Проверка прав до открытия не отменяет проверки самой операции.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileInfo::getPerms

(PHP 5 >= 5.1.2, PHP 7, PHP 8) SplFileInfo::getPerms — Gets file permissions

Description

public function SplFileInfo::getPerms(): int|false

Gets the file permissions for the file.

Parameters

This function has no parameters.

Return Values

Returns the file permissions on success, or false on failure.

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileInfo::getRealPathРазрешить относительный путь и проверить существование файла.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileInfo::getRealPath(): string|false

Метод разрешает относительные компоненты и символические ссылки и возвращает абсолютный путь существующего объекта.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileInfo::getRealPath(): string|false
РезультатАбсолютный путь либо false, если файл не существует.
Ошибки и особые значенияfalse при отсутствии файла или невозможности разрешить путь; не передавайте false в следующее чтение.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Файл input/receipt.txt уже приложен. chdir(__DIR__) делает папку программы текущей: относительный путь input/receipt.txt теперь однозначен. new SplFileInfo создаёт карточку пути, а не открывает содержимое; -> вызывает действие этой карточки. Абсолютный путь зависит от вашей папки; basename выводит его стабильное имя, а чтение использует весь найденный путь.

Прочитать документ через разрешённый путьСамостоятельный пример
<?php
declare(strict_types=1);

chdir(__DIR__);
$info = new SplFileInfo('input/receipt.txt');
$real = $info->getRealPath();
if ($real === false) { throw new RuntimeException('Документ отсутствует'); }
echo basename($real) . ":
";
echo file_get_contents($real);
Ожидаемый результат
receipt.txt:
Заказ 42
Кисть — 2 шт.
Итого: 300 руб.

Ваша абсолютная папка не зашита в программу.

missing.txt не приложен специально. === false отличает отсутствие разрешённого пути от строки пути.

Отсутствующий документ не становится пустымСамостоятельный пример
<?php
declare(strict_types=1);

$info = new SplFileInfo(__DIR__ . '/input/missing.txt');
$real = $info->getRealPath();
if ($real === false) { echo "Квитанция ещё не сохранена.\n"; }
else { echo file_get_contents($real); }
Ожидаемый результат
Квитанция ещё не сохранена.

Пользователь получает состояние документа, а не ошибочную пустую квитанцию.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileInfo::getRealPath

(PHP 5 >= 5.2.2, PHP 7, PHP 8) SplFileInfo::getRealPath — Gets absolute path to file

Description

public function SplFileInfo::getRealPath(): string|false

This method expands all symbolic links, resolves relative references and returns the real path to the file.

Parameters

This function has no parameters.

Return Values

Returns the path to the file, or false if the file does not exist.

See Also

SplFileInfo::isLink() - Tells if the file is a link

realpath() - Returns canonicalized absolute pathname

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileInfo::getSizeПроверить объём квитанции перед чтением.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileInfo::getSize(): int|false

Размер возвращается в байтах файловой системы. В UTF-8 многие русские буквы занимают по два байта, поэтому длина текста в буквах и размер файла различаются.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileInfo::getSize(): int|false
Результатint байтов либо false; RuntimeException при отсутствующем файле/ошибке.
Ошибки и особые значенияRuntimeException для отсутствующего файла; false также указан официальным контрактом. Не путать 0-байтовый файл и ошибку.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Файл input/receipt.txt уже приложен. chdir(__DIR__) делает папку программы текущей: относительный путь input/receipt.txt теперь однозначен. new SplFileInfo создаёт карточку пути, а не открывает содержимое; -> вызывает действие этой карточки.

Размер и содержимое квитанцииСамостоятельный пример
<?php
declare(strict_types=1);

chdir(__DIR__);
$info = new SplFileInfo('input/receipt.txt');
echo 'Размер: ' . $info->getSize() . " байт\n";
echo file_get_contents($info->getPathname());
Ожидаемый результат
Размер: 61 байт
Заказ 42
Кисть — 2 шт.
Итого: 300 руб.

В архиве receipt.txt занимает ровно 61 байт UTF-8.

Файл input/receipt.txt уже приложен. chdir(__DIR__) делает папку программы текущей: относительный путь input/receipt.txt теперь однозначен. new SplFileInfo создаёт карточку пути, а не открывает содержимое; -> вызывает действие этой карточки. Задаём лимит 32 байта и сравниваем размер перед чтением. В bytes.txt всего шесть ASCII-байтов.

Отказать слишком большому документу и показать малыйСамостоятельный пример
<?php
declare(strict_types=1);

chdir(__DIR__);
$info = new SplFileInfo('input/receipt.txt');
$limit = 32;
if ($info->getSize() > $limit) { echo "Квитанция не помещается в краткое уведомление (лимит 32 байта).
"; }
$small = new SplFileInfo('input/bytes.txt');
if ($small->getSize() <= $limit) { echo 'Короткий код: ' . file_get_contents($small->getPathname()) . "
"; }
Ожидаемый результат
Квитанция не помещается в краткое уведомление (лимит 32 байта).
Короткий код: ABCDEF

Лимит применяется к конкретному каналу сообщения; полная квитанция остаётся на диске.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileInfo::getSize

(PHP 5 >= 5.1.2, PHP 7, PHP 8) SplFileInfo::getSize — Gets file size

Description

public function SplFileInfo::getSize(): int|false

Returns the filesize in bytes for the file referenced.

Parameters

This function has no parameters.

Return Values

The filesize in bytes on success, or false on failure.

Errors/Exceptions

A RuntimeException will be thrown if the file does not exist or an error occurs.

See Also

filesize() - Gets file size

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileInfo::getTypeОтделить каталог от читаемого документа.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileInfo::getType(): string|false

isDir проверяет каталог, isFile — обычный файл, getType возвращает имя типа. Проверка пути помогает выбрать действие; содержимое открывается отдельно.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileInfo::getType(): string|false
РезультатisDir/isFile: bool. getType: file, link, dir, block, fifo, char, socket, unknown либо false.
Ошибки и особые значенияgetType: RuntimeException при ошибке; булевы методы возвращают false при неподходящем/отсутствующем объекте. false не объясняет причину.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Файл input/receipt.txt уже приложен. chdir(__DIR__) делает папку программы текущей: относительный путь input/receipt.txt теперь однозначен. new SplFileInfo создаёт карточку пути, а не открывает содержимое; -> вызывает действие этой карточки. Каталог input и файл receipt.txt — разные виды объектов.

Выбрать подходящий вид объектаСамостоятельный пример
<?php
declare(strict_types=1);

chdir(__DIR__);
foreach (['input', 'input/receipt.txt'] as $path) {
    $info = new SplFileInfo($path);
    echo $path . ': ' . $info->getType() . "\n";
}
Ожидаемый результат
input: dir
input/receipt.txt: file

Выбор метода соответствует следующему действию с путём.

foreach рассматривает два пути. continue пропускает каталог; только обычный файл открывается как документ.

Не пытаться читать каталог как текстСамостоятельный пример
<?php
declare(strict_types=1);

chdir(__DIR__);
foreach (['input', 'input/receipt.txt'] as $path) {
    $info = new SplFileInfo($path);
    if ($info->isDir()) { echo 'Каталог не читаем как документ: ' . $path . "\n"; continue; }
    if ($info->isFile()) { echo $info->openFile()->fgets(); }
}
Ожидаемый результат
Каталог не читаем как документ: input
Заказ 42

Пользователь получает объяснение пропуска каталога и содержимое подходящего файла.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileInfo::getType

(PHP 5 >= 5.1.2, PHP 7, PHP 8) SplFileInfo::getType — Gets file type

Description

public function SplFileInfo::getType(): string|false

Returns the type of the file referenced.

Parameters

This function has no parameters.

Return Values

A string representing the type of the entry. May be one of file, link, dir, block, fifo, char, socket, or unknown, or false on failure.

Errors/Exceptions

Throws a RuntimeException on error.

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileInfo::isDirОтделить каталог от читаемого документа.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileInfo::isDir(): bool

isDir проверяет каталог, isFile — обычный файл, getType возвращает имя типа. Проверка пути помогает выбрать действие; содержимое открывается отдельно.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileInfo::isDir(): bool
РезультатisDir/isFile: bool. getType: file, link, dir, block, fifo, char, socket, unknown либо false.
Ошибки и особые значенияgetType: RuntimeException при ошибке; булевы методы возвращают false при неподходящем/отсутствующем объекте. false не объясняет причину.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Файл input/receipt.txt уже приложен. chdir(__DIR__) делает папку программы текущей: относительный путь input/receipt.txt теперь однозначен. new SplFileInfo создаёт карточку пути, а не открывает содержимое; -> вызывает действие этой карточки. Каталог input и файл receipt.txt — разные виды объектов.

Выбрать подходящий вид объектаСамостоятельный пример
<?php
declare(strict_types=1);

chdir(__DIR__);
$info = new SplFileInfo('input');
if ($info->isDir()) { echo 'Выбран каталог: ' . $info->getPathname() . "\n"; }
echo (new SplFileInfo('input/receipt.txt'))->openFile()->fgets();
Ожидаемый результат
Выбран каталог: input
Заказ 42

Выбор метода соответствует следующему действию с путём.

foreach рассматривает два пути. continue пропускает каталог; только обычный файл открывается как документ.

Не пытаться читать каталог как текстСамостоятельный пример
<?php
declare(strict_types=1);

chdir(__DIR__);
foreach (['input', 'input/receipt.txt'] as $path) {
    $info = new SplFileInfo($path);
    if ($info->isDir()) { echo 'Каталог не читаем как документ: ' . $path . "\n"; continue; }
    if ($info->isFile()) { echo $info->openFile()->fgets(); }
}
Ожидаемый результат
Каталог не читаем как документ: input
Заказ 42

Пользователь получает объяснение пропуска каталога и содержимое подходящего файла.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileInfo::isDir

(PHP 5 >= 5.1.2, PHP 7, PHP 8) SplFileInfo::isDir — Tells if the file is a directory

Description

public function SplFileInfo::isDir(): bool

This method can be used to determine if the file is a directory.

Parameters

This function has no parameters.

Return Values

Returns true if a directory, false otherwise.

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileInfo::isExecutableПредварительно проверить доступность нужного действия.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileInfo::isExecutable(): bool

Признак исполняемости зависит от ОС и не доказывает безопасность программы. Пример проверяет уже используемый PHP_BINARY и ничего дополнительно не запускает.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileInfo::isExecutable(): bool
Результатtrue при положительной проверке, false иначе.
Ошибки и особые значенияfalse — отрицательная предварительная проверка, а не подробный код причины; действие после true всё равно проверяется.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Файл input/receipt.txt уже приложен. chdir(__DIR__) делает папку программы текущей: относительный путь input/receipt.txt теперь однозначен. new SplFileInfo создаёт карточку пути, а не открывает содержимое; -> вызывает действие этой карточки. Признак исполняемости зависит от ОС и не доказывает безопасность программы. Пример проверяет уже используемый PHP_BINARY и ничего дополнительно не запускает.

Выполнить осмысленное действие после проверкиСамостоятельный пример
<?php
declare(strict_types=1);

$info = new SplFileInfo(PHP_BINARY);
if (!$info->isExecutable()) { throw new RuntimeException('PHP_BINARY не помечен исполняемым'); }
echo "Выбран исполняемый PHP для локальных задач.\n";
echo (new SplFileObject(__DIR__ . '/input/receipt.txt'))->fgets();
Ожидаемый результат
Выбран исполняемый PHP для локальных задач.
Заказ 42

Показан результат работы с конкретным файлом, а не только bool(true).

Второй путь специально не существует. Отрицательная проверка ведёт к понятному сообщению и не запускает ошибочную операцию.

Показать человеку причину отказаСамостоятельный пример
<?php
declare(strict_types=1);

$info = new SplFileInfo(__DIR__ . '/input/missing-tool');
if (!$info->isExecutable()) { echo "Инструмент отсутствует или не помечен исполняемым; запуск отменён.\n"; }
Ожидаемый результат
Инструмент отсутствует или не помечен исполняемым; запуск отменён.

Для диагностики разных причин нужны сведения об окружении и фактическое исключение операции.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileInfo::isExecutable

(PHP 5 >= 5.1.2, PHP 7, PHP 8) SplFileInfo::isExecutable — Tells if the file is executable

Description

public function SplFileInfo::isExecutable(): bool

Checks if the file is executable.

Parameters

This function has no parameters.

Return Values

Returns true if executable, false otherwise.

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileInfo::isFileОтделить каталог от читаемого документа.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileInfo::isFile(): bool

isDir проверяет каталог, isFile — обычный файл, getType возвращает имя типа. Проверка пути помогает выбрать действие; содержимое открывается отдельно.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileInfo::isFile(): bool
РезультатisDir/isFile: bool. getType: file, link, dir, block, fifo, char, socket, unknown либо false.
Ошибки и особые значенияgetType: RuntimeException при ошибке; булевы методы возвращают false при неподходящем/отсутствующем объекте. false не объясняет причину.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Файл input/receipt.txt уже приложен. chdir(__DIR__) делает папку программы текущей: относительный путь input/receipt.txt теперь однозначен. new SplFileInfo создаёт карточку пути, а не открывает содержимое; -> вызывает действие этой карточки. Каталог input и файл receipt.txt — разные виды объектов.

Выбрать подходящий вид объектаСамостоятельный пример
<?php
declare(strict_types=1);

chdir(__DIR__);
$info = new SplFileInfo('input/receipt.txt');
if ($info->isFile()) { echo 'Выбран обычный файл: ' . $info->getPathname() . "\n"; }
echo (new SplFileInfo('input/receipt.txt'))->openFile()->fgets();
Ожидаемый результат
Выбран обычный файл: input/receipt.txt
Заказ 42

Выбор метода соответствует следующему действию с путём.

foreach рассматривает два пути. continue пропускает каталог; только обычный файл открывается как документ.

Не пытаться читать каталог как текстСамостоятельный пример
<?php
declare(strict_types=1);

chdir(__DIR__);
foreach (['input', 'input/receipt.txt'] as $path) {
    $info = new SplFileInfo($path);
    if ($info->isDir()) { echo 'Каталог не читаем как документ: ' . $path . "\n"; continue; }
    if ($info->isFile()) { echo $info->openFile()->fgets(); }
}
Ожидаемый результат
Каталог не читаем как документ: input
Заказ 42

Пользователь получает объяснение пропуска каталога и содержимое подходящего файла.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileInfo::isFile

(PHP 5 >= 5.1.2, PHP 7, PHP 8) SplFileInfo::isFile — Tells if the object references a regular file

Description

public function SplFileInfo::isFile(): bool

Checks if the file referenced by this SplFileInfo object exists and is a regular file.

Parameters

This function has no parameters.

Return Values

Returns true if the file exists and is a regular file (not a link), false otherwise.

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileInfo::isReadableПредварительно проверить доступность нужного действия.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileInfo::isReadable(): bool

Положительная предварительная проверка позволяет предложить чтение; само openFile всё равно может завершиться ошибкой.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileInfo::isReadable(): bool
Результатtrue при положительной проверке, false иначе.
Ошибки и особые значенияfalse — отрицательная предварительная проверка, а не подробный код причины; действие после true всё равно проверяется.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Файл input/receipt.txt уже приложен. chdir(__DIR__) делает папку программы текущей: относительный путь input/receipt.txt теперь однозначен. new SplFileInfo создаёт карточку пути, а не открывает содержимое; -> вызывает действие этой карточки. Положительная предварительная проверка позволяет предложить чтение; само openFile всё равно может завершиться ошибкой.

Выполнить осмысленное действие после проверкиСамостоятельный пример
<?php
declare(strict_types=1);

chdir(__DIR__);
$info = new SplFileInfo('input/receipt.txt');
if ($info->isReadable()) { echo $info->openFile('rb')->fgets(); }
else { echo "Документ недоступен.\n"; }
Ожидаемый результат
Заказ 42

Показан результат работы с конкретным файлом, а не только bool(true).

Второй путь специально не существует. Отрицательная проверка ведёт к понятному сообщению и не запускает ошибочную операцию.

Показать человеку причину отказаСамостоятельный пример
<?php
declare(strict_types=1);

$info = new SplFileInfo(__DIR__ . '/input/missing.txt');
if (!$info->isReadable()) { echo "Документ отсутствует или недоступен для чтения.\n"; }
Ожидаемый результат
Документ отсутствует или недоступен для чтения.

Для диагностики разных причин нужны сведения об окружении и фактическое исключение операции.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileInfo::isReadable

(PHP 5 >= 5.1.2, PHP 7, PHP 8) SplFileInfo::isReadable — Tells if file is readable

Description

public function SplFileInfo::isReadable(): bool

Check if the file is readable.

Parameters

This function has no parameters.

Return Values

Returns true if readable, false otherwise.

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileInfo::isWritableПредварительно проверить доступность нужного действия.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileInfo::isWritable(): bool

Для нового файла проверяется возможность создания в родительском каталоге; isWritable отсутствующего пути не отвечает на этот другой вопрос.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileInfo::isWritable(): bool
Результатtrue при положительной проверке, false иначе.
Ошибки и особые значенияfalse — отрицательная предварительная проверка, а не подробный код причины; действие после true всё равно проверяется.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Файл input/receipt.txt уже приложен. chdir(__DIR__) делает папку программы текущей: относительный путь input/receipt.txt теперь однозначен. new SplFileInfo создаёт карточку пути, а не открывает содержимое; -> вызывает действие этой карточки. Для нового файла проверяется возможность создания в родительском каталоге; isWritable отсутствующего пути не отвечает на этот другой вопрос.

Выполнить осмысленное действие после проверкиСамостоятельный пример
<?php
declare(strict_types=1);

$path = __DIR__ . '/edit.txt';
file_put_contents($path, "Заказ 42\n");
$info = new SplFileInfo($path);
if (!$info->isWritable()) { throw new RuntimeException('Нет доступа к записи'); }
$file = $info->openFile('ab');
$file->fwrite("Подтверждён\n");
$file->fflush();
echo file_get_contents($path);
Ожидаемый результат
Заказ 42
Подтверждён

Показан результат работы с конкретным файлом, а не только bool(true).

Второй путь специально не существует. Отрицательная проверка ведёт к понятному сообщению и не запускает ошибочную операцию.

Показать человеку причину отказаСамостоятельный пример
<?php
declare(strict_types=1);

$info = new SplFileInfo(__DIR__ . '/input/missing.txt');
if (!$info->isWritable()) { echo "Файл ещё не существует: проверяйте создание в родительском каталоге.\n"; }
Ожидаемый результат
Файл ещё не существует: проверяйте создание в родительском каталоге.

Для диагностики разных причин нужны сведения об окружении и фактическое исключение операции.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileInfo::isWritable

(PHP 5 >= 5.1.2, PHP 7, PHP 8) SplFileInfo::isWritable — Tells if the entry is writable

Description

public function SplFileInfo::isWritable(): bool

Checks if the current entry is writable.

Parameters

This function has no parameters.

Return Values

Returns true if writable, false otherwise;

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileInfo::openFileПолучить подходящий объект для пути или открытого файла.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileInfo::openFile(string $mode = 'r', bool $useIncludePath = false, $context = null): SplFileObject

getFileInfo создаёт карточку того же файла, getPathInfo — родителя. setInfoClass задаёт совместимый подкласс SplFileInfo для этих фабрик; setFileClass — подкласс SplFileObject для openFile. Существующий объект не превращается в другой класс.

ПараметрЧто означает в задаче
modeРежим открытия: rb — чтение; wb — создание с немедленной очисткой; xb — создание только нового; c+b — чтение/запись без очистки; a+b — запись всегда в конец. b сохраняет байтовые смещения на Windows.
useIncludePathfalse: использовать данный путь. true: дополнительно искать относительное имя в include_path. Здесь файлы задаются через __DIR__, поиск не нужен.
contextnull — стандартные настройки потока. Для обёртки можно передать ресурс stream_context_create(); допустимые параметры определяет именно обёртка.
Часть контрактаЧто важно
Сигнатураpublic function SplFileInfo::openFile(string $mode = 'r', bool $useIncludePath = false, $context = null): SplFileObject
РезультатgetFileInfo: SplFileInfo; getPathInfo: SplFileInfo|null; openFile: SplFileObject; setters ничего не возвращают.
Ошибки и особые значенияopenFile: RuntimeException при отказе открытия. getPathInfo может вернуть null. Несовместимый или отсутствующий класс приводит к исключению/Error; не принимать имя класса от пользователя.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Файл input/receipt.txt уже приложен. chdir(__DIR__) делает папку программы текущей: относительный путь input/receipt.txt теперь однозначен. new SplFileInfo создаёт карточку пути, а не открывает содержимое; -> вызывает действие этой карточки. openFile возвращает уже открытый SplFileObject. Для нового new.txt x+b разрешает создание только если такого файла ещё нет; затем записываем и читаем его.

Применить карточку или фабрику к квитанцииСамостоятельный пример
<?php
declare(strict_types=1);

chdir(__DIR__);
$info = new SplFileInfo('input/receipt.txt');
$file = $info->openFile('rb');
echo $file->fgets();
Ожидаемый результат
Заказ 42

Полученный объект выполняет полезное действие: показывает подпись или читает квитанцию.

openFile возвращает уже открытый SplFileObject. Для нового new.txt x+b разрешает создание только если такого файла ещё нет; затем записываем и читаем его.

Другой режим или явный класс результатаСамостоятельный пример
<?php
declare(strict_types=1);

$info = new SplFileInfo(__DIR__ . '/new.txt');
$file = $info->openFile('x+b');
$file->fwrite("Заказ 43\n");
$file->rewind();
echo $file->fgets();
Ожидаемый результат
Заказ 43

Имя класса служит выбором поведения, а результат показан данными документа.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileInfo::openFile

(PHP 5 >= 5.1.2, PHP 7, PHP 8) SplFileInfo::openFile — Gets an SplFileObject object for the file

Description

public function SplFileInfo::openFile(string $mode = "r", bool $useIncludePath = false, ?resource $context = null): SplFileObject

Creates an SplFileObject object of the file. This is useful because SplFileObject contains additional methods for manipulating the file whereas SplFileInfo is only useful for gaining information, like whether the file is writable.

Parameters

mode

The mode for opening the file. See the fopen() documentation for descriptions of possible modes. The default is read only.

useIncludePath

When set to true, the filename is also searched for within the include_path

context

Refer to the context section of the manual for a description of contexts.

Return Values

The opened file as an SplFileObject object.

Errors/Exceptions

A RuntimeException if the file cannot be opened (e.g. insufficient access rights).

Changelog

Version Description

8.0.0

context is now nullable.

See Also

SplFileObject

stream_context_create() - Creates a stream context

fopen() - Opens file or URL

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileInfo::setFileClassПолучить подходящий объект для пути или открытого файла.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileInfo::setFileClass(string $class = 'SplFileObject'): void

getFileInfo создаёт карточку того же файла, getPathInfo — родителя. setInfoClass задаёт совместимый подкласс SplFileInfo для этих фабрик; setFileClass — подкласс SplFileObject для openFile. Существующий объект не превращается в другой класс.

ПараметрЧто означает в задаче
classИмя совместимого класса: запись ReportInfo::class получает имя класса, а не создаёт объект. getFileInfo/getPathInfo принимают null для настроенного класса.
Часть контрактаЧто важно
Сигнатураpublic function SplFileInfo::setFileClass(string $class = 'SplFileObject'): void
РезультатgetFileInfo: SplFileInfo; getPathInfo: SplFileInfo|null; openFile: SplFileObject; setters ничего не возвращают.
Ошибки и особые значенияopenFile: RuntimeException при отказе открытия. getPathInfo может вернуть null. Несовместимый или отсутствующий класс приводит к исключению/Error; не принимать имя класса от пользователя.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Файл input/receipt.txt уже приложен. chdir(__DIR__) делает папку программы текущей: относительный путь input/receipt.txt теперь однозначен. new SplFileInfo создаёт карточку пути, а не открывает содержимое; -> вызывает действие этой карточки. ReceiptFile наследует SplFileObject через extends и добавляет heading. $this означает текущий объект. public разрешает вызов метода снаружи, : string указывает тип результата. setFileClass выбирает класс будущих openFile, затем возвращаем стандартный.

Применить карточку или фабрику к квитанцииСамостоятельный пример
<?php
declare(strict_types=1);

class ReceiptFile extends SplFileObject {
    public function heading(): string { $this->rewind(); return trim($this->fgets()); }
}
chdir(__DIR__);
$info = new SplFileInfo('input/receipt.txt');
$info->setFileClass(ReceiptFile::class);
$file = $info->openFile('rb');
echo $file->heading() . "\n";
Ожидаемый результат
Заказ 42

Полученный объект выполняет полезное действие: показывает подпись или читает квитанцию.

ReceiptFile наследует SplFileObject через extends и добавляет heading. $this означает текущий объект. public разрешает вызов метода снаружи, : string указывает тип результата. setFileClass выбирает класс будущих openFile, затем возвращаем стандартный.

Другой режим или явный класс результатаСамостоятельный пример
<?php
declare(strict_types=1);

class ReceiptFile extends SplFileObject {
    public function heading(): string { $this->rewind(); return trim($this->fgets()); }
}
chdir(__DIR__);
$info = new SplFileInfo('input/receipt.txt');
$info->setFileClass(ReceiptFile::class);
echo $info->openFile()->heading() . "\n";
$info->setFileClass(SplFileObject::class);
echo $info->openFile()->fgets();
Ожидаемый результат
Заказ 42
Заказ 42

Имя класса служит выбором поведения, а результат показан данными документа.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileInfo::setFileClass

(PHP 5 >= 5.1.2, PHP 7, PHP 8) SplFileInfo::setFileClass — Sets the class used with SplFileInfo::openFile()

Description

public function SplFileInfo::setFileClass(string $class = SplFileObject::class): void

Use this method to set a custom class which will be used when SplFileInfo::openFile() is called. The class name passed to this method must be SplFileObject or a class derived from SplFileObject.

Parameters

class

The class name to use when SplFileInfo::openFile() is called.

Return Values

No value is returned.

See Also

SplFileInfo::openFile() - Gets an SplFileObject object for the file

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileInfo::setInfoClassПолучить подходящий объект для пути или открытого файла.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileInfo::setInfoClass(string $class = 'SplFileInfo'): void

getFileInfo создаёт карточку того же файла, getPathInfo — родителя. setInfoClass задаёт совместимый подкласс SplFileInfo для этих фабрик; setFileClass — подкласс SplFileObject для openFile. Существующий объект не превращается в другой класс.

ПараметрЧто означает в задаче
classИмя совместимого класса: запись ReportInfo::class получает имя класса, а не создаёт объект. getFileInfo/getPathInfo принимают null для настроенного класса.
Часть контрактаЧто важно
Сигнатураpublic function SplFileInfo::setInfoClass(string $class = 'SplFileInfo'): void
РезультатgetFileInfo: SplFileInfo; getPathInfo: SplFileInfo|null; openFile: SplFileObject; setters ничего не возвращают.
Ошибки и особые значенияopenFile: RuntimeException при отказе открытия. getPathInfo может вернуть null. Несовместимый или отсутствующий класс приводит к исключению/Error; не принимать имя класса от пользователя.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Файл input/receipt.txt уже приложен. chdir(__DIR__) делает папку программы текущей: относительный путь input/receipt.txt теперь однозначен. new SplFileInfo создаёт карточку пути, а не открывает содержимое; -> вызывает действие этой карточки. DocumentInfo extends SplFileInfo наследует операции пути и добавляет label. TaggedDocumentInfo наследует уже DocumentInfo и добавляет tag. После setInfoClass(DocumentInfo::class) явный класс фабрики должен быть этим классом или его потомком; передать обратно базовый SplFileInfo нельзя. ::class получает безопасное имя известного класса.

Применить карточку или фабрику к квитанцииСамостоятельный пример
<?php
declare(strict_types=1);

class DocumentInfo extends SplFileInfo {
    public function label(): string { return 'Документ: ' . $this->getFilename(); }
}
chdir(__DIR__);
$info = new SplFileInfo('input/receipt.txt');
$info->setInfoClass(DocumentInfo::class);
$copy = $info->getFileInfo();
echo $copy->label() . "\n";
echo $copy->openFile()->fgets();
Ожидаемый результат
Документ: receipt.txt
Заказ 42

Полученный объект выполняет полезное действие: показывает подпись или читает квитанцию.

DocumentInfo extends SplFileInfo наследует операции пути и добавляет label. TaggedDocumentInfo наследует уже DocumentInfo и добавляет tag. После setInfoClass(DocumentInfo::class) явный класс фабрики должен быть этим классом или его потомком; передать обратно базовый SplFileInfo нельзя. ::class получает безопасное имя известного класса.

Другой режим или явный класс результатаСамостоятельный пример
<?php
declare(strict_types=1);

class DocumentInfo extends SplFileInfo {
    public function label(): string { return 'Документ: ' . $this->getFilename(); }
}
class TaggedDocumentInfo extends DocumentInfo {
    public function tag(): string { return 'Тег: ' . $this->getFilename(); }
}
chdir(__DIR__);
$info = new SplFileInfo('input/receipt.txt');
$info->setInfoClass(DocumentInfo::class);
$parent = $info->getPathInfo();
if ($parent === null) { throw new RuntimeException('Нет родителя'); }
echo $parent->label() . "\n";
$specific = $info->getFileInfo(TaggedDocumentInfo::class);
echo $specific->tag() . "\n";
Ожидаемый результат
Документ: input
Тег: receipt.txt

Имя класса служит выбором поведения, а результат показан данными документа.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileInfo::setInfoClass

(PHP 5 >= 5.1.2, PHP 7, PHP 8) SplFileInfo::setInfoClass — Sets the class used with SplFileInfo::getFileInfo() and SplFileInfo::getPathInfo()

Description

public function SplFileInfo::setInfoClass(string $class = SplFileInfo::class): void

Use this method to set a custom class which will be used when SplFileInfo::getFileInfo() and SplFileInfo::getPathInfo() are called. The class name passed to this method must be SplFileInfo or a class derived from SplFileInfo.

Parameters

class

The class name to use when SplFileInfo::getFileInfo() and SplFileInfo::getPathInfo() are called.

Return Values

No value is returned.

See Also

SplFileInfo::getFileInfo() - Gets an SplFileInfo object for the file

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileInfo::__toStringИспользовать карточку файла как строку пути.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileInfo::__toString(): string

Приведение SplFileInfo к строке даёт путь. Это отличается от SplFileObject, у которого строковое представление — текущая строка содержимого.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileInfo::__toString(): string
РезультатСтрока пути/имени; конструктор создаёт объект.
Ошибки и особые значенияДля этих операций строкового пути файл может отсутствовать. Ошибки фактического открытия обрабатываются отдельно; NUL в пути недопустим.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Файл input/receipt.txt уже приложен. chdir(__DIR__) делает папку программы текущей: относительный путь input/receipt.txt теперь однозначен. new SplFileInfo создаёт карточку пути, а не открывает содержимое; -> вызывает действие этой карточки. Приведение SplFileInfo к строке даёт путь. Это отличается от SplFileObject, у которого строковое представление — текущая строка содержимого.

Путь и подпись документаСамостоятельный пример
<?php
declare(strict_types=1);

chdir(__DIR__);
$info = new SplFileInfo('input/receipt.txt');
echo 'Путь: ' . $info . "\n";
Ожидаемый результат
Путь: input/receipt.txt

Полученное значение можно использовать как подпись или известный локальный путь.

Файл input/receipt.txt уже приложен. chdir(__DIR__) делает папку программы текущей: относительный путь input/receipt.txt теперь однозначен. new SplFileInfo создаёт карточку пути, а не открывает содержимое; -> вызывает действие этой карточки. (string) явно получает строку пути для конструктора SplFileObject; затем файл действительно читается.

Пограничный случай имени или чтение по путиСамостоятельный пример
<?php
declare(strict_types=1);

chdir(__DIR__);
$info = new SplFileInfo('input/receipt.txt');
$file = new SplFileObject((string) $info, 'rb');
echo $file->fgets();
Ожидаемый результат
Заказ 42

Имя и расположение не смешиваются с содержимым документа.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileInfo::__toString

(PHP 5 >= 5.1.2, PHP 7, PHP 8) SplFileInfo::__toString — Returns the path to the file as a string

Description

public function SplFileInfo::__toString(): string

This method will return the file name of the referenced file.

Parameters

This function has no parameters.

Return Values

Returns the path to the file.

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileObject::__constructПрочитать строку настоящего текстового файла.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileObject::__construct(string $filename, string $mode = 'r', bool $useIncludePath = false, $context = null)

SplFileObject открывает файл и сохраняет позицию чтения. Каждый следующий вызов fgets/getCurrentLine читает следующую строку. getCurrentLine — точный псевдоним fgets; current работает с текущим элементом итератора.

ПараметрЧто означает в задаче
filenameПуть к файлу. В архиве это input/receipt.txt рядом с example.php; __DIR__ привязывает путь к папке программы.
modeРежим открытия: rb — чтение; wb — создание с немедленной очисткой; xb — создание только нового; c+b — чтение/запись без очистки; a+b — запись всегда в конец. b сохраняет байтовые смещения на Windows.
useIncludePathfalse: использовать данный путь. true: дополнительно искать относительное имя в include_path. Здесь файлы задаются через __DIR__, поиск не нужен.
contextnull — стандартные настройки потока. Для обёртки можно передать ресурс stream_context_create(); допустимые параметры определяет именно обёртка.
Часть контрактаЧто важно
Сигнатураpublic function SplFileObject::__construct(string $filename, string $mode = 'r', bool $useIncludePath = false, $context = null)
РезультатКонструктор создаёт объект. Чтение возвращает строку с переводом строки; при DROP_NEW_LINE перевод убирается.
Ошибки и особые значенияНевозможность открыть/прочитать файл: RuntimeException. Конструктор для каталога: LogicException. getCurrentLine повторяет контракт fgets.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

В input/receipt.txt три строки: «Заказ 42», «Кисть — 2 шт.», «Итого: 300 руб.». new создаёт объект открытого файла; $file хранит его, а -> вызывает его метод. __DIR__ означает папку example.php. echo выводит полученную строку вместе с её переводом строки.

Открыть файл и прочитать первую строкуСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/receipt.txt', 'rb');
echo $file->fgets();
Ожидаемый результат
Заказ 42

После вызова указатель находится после первой строки. Остальные данные остались в файле.

Теперь тот же объект читается дважды. Затем открывается заведомо отсутствующий input/missing.txt. try выполняет действие, catch ловит RuntimeException и выводит сообщение для человека; $error содержит техническую ошибку.

Показать две строки, затем понятную ошибку отсутствующего файлаСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/receipt.txt', 'rb');
echo $file->fgets();
echo $file->fgets();
try {
    $missing = new SplFileObject(__DIR__ . '/input/missing.txt', 'rb');
} catch (RuntimeException $error) {
    echo "Уведомление ещё не создано.
";
}
Ожидаемый результат
Заказ 42
Кисть — 2 шт.
Уведомление ещё не создано.

Вторая строка не повторяет первую: объект помнит позицию. Ошибка другого файла не скрыта под видом пустого уведомления.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileObject::__construct

(PHP 5 >= 5.1.0, PHP 7, PHP 8) SplFileObject::__construct — Construct a new file object

Description

public function SplFileObject::__construct(    string $filename,    string $mode = "r",    bool $useIncludePath = false,    ?resource $context = null)

Construct a new file object.

Parameters

filename

The file to read.

TipA URL can be used as a filename with this function if the fopen wrappers have been enabled. See fopen() for more details on how to specify the filename. See the Supported Protocols and Wrappers for links to information about what abilities the various wrappers have, notes on their usage, and information on any predefined variables they may provide.

mode

The mode in which to open the file. See fopen() for a list of allowed modes.

useIncludePath

Whether to search in the include_path for filename.

context

A valid context resource created with stream_context_create().

Errors/Exceptions

Throws a RuntimeException if the filename cannot be opened.

Throws a LogicException if the filename is a directory.

See Also

SplFileInfo::openFile() - Gets an SplFileObject object for the file

fopen() - Opens file or URL

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileObject::currentПолучить текущую строку без ручного перехода к следующей.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileObject::current(): array|string|false

current читает значение текущего элемента итератора; повторный current возвращает тот же элемент. next перемещает итератор, rewind начинает его заново.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileObject::current(): array|string|false
РезультатСтрока; при READ_CSV — массив полей; false при достигнутом конце.
Ошибки и особые значенияfalse означает конец. Тип результата зависит от READ_CSV; нельзя обращаться к строке как к массиву полей без этого режима.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

В input/receipt.txt три строки: «Заказ 42», «Кисть — 2 шт.», «Итого: 300 руб.». new создаёт объект открытого файла; $file хранит его, а -> вызывает его метод. __DIR__ означает папку example.php. echo выводит полученную строку вместе с её переводом строки.

Текущая строка и повторное чтениеСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/receipt.txt', 'rb');
echo $file->current();
echo $file->current();
Ожидаемый результат
Заказ 42
Заказ 42

Два current не переводят итератор к товару. Это полезно, когда одну строку проверяют и затем отображают.

stock.csv содержит заголовок и строку "Кисть; широкая";2. setCsvControl задаёт ;, кавычку и пустой escape; READ_CSV включает массив полей. seek(1) выбирает вторую запись этого простого файла. [0] и [1] выбирают её поля.

Товар из выбранной CSV-записиСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/stock.csv');
$file->setCsvControl(';', '"', '');
$file->setFlags(SplFileObject::READ_CSV);
$file->seek(1);
$row = $file->current();
echo $row[0] . ': ' . $row[1] . " шт.\n";
Ожидаемый результат
Кисть; широкая: 2 шт.

Точка с запятой внутри кавычек осталась частью названия, а не создала лишнюю колонку.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileObject::current

(PHP 5 >= 5.1.0, PHP 7, PHP 8) SplFileObject::current — Retrieve current line of file

Description

public function SplFileObject::current(): string|array|false

Retrieves the current line of the file.

Parameters

This function has no parameters.

Return Values

Retrieves the current line of the file. If the SplFileObject::READ_CSV flag is set, this method returns an array containing the current line parsed as CSV data. If the end of the file is reached, false is returned.

See Also

SplFileObject::key() - Get line number

SplFileObject::seek() - Seek to specified line

SplFileObject::next() - Read next line

SplFileObject::rewind() - Rewind the file to the first line

SplFileObject::valid() - Not at EOF

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileObject::eofПрочитать содержимое до конца, сохранив строку «0».

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileObject::eof(): bool

eof отвечает, достигнут ли конец потока; valid отвечает, можно ли продолжить итерацию. Значение флага не является данными файла. Конец нередко становится известен только после попытки чтения.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileObject::eof(): bool
Результатeof: true при конце; valid: true пока итератор действителен.
Ошибки и особые значенияБулев результат не объясняет ошибку чтения. Исключение чтения нельзя считать обычным завершением файла.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

В input/receipt.txt три строки: «Заказ 42», «Кисть — 2 шт.», «Итого: 300 руб.». new создаёт объект открытого файла; $file хранит его, а -> вызывает его метод. __DIR__ означает папку example.php. echo выводит полученную строку вместе с её переводом строки. while повторяет тело, пока условие истинно; ! означает отрицание. break завершает цикл.

Вывести квитанцию до концаСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/receipt.txt', 'rb');
while (!$file->eof()) {
    $line = $file->fgets();
    if ($line === false) { break; }
    echo $line;
}
Ожидаемый результат
Заказ 42
Кисть — 2 шт.
Итого: 300 руб.

Вывод совпадает с содержимым input/receipt.txt, а не только сообщает, что конец найден.

Оператор === сравнивает и значение, и тип; || означает «или». Пропускаем только пустую строку либо false. DROP_NEW_LINE убирает завершающий перевод строки.

Пустые строки и нулевое значениеСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/lines.txt', 'rb');
$file->setFlags(SplFileObject::DROP_NEW_LINE);
while (!$file->eof()) {
    $line = $file->fgets();
    if ($line === false || $line === '') { continue; }
    echo "Значение: " . $line . "\n";
}
Ожидаемый результат
Значение: first
Значение: 0
Значение: last

Ноль выведен, пустая строка пропущена. Это правило импорта, а не автоматическая проверка корректности данных.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileObject::eof

(PHP 5 >= 5.1.0, PHP 7, PHP 8) SplFileObject::eof — Reached end of file

Description

public function SplFileObject::eof(): bool

Determine whether the end of file has been reached

Parameters

This function has no parameters.

Return Values

Returns true if file is at EOF, false otherwise.

See Also

SplFileObject::valid() - Not at EOF

feof() - Tests for end-of-file on a file pointer

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileObject::fflushПередать записанные данные из буфера потока файловой системе.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileObject::fflush(): bool

После fflush другой открывший файл читатель может получить переданные данные. Сброс буфера не является гарантией физического сохранения на диске при аварии питания.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileObject::fflush(): bool
Результатtrue при успехе, false при неудаче.
Ошибки и особые значенияfalse означает, что сброс не удался; успех не обещает устойчивость к отключению питания.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

writer и reader — два объекта для одного status.txt. Сначала записываем строку и проверяем fflush, затем открываем отдельного читателя.

Прочитать запись другим объектомСамостоятельный пример
<?php
declare(strict_types=1);

$writer = new SplFileObject(__DIR__ . '/status.txt', 'wb');
$writer->fwrite("Заказ 42 готов
");
if (!$writer->fflush()) { throw new RuntimeException('Не удалось сбросить буфер'); }
$reader = new SplFileObject(__DIR__ . '/status.txt', 'rb');
echo $reader->fgets();
Ожидаемый результат
Заказ 42 готов

Читатель получил содержимое, а не только значение true от сброса.

Запись и чтение пользуются одинаковыми правилами CSV. Второй объект моделирует следующую стадию обработки уже сброшенного файла.

Сбросить CSV перед чтением другой программойСамостоятельный пример
<?php
declare(strict_types=1);

$writer = new SplFileObject(__DIR__ . '/ready.csv', 'wb');
$writer->fputcsv(['brush', 2], ';', '"', '');
if (!$writer->fflush()) { throw new RuntimeException('CSV не передан потоку'); }
$reader = new SplFileObject(__DIR__ . '/ready.csv', 'rb');
$row = $reader->fgetcsv(';', '"', '');
echo 'К отгрузке: ' . $row[0] . ', ' . $row[1] . " шт.
";
Ожидаемый результат
К отгрузке: brush, 2 шт.

Содержимое ready.csv: brush;2 и перевод строки.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileObject::fflush

(PHP 5 >= 5.1.0, PHP 7, PHP 8) SplFileObject::fflush — Flushes the output to the file

Description

public function SplFileObject::fflush(): bool

Forces a write of all buffered output to the file.

Parameters

This function has no parameters.

Return Values

Returns true on success or false on failure.

See Also

SplFileObject::fwrite() - Write to file

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileObject::fgetcПрочитать один байт и не потерять символ «0».

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileObject::fgetc(): string|false

Метод получает следующий байт. Для ASCII один байт совпадает с символом; буквы UTF-8 могут занимать несколько байтов.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileObject::fgetc(): string|false
РезультатСтрока длиной один байт либо false в конце. Проверять через === false.
Ошибки и особые значенияfalse на EOF. Значение "0" не является ошибкой.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

input/code.txt содержит A042 без перевода строки. Присваивание внутри условия сохраняет байт; !== false отличает строку "0" от конца.

Прочитать код заказа по байтамСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/code.txt', 'rb');
while (($byte = $file->fgetc()) !== false) { echo $byte; }
echo "\n";
Ожидаемый результат
A042

Получен весь код A042, включая ноль.

input/letter.txt содержит единственную букву Я в UTF-8 — два байта. Точка соединяет две считанные строки байтов перед выводом.

Собрать два байта кириллической буквыСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/letter.txt', 'rb');
$first = $file->fgetc();
$second = $file->fgetc();
echo 'Буква: ' . $first . $second . "\n";
Ожидаемый результат
Буква: Я

Два вызова прочитали одну букву. Для неизвестного текста лучше читать строки и использовать mbstring.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileObject::fgetc

(PHP 5 >= 5.1.0, PHP 7, PHP 8) SplFileObject::fgetc — Gets character from file

Description

public function SplFileObject::fgetc(): string|false

Gets a character from the file.

Parameters

This function has no parameters.

Return Values

Returns a string containing a single character read from the file or false on EOF.

WarningThis function may return Boolean false, but may also return a non-Boolean value which evaluates to false. Please read the section on Booleans for more information. Use the === operator for testing the return value of this function.

See Also

SplFileObject::fgets() - Gets line from file

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileObject::fgetcsvПрочитать поля CSV, сохранив кавычки, разделитель и ноль.

PHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.4.0) · SPL

public function SplFileObject::fgetcsv(string $separator = ',', string $enclosure = '"', string $escape = '\\'): array|false

Один вызов читает одну логическую CSV-запись. Она может занимать несколько физических строк, если перенос находится внутри кавычек. Поэтому explode не заменяет CSV-парсер.

ПараметрЧто означает в задаче
separatorРазделитель полей CSV: один байт, например ";" или ",". Строка из двух символов и многобайтовая буква не подходят.
enclosureОдин байт кавычки, обычно двойная кавычка. Кавычка внутри поля записывается дважды.
escapeВ новых примерах явно "": отключить собственный механизм обратной косой черты. Это не отключает удвоение enclosure внутри поля.
Часть контрактаЧто важно
Сигнатураpublic function SplFileObject::fgetcsv(string $separator = ',', string $enclosure = '"', string $escape = '\\'): array|false
РезультатМассив строковых полей, [null] для пустой строки без режима пропуска, false при ошибке.
Ошибки и особые значенияValueError при неверной длине separator/enclosure/escape. false при ошибке чтения. Пустую запись нельзя путать с ошибкой.
ВерсииPHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.4.0)

В stock.csv приложены заголовок name;qty, товар "Кисть; широкая";2, пустая строка и товар "Лак ""Матовый""";0. Разделитель — ;. Кавычки защищают разделитель внутри поля; двойная кавычка внутри названия удваивается. Все файлы сохранены в UTF-8. Первый вызов читает заголовок, второй сохраняет товар в $row. Индексы [0] и [1] выбирают название и количество.

Прочитать одну товарную записьСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/stock.csv', 'rb');
$file->fgetcsv(';', '"', '');
$row = $file->fgetcsv(';', '"', '');
echo $row[0] . ': ' . $row[1] . " шт.
";
Ожидаемый результат
Кисть; широкая: 2 шт.

В названии сохранилась точка с запятой, а количество осталось отдельным полем.

В stock.csv приложены заголовок name;qty, товар "Кисть; широкая";2, пустая строка и товар "Лак ""Матовый""";0. Разделитель — ;. Кавычки защищают разделитель внутри поля; двойная кавычка внутри названия удваивается. Все файлы сохранены в UTF-8. while повторяет чтение; === [null] сравнивает весь массив с единственным null. continue переходит к следующей записи; count проверяет структуру.

Импортировать строки и явно пропустить пустуюСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/stock.csv', 'rb');
$file->fgetcsv(';', '"', '');
while (!$file->eof()) {
    $row = $file->fgetcsv(';', '"', '');
    if ($row === false) { throw new RuntimeException('Ошибка CSV'); }
    if ($row === [null]) { continue; }
    if (count($row) !== 2) { throw new RuntimeException('Нужны две колонки'); }
    echo $row[0] . ': ' . $row[1] . " шт.
";
}
Ожидаемый результат
Кисть; широкая: 2 шт.
Лак "Матовый": 0 шт.

Нулевое количество не потерялось. Проверка числа полей ещё не доказывает, что второе поле — допустимое количество: полная проверка есть в проекте импорта.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileObject::fgetcsv

(PHP 5 >= 5.1.0, PHP 7, PHP 8) SplFileObject::fgetcsv — Gets line from file and parse as CSV fields

Description

public function SplFileObject::fgetcsv(string $separator = ",", string $enclosure = "\"", string $escape = "\\"): array|false

Gets a line from the file which is in CSV format and returns an array containing the fields read.

Note:

The locale settings are taken into account by this function. For example, data encoded in certain one-byte encodings may be parsed incorrectly if LC_CTYPE is en_US.UTF-8.

Parameters

separator

The field delimiter (one single-byte character only). By default , or the value set by a prior call to SplFileObject::setCsvControl().

enclosure

The field enclosure character (one single-byte character only). By default " or the value set by a prior call to SplFileObject::setCsvControl().

escape

The escape character (at most one single-byte character). By default \ or the value set by a prior call to SplFileObject::setCsvControl(). An empty string ("") disables the proprietary escape mechanism.

Warning

In the input stream, the enclosure character can always be escaped by doubling it inside a quoted string, resulting in a single enclosure character in the parsed result. The escape character works differently: If a sequence of escape and enclosure characters appear in the input, both characters will be present in the parsed result. So for the default parameters, a CSV line like "a""b","c\"d" will have the fields parsed as a"b and c\"d, respectively.

Warning

As of PHP 8.4.0, depending on the default value of escape is deprecated. It needs to be provided explicitly either positionally or by the use of Named Arguments, or by a call to SplFileObject::setCsvControl().

Warning When escape is set to anything other than an empty string ("") it can result in CSV that is not compliant with » RFC 4180 or unable to survive a roundtrip through the PHP CSV functions. The default for escape is "\\" so it is recommended to set it to the empty string explicitly. The default value will change in a future version of PHP, no earlier than PHP 9.0.

Return Values

Returns an indexed array containing the fields read, or false on error.

Note:

A blank line in a CSV file will be returned as an array comprising a single null field unless using SplFileObject::SKIP_EMPTY | SplFileObject::DROP_NEW_LINE, in which case empty lines are skipped.

Errors/Exceptions

Throws a ValueError if separator or enclosure is not one byte long.

Throws a ValueError if escape is not one byte long or the empty string.

Changelog

Version Description

8.4.0

Relying on the default value of escape is now deprecated.

7.4.0

The escape parameter now also accepts an empty string to disable the proprietary escape mechanism.

See Also

SplFileObject::fputcsv() - Write a field array as a CSV line

SplFileObject::setCsvControl() - Set the delimiter, enclosure and escape character for CSV

SplFileObject::getCsvControl() - Get the delimiter, enclosure and escape character for CSV

SplFileObject::setFlags() - Sets flags for the SplFileObject

SplFileObject::READ_CSV

SplFileObject::current() - Retrieve current line of file

fputcsv() - Format line as CSV and write to file pointer

fgetcsv() - Gets line from file pointer and parse for CSV fields

str_getcsv() - Parse a CSV string into an array

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileObject::fgetsПрочитать строку настоящего текстового файла.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileObject::fgets(): string

SplFileObject открывает файл и сохраняет позицию чтения. Каждый следующий вызов fgets/getCurrentLine читает следующую строку. getCurrentLine — точный псевдоним fgets; current работает с текущим элементом итератора.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileObject::fgets(): string
РезультатКонструктор создаёт объект. Чтение возвращает строку с переводом строки; при DROP_NEW_LINE перевод убирается.
Ошибки и особые значенияНевозможность открыть/прочитать файл: RuntimeException. Конструктор для каталога: LogicException. getCurrentLine повторяет контракт fgets.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

В input/receipt.txt три строки: «Заказ 42», «Кисть — 2 шт.», «Итого: 300 руб.». new создаёт объект открытого файла; $file хранит его, а -> вызывает его метод. __DIR__ означает папку example.php. echo выводит полученную строку вместе с её переводом строки.

Открыть файл и прочитать первую строкуСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/receipt.txt', 'rb');
echo $file->fgets();
Ожидаемый результат
Заказ 42

После вызова указатель находится после первой строки. Остальные данные остались в файле.

Теперь тот же объект читается дважды. Затем открывается заведомо отсутствующий input/missing.txt. try выполняет действие, catch ловит RuntimeException и выводит сообщение для человека; $error содержит техническую ошибку.

Показать две строки, затем понятную ошибку отсутствующего файлаСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/receipt.txt', 'rb');
echo $file->fgets();
echo $file->fgets();
try {
    $missing = new SplFileObject(__DIR__ . '/input/missing.txt', 'rb');
} catch (RuntimeException $error) {
    echo "Уведомление ещё не создано.
";
}
Ожидаемый результат
Заказ 42
Кисть — 2 шт.
Уведомление ещё не создано.

Вторая строка не повторяет первую: объект помнит позицию. Ошибка другого файла не скрыта под видом пустого уведомления.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileObject::fgets

(PHP 5 >= 5.1.0, PHP 7, PHP 8) SplFileObject::fgets — Gets line from file

Description

public function SplFileObject::fgets(): string

Gets a line from the file.

Parameters

This function has no parameters.

Return Values

Returns a string containing the next line from the file.

Errors/Exceptions

Throws a RuntimeException if the file cannot be read.

See Also

fgets() - Gets line from file pointer

SplFileObject::fgetss() - Gets line from file and strip HTML tags

SplFileObject::fgetc() - Gets character from file

SplFileObject::current() - Retrieve current line of file

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileObject::fgetssПрочитать старый код и выбрать современную обработку HTML.

Историческая официальная страница; метода нет в PHP 8.5.11 · SPL

public function SplFileObject::fgetss(string $allowable_tags = ?): string

Исторический fgetss читал строку, пытаясь удалить PHP/HTML-теги, и сохранял состояние парсера между вызовами. Он объявлен устаревшим в 7.3 и удалён в 8.0. Ни один следующий пример его не вызывает.

ПараметрЧто означает в задаче
allowable_tagsИсторический список разрешённых тегов. fgetss удалён в PHP 8.0; этот параметр не превращал его в HTML-санитайзер.
Часть контрактаЧто важно
Сигнатураpublic function SplFileObject::fgetss(string $allowable_tags = ?): string
РезультатИсторически строка без удаляемых тегов; описание также указывает false при ошибке. В PHP 8 метода нет.
Ошибки и особые значенияВызов fgetss в PHP 8 вызывает Error «undefined method». Современные примеры исполняются отдельно от исторической сигнатуры.
ВерсииИсторическая официальная страница; метода нет в PHP 8.5.11

notice.html содержит Заказ 42 готов. htmlspecialchars превращает угловые скобки в HTML-сущности, чтобы браузер показал теги текстом. Это современная задача отображения, а не эмуляция fgetss.

Показать исходную разметку как безопасный текстСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/notice.html', 'rb');
$text = $file->fgets();
echo htmlspecialchars($text, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
Ожидаемый результат
&lt;b&gt;Заказ 42&lt;/b&gt; готов.

В HTML-странице пользователь увидит буквальное «Заказ 42 готов.», без выполнения разметки.

Второй вариант читает весь наш короткий фрагмент до обработки. strip_tags удаляет разметку только для подготовки обычного текста из заранее заданного учебного входа.

Получить простой текст из собственного короткого фрагментаСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/notice.html', 'rb');
$html = $file->fread(1024);
if ($html === false) { throw new RuntimeException('Нет текста'); }
echo strip_tags($html);
Ожидаемый результат
Заказ 42 готов.

Результат — текстовое уведомление. Для произвольного большого HTML нужен подходящий HTML-парсер и отдельная политика допустимых элементов.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileObject::fgetss

(PHP 5 >= 5.1.0, PHP 7) SplFileObject::fgetss — Gets line from file and strip HTML tags

WarningThis function has been DEPRECATED as of PHP 7.3.0, and REMOVED as of PHP 8.0.0. Relying on this function is highly discouraged.

Description

public function SplFileObject::fgetss(string $allowable_tags = ?): string

Identical to SplFileObject::fgets(), except that SplFileObject::fgetss() attempts to strip any HTML and PHP tags from the text it reads. The function retains the parsing state from call to call, and as such is not equivalent to calling strip_tags() on the return value of SplFileObject::fgets().

Parameters

allowable_tags

Optional parameter to specify tags which should not be stripped.

Return Values

Returns a string containing the next line of the file with HTML and PHP code stripped, or false on error.

See Also

fgetss() - Gets line from file pointer and strip HTML tags

SplFileObject::fgets() - Gets line from file

SplFileObject::fgetc() - Gets character from file

SplFileObject::current() - Retrieve current line of file

The string.strip_tags filter

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileObject::flockСогласовать запись журнала между работающими процессами.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileObject::flock(int $operation, &$wouldBlock = null): bool

Блокировка — договор между участниками, открывающими один файл и использующими flock. LOCK_EX защищает изменение, LOCK_SH — совместное чтение, LOCK_UN снимает блокировку. LOCK_NB позволяет сразу получить отказ вместо ожидания.

ПараметрЧто означает в задаче
operationLOCK_SH — совместное чтение; LOCK_EX — исключительная запись; LOCK_UN — снять блокировку. | LOCK_NB запрещает ожидание занятого файла.
wouldBlockПеременная, передаваемая по ссылке: при неудаче из-за занятой блокировки получает 1. Сам результат flock всё равно нужно проверить.
Часть контрактаЧто важно
Сигнатураpublic function SplFileObject::flock(int $operation, &$wouldBlock = null): bool
Результатtrue при успехе, false при отказе; wouldBlock получает 1 при конфликте блокировки.
Ошибки и особые значенияfalse само по себе не доказывает конфликт: проверяйте wouldBlock. Ошибка блокировки не даёт права продолжать запись без защиты.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

c+b создаёт orders.log без преждевременной очистки. try содержит защищённую операцию; finally выполняется при любом выходе и освобождает блокировку. Переход SEEK_END происходит уже внутри защиты.

Записать законченную строку под блокировкойСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/orders.log', 'c+b');
if (!$file->flock(LOCK_EX)) { throw new RuntimeException('Журнал занят'); }
try {
    $file->fseek(0, SEEK_END);
    $line = "order=42 status=paid
";
    if ($file->fwrite($line) !== strlen($line)) { throw new RuntimeException('Неполная запись'); }
    if (!$file->fflush()) { throw new RuntimeException('Сброс не выполнен'); }
} finally {
    $file->flock(LOCK_UN);
}
$file->rewind();
echo $file->fgets();
Ожидаемый результат
order=42 status=paid

В файле одна законченная строка. Другие участники должны использовать тот же протокол.

В архиве есть competitor.php. proc_open получает массив аргументов без командной оболочки и запускает тот же PHP_BINARY; pipe собирает его stdout/stderr. Второй процесс пытается взять LOCK_EX | LOCK_NB на locked.log. Основной процесс пока удерживает блокировку.

Второй процесс получает отказ без ожиданияСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/locked.log', 'c+b');
if (!$file->flock(LOCK_EX)) { throw new RuntimeException('Не получили исходную блокировку'); }
try {
    $process = proc_open([PHP_BINARY, '-n', __DIR__ . '/competitor.php'], [1 => ['pipe', 'w'], 2 => ['pipe', 'w']], $pipes);
    if (!is_resource($process)) { throw new RuntimeException('Не запущен второй процесс'); }
    $out = stream_get_contents($pipes[1]);
    $error = stream_get_contents($pipes[2]);
    fclose($pipes[1]); fclose($pipes[2]);
    $exit = proc_close($process);
    if ($exit !== 0 || $error !== '') { throw new RuntimeException('Ошибка второго процесса: ' . $error); }
    echo $out;
    $file->fwrite("order=42 writer=first
");
    $file->fflush();
} finally { $file->flock(LOCK_UN); }
$file->rewind();
echo $file->fgets();
Ожидаемый результат
Второй писатель: журнал занят, запись отложена.
order=42 writer=first

Конкурент не завис и не записал частичную строку. Показан реальный отказ другого процесса и содержимое журнала первого.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileObject::flock

(PHP 5 >= 5.1.0, PHP 7, PHP 8) SplFileObject::flock — Portable file locking

Description

public function SplFileObject::flock(int $operation, int &$wouldBlock = null): bool

Locks or unlocks the file in the same portable way as flock().

Parameters

operation

operation is one of the following:

LOCK_SH to acquire a shared lock (reader).

LOCK_EX to acquire an exclusive lock (writer).

LOCK_UN to release a lock (shared or exclusive).

It is also possible to add LOCK_NB as a bitmask to one of the above operations, if flock() should not block during the locking attempt.

wouldBlock

Set to true if the lock would block (EWOULDBLOCK errno condition).

Return Values

Returns true on success or false on failure.

See Also

flock() - Portable advisory file locking

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileObject::fpassthruВывести оставшуюся часть файла.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileObject::fpassthru(): int

fpassthru передаёт в вывод все байты от текущей позиции до EOF. Метод сам выводит содержимое; возвращаемое число — дополнительный отчёт, а не строка файла.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileObject::fpassthru(): int
РезультатКоличество переданных байтов (в описании Manual названо characters).
Ошибки и особые значенияМетод выводит всё оставшееся содержимое; ошибка передачи не должна трактоваться как успешный полный документ.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

fgets читает и пропускает первую строку квитанции. fpassthru затем печатает остаток самостоятельно: перед ним не нужен echo.

Показать остаток после заголовкаСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/receipt.txt', 'rb');
$file->fgets();
$file->fpassthru();
Ожидаемый результат
Кисть — 2 шт.
Итого: 300 руб.

Выведены две оставшиеся строки, позиция дошла до конца.

SplTempFileObject создаёт временное хранилище. После fwrite нужно rewind, иначе на текущей позиции уже конец и вывод будет пустым.

Выдать только что подготовленный документСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplTempFileObject();
$file->fwrite("Заказ 42 принят
");
$file->rewind();
$file->fpassthru();
Ожидаемый результат
Заказ 42 принят

Содержимое временного документа попало в stdout без промежуточного накопления всей строки в новой переменной.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileObject::fpassthru

(PHP 5 >= 5.1.0, PHP 7, PHP 8) SplFileObject::fpassthru — Output all remaining data on a file pointer

Description

public function SplFileObject::fpassthru(): int

Reads to EOF on the given file pointer from the current position and writes the results to the output buffer.

You may need to call SplFileObject::rewind() to reset the file pointer to the beginning of the file if you have already written data to the file.

Parameters

This function has no parameters.

Return Values

Returns the number of characters read from handle and passed through to the output.

See Also

fpassthru() - Output all remaining data on a file pointer

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileObject::fputcsvЗаписать товар в CSV и прочитать восстановленные поля.

PHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.4.0) · SPL

public function SplFileObject::fputcsv(array $fields, string $separator = ',', string $enclosure = '"', string $escape = '\\', string $eol = '\n'): int|false

fputcsv принимает массив значений и самостоятельно ставит необходимые кавычки. Результат пригоден для последующего fgetcsv при одинаковых настройках.

ПараметрЧто означает в задаче
fieldsМассив полей одной CSV-записи; запятые, кавычки и переносы внутри значений кодирует fputcsv.
separatorРазделитель полей CSV: один байт, например ";" или ",". Строка из двух символов и многобайтовая буква не подходят.
enclosureОдин байт кавычки, обычно двойная кавычка. Кавычка внутри поля записывается дважды.
escapeВ новых примерах явно "": отключить собственный механизм обратной косой черты. Это не отключает удвоение enclosure внутри поля.
eolКонец CSV-записи: "\n" по умолчанию, можно задать "\r\n". Параметр появился в PHP 8.1.
Часть контрактаЧто важно
Сигнатураpublic function SplFileObject::fputcsv(array $fields, string $separator = ',', string $enclosure = '"', string $escape = '\\', string $eol = '\n'): int|false
РезультатЧисло записанных байтов либо false при ошибке; eol настраивается с PHP 8.1.
Ошибки и особые значенияfalse при ошибке записи; ValueError при недопустимых длинах параметров CSV. CSV для открытия в таблицах требует отдельной защиты от формул в пользовательских ячейках.
ВерсииPHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.4.0)

w+b создаёт export.csv рядом с example.php и очищает его, если он уже был. Массив содержит два поля; rewind возвращает к началу после записи.

Создать CSV с разделителем внутри названияСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/export.csv', 'w+b');
$fields = ['Кисть; широкая', '2'];
if ($file->fputcsv($fields, ';', '"', '') === false) { throw new RuntimeException('Запись не выполнена'); }
$file->rewind();
echo $file->fgets();
Ожидаемый результат
"Кисть; широкая";2

export.csv содержит ровно показанную строку. Кавычки добавлены для защиты ; внутри первого поля.

Второе поле содержит настоящий перевод строки. Пятый аргумент задаёт конец записи CRLF; перенос внутри поля остаётся частью значения. fgetcsv прочитает всю логическую запись.

Кавычки и многострочное примечание: запись и обратное чтениеСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/notes.csv', 'w+b');
$file->fputcsv(['Лак "Матовый"', "Доставить
после 18:00"], ';', '"', '', "

");
$file->rewind();
$row = $file->fgetcsv(';', '"', '');
echo 'Товар: ' . $row[0] . "
Примечание:
" . $row[1] . "
";
Ожидаемый результат
Товар: Лак "Матовый"
Примечание:
Доставить
после 18:00

В notes.csv: "Лак ""Матовый""";"Доставить, затем перенос, затем после 18:00" и CRLF. После чтения восстановились исходные кавычки и две строки примечания.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileObject::fputcsv

(PHP 5 >= 5.4.0, PHP 7, PHP 8) SplFileObject::fputcsv — Write a field array as a CSV line

Description

public function SplFileObject::fputcsv(    array $fields,    string $separator = ",",    string $enclosure = "\"",    string $escape = "\\",    string $eol = "\n"): int|false

Writes the fields array to the file as a CSV line.

Parameters

fields

An array of values.

separator

The field delimiter (one single-byte character only). By default , or the value set by a prior call to SplFileObject::setCsvControl().

enclosure

The field enclosure character (one single-byte character only). By default " or the value set by a prior call to SplFileObject::setCsvControl().

escape

The escape character (at most one single-byte character). By default \ or the value set by a prior call to SplFileObject::setCsvControl(). An empty string ("") disables the proprietary escape mechanism.

Warning

In the input stream, the enclosure character can always be escaped by doubling it inside a quoted string, resulting in a single enclosure character in the parsed result. The escape character works differently: If a sequence of escape and enclosure characters appear in the input, both characters will be present in the parsed result. So for the default parameters, a CSV line like "a""b","c\"d" will have the fields parsed as a"b and c\"d, respectively.

Warning

As of PHP 8.4.0, depending on the default value of escape is deprecated. It needs to be provided explicitly either positionally or by the use of Named Arguments, or by a call to SplFileObject::setCsvControl().

eol

The optional eol parameter sets a custom End of Line sequence.

Warning When escape is set to anything other than an empty string ("") it can result in CSV that is not compliant with » RFC 4180 or unable to survive a roundtrip through the PHP CSV functions. The default for escape is "\\" so it is recommended to set it to the empty string explicitly. The default value will change in a future version of PHP, no earlier than PHP 9.0.

Note:

If an enclosure character is contained in a field, it will be escaped by doubling it, unless it is immediately preceded by an escape.

Return Values

Returns the length of the written string or false on failure.

Errors/Exceptions

Throws a ValueError if separator or enclosure is not one byte long.

Throws a ValueError if escape is not one byte long or the empty string.

Changelog

Version Description

8.4.0

Relying on the default value of escape is now deprecated.

8.1.0

The optional eol parameter has been added.

7.4.0

The escape parameter now also accepts an empty string to disable the proprietary escape mechanism.

See Also

SplFileObject::fgetcsv() - Gets line from file and parse as CSV fields

SplFileObject::setCsvControl() - Set the delimiter, enclosure and escape character for CSV

SplFileObject::getCsvControl() - Get the delimiter, enclosure and escape character for CSV

fputcsv() - Format line as CSV and write to file pointer

fgetcsv() - Gets line from file pointer and parse for CSV fields

str_getcsv() - Parse a CSV string into an array

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileObject::freadПрочитать заданный участок или обработать файл порциями.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileObject::fread(int $length): string|false

fread запрашивает не больше length байтов от текущей позиции. Короткий результат возможен; счётчик символов UTF-8 здесь не применяется.

ПараметрЧто означает в задаче
lengthКоличество байтов. В fread это верхняя граница чтения; в fwrite — необязательное ограничение записи, а не число букв.
Часть контрактаЧто важно
Сигнатураpublic function SplFileObject::fread(int $length): string|false
РезультатСтрока прочитанных байтов либо false. В конце обычно пустая строка.
Ошибки и особые значенияfalse при ошибке; неположительная длина вызывает ValueError в текущем PHP.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

bytes.txt содержит ABCDEF без переноса. fread(3) берёт три байта и оставляет позицию после них.

Прочитать две части кодаСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/bytes.txt', 'rb');
echo $file->fread(3) . "\n";
echo $file->fread(3) . "\n";
Ожидаемый результат
ABC
DEF

Второй вызов продолжает с D, а не начинает файл заново.

Создаём copy.txt рядом с example.php. while переносит порции по 16 байтов; strlen измеряет байты. Проверка fwrite не позволяет объявить неполную копию успешной.

Скопировать квитанцию порциямиСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/receipt.txt', 'rb');
$copy = new SplFileObject(__DIR__ . '/copy.txt', 'wb');
while (!$file->eof()) {
    $chunk = $file->fread(16);
    if ($chunk === false) { throw new RuntimeException('Не удалось прочитать квитанцию'); }
    if ($chunk === '') { break; }
    if ($copy->fwrite($chunk) !== strlen($chunk)) { throw new RuntimeException('Неполная запись'); }
}
$copy->fflush();
echo file_get_contents(__DIR__ . '/copy.txt');
Ожидаемый результат
Заказ 42
Кисть — 2 шт.
Итого: 300 руб.

copy.txt содержит те же три строки. Порция может разрезать букву UTF-8: байты соединяются в копии без изменения, отдельно порции не выводятся как текст.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileObject::fread

(PHP 5 >= 5.5.11, PHP 7, PHP 8) SplFileObject::fread — Read from file

Description

public function SplFileObject::fread(int $length): string|false

Reads the given number of bytes from the file.

Parameters

length

The number of bytes to read.

Return Values

Returns the string read from the file or false on failure.

Notes

Note:

Note that SplFileObject::fread() reads from the current position of the file pointer. Use SplFileObject::ftell() to find the current position of the pointer and SplFileObject::rewind() (or SplFileObject::fseek()) to rewind the pointer position.

See Also

fread() - Binary-safe file read

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileObject::fscanfРазобрать строку установленного формата.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileObject::fscanf(string $format, mixed &...$vars): array|int|null

fscanf сопоставляет текст строки с шаблоном. %s читает слово до пробела, %d — целое. Без выходных переменных возвращается массив; с переменными по ссылке — число присвоенных значений.

ПараметрЧто означает в задаче
formatШаблон разбора строки: %s — до пробела, %d — целое. Это разбор структурированной строки, не CSV.
varsНеобязательные переменные по ссылке: результат помещается в них, а метод возвращает число присваиваний вместо массива.
Часть контрактаЧто важно
Сигнатураpublic function SplFileObject::fscanf(string $format, mixed &...$vars): array|int|null
Результатarray|int|null; с выходными переменными при конце строки до первого значения может вернуться -1. Неполное соответствие требует проверки.
Ошибки и особые значенияНеполный результат и null/-1 нужно отличать от полного разбора; дополнительные проверки диапазона количества остаются задачей программы.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

metrics.txt содержит brush 2 150 и paint 3 400. Три спецификатора читают три поля; распаковка [...] присваивает их переменным, * умножает количество на цену.

Получить товар, количество и ценуСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/metrics.txt', 'rb');
$values = $file->fscanf('%s %d %d');
[$name, $qty, $price] = $values;
echo $name . ': ' . $qty . ' × ' . $price . ' = ' . ($qty * $price) . "
";
Ожидаемый результат
brush: 2 × 150 = 300

Получена сумма строки заказа, а не только массив без объяснения.

short.txt содержит только brush 2. Метод заполняет переданные переменные по ссылке; число присваиваний проверяется до расчёта.

Заполнить переменные и проверить неполную строкуСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/short.txt', 'rb');
$name = ''; $qty = 0; $price = 0;
$assigned = $file->fscanf('%s %d %d', $name, $qty, $price);
if ($assigned !== 3) { echo "Строка отклонена: нужны товар, количество и цена.
"; }
else { echo $name . ': ' . ($qty * $price) . "
"; }
Ожидаемый результат
Строка отклонена: нужны товар, количество и цена.

Недостающая цена не превращается молча в бесплатный товар.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileObject::fscanf

(PHP 5 >= 5.1.0, PHP 7, PHP 8) SplFileObject::fscanf — Parses input from file according to a format

Description

public function SplFileObject::fscanf(string $format, mixed &...$vars): array|int|null

Reads a line from the file and interprets it according to the specified format.

Any whitespace in the format string matches any whitespace in the line from the file. This means that even a tab (\t) in the format string can match a single space character in the input stream.

Parameters

format

The interpreted format for string, which is described in the documentation for sprintf() with following differences:

Function is not locale-aware.

F, g, G and b are not supported.

D stands for decimal number.

i stands for integer with base detection.

n stands for number of characters processed so far.

s stops reading at any whitespace character.

* instead of argnum$ suppresses the assignment of this conversion specification.

vars

The optional assigned values.

Return Values

If only one parameter is passed to this method, the values parsed will be returned as an array. Otherwise, if optional parameters are passed, the method will return the number of assigned values. The optional parameters must be passed by reference.

If there are more substrings expected in the format than there are available in the line read from the file, null will be returned.

When optional parameters are used and the end of the line read from the file is reached before any value has been parsed, -1 is returned.

See Also

fscanf() - Parses input from a file according to a format

sscanf() - Parses input from a string according to a format

printf() - Output a formatted string

sprintf() - Return a formatted string

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileObject::fseekСохранить байтовую позицию и прочитать нужный участок.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileObject::fseek(int $offset, int $whence = SEEK_SET): int

ftell узнаёт позицию, fseek изменяет её. Сохранять смещение удобно после полной записи журнала или CSV: следующий запуск может продолжить с него, если исходный файл не изменён.

ПараметрЧто означает в задаче
offsetСмещение в байтах. Отрицательное значение позволяет идти назад относительно SEEK_CUR или SEEK_END.
whenceSEEK_SET — от начала (по умолчанию), SEEK_CUR — от текущей позиции, SEEK_END — от конца.
Часть контрактаЧто важно
Сигнатураpublic function SplFileObject::fseek(int $offset, int $whence = SEEK_SET): int
Результатftell: int или false; fseek: 0 при успехе, -1 при неудаче.
Ошибки и особые значенияftell может вернуть false; fseek возвращает -1, если поток не допускает переход. Не каждый поток перематывается.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

В bytes.txt ровно ABCDEF. После первых двух байтов ftell вернёт 2. !== 0 в проверке fseek нужен потому, что успешный результат равен нулю.

Продолжить с сохранённого местаСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/bytes.txt', 'rb');
echo $file->fread(2) . "
";
$offset = $file->ftell();
echo 'Продолжим с байта ' . $offset . "
";
$file->fseek($offset);
echo $file->fread(4) . "
";
Ожидаемый результат
AB
Продолжим с байта 2
CDEF

Смещение указывает на C. В рабочем импорте сохраняйте также идентичность и версию файла.

SEEK_END задаёт отсчёт от конца; -2 выбирает последние два байта. SEEK_SET задаёт отсчёт от начала.

Прочитать хвост и вернуться к началуСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/bytes.txt', 'rb');
if ($file->fseek(-2, SEEK_END) !== 0) { throw new RuntimeException('Переход не выполнен'); }
echo 'Хвост: ' . $file->fread(2) . "
";
$file->fseek(0, SEEK_SET);
echo 'Начало: ' . $file->fread(2) . "
";
Ожидаемый результат
Хвост: EF
Начало: AB

Содержимое не изменилось: изменялась только позиция чтения.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileObject::fseek

(PHP 5 >= 5.1.0, PHP 7, PHP 8) SplFileObject::fseek — Seek to a position

Description

public function SplFileObject::fseek(int $offset, int $whence = SEEK_SET): int

Seek to a position in the file measured in bytes from the beginning of the file, obtained by adding offset to the position specified by whence.

Parameters

offset

The offset. A negative value can be used to move backwards through the file which is useful when SEEK_END is used as the whence value.

whence

whence values are:

SEEK_SET - Set position equal to offset bytes.

SEEK_CUR - Set position to current location plus offset.

SEEK_END - Set position to end-of-file plus offset.

If whence is not specified, it is assumed to be SEEK_SET.

Return Values

Returns 0 if the seek was successful, -1 otherwise. Note that seeking past EOF is not considered an error.

See Also

fseek() - Seeks on a file pointer

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileObject::fstatПроверить размер именно открытого потока.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileObject::fstat(): array

fstat возвращает сведения об открытом файле, в отличие от проверки нового пути через SplFileInfo. Массив содержит как числовые, так и именованные ключи stat.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileObject::fstat(): array
РезультатМассив: dev, ino, mode, nlink, uid, gid, rdev, size, atime, mtime, ctime, blksize, blocks; полная таблица значений приведена в разделе метаданных.
Ошибки и особые значенияПоля времени/блоков/владельца зависят от файловой системы; часть значений недоступна. Нельзя считать один stat защитой от конкурентной замены пути.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Массив $stat содержит ключ size. В этом фиксированном файле 6 байтов ASCII, поэтому можно прочитать их одним вызовом.

Размер и содержимое короткого кодаСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/bytes.txt', 'rb');
$stat = $file->fstat();
echo 'Размер ABCDEF: ' . $stat['size'] . " байт
";
echo $file->fread($stat['size']) . "
";
Ожидаемый результат
Размер ABCDEF: 6 байт
ABCDEF

Видны и размер, и данные, к которым он относится.

Лимит этого учебного экспорта — 1024 байта. Проверяем размер после записи и сброса; потом читаем тот же объект.

Контролировать готовый экспортСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/export.txt', 'w+b');
$file->fwrite("brush=2
");
$file->fflush();
$stat = $file->fstat();
if ($stat['size'] > 1024) { throw new RuntimeException('Экспорт больше лимита'); }
$file->rewind();
echo 'Экспорт принят (' . $stat['size'] . " байт):
";
echo $file->fread(1024);
Ожидаемый результат
Экспорт принят (8 байт):
brush=2

Проверка относится к открытому потоку, а не к отдельно повторно разрешённому пути.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileObject::fstat

(PHP 5 >= 5.1.0, PHP 7, PHP 8) SplFileObject::fstat — Gets information about the file

Description

public function SplFileObject::fstat(): array

Gathers the statistics of the file. Behaves identically to fstat().

Parameters

This function has no parameters.

Return Values

Returns an array with the statistics of the file; the format of the array is described in detail on the stat() manual page.

See Also

fstat() - Gets information about a file using an open file pointer

stat() - Gives information about a file

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileObject::ftellСохранить байтовую позицию и прочитать нужный участок.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileObject::ftell(): int|false

ftell узнаёт позицию, fseek изменяет её. Сохранять смещение удобно после полной записи журнала или CSV: следующий запуск может продолжить с него, если исходный файл не изменён.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileObject::ftell(): int|false
Результатftell: int или false; fseek: 0 при успехе, -1 при неудаче.
Ошибки и особые значенияftell может вернуть false; fseek возвращает -1, если поток не допускает переход. Не каждый поток перематывается.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

В bytes.txt ровно ABCDEF. После первых двух байтов ftell вернёт 2. !== 0 в проверке fseek нужен потому, что успешный результат равен нулю.

Продолжить с сохранённого местаСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/bytes.txt', 'rb');
echo $file->fread(2) . "
";
$offset = $file->ftell();
echo 'Продолжим с байта ' . $offset . "
";
$file->fseek($offset);
echo $file->fread(4) . "
";
Ожидаемый результат
AB
Продолжим с байта 2
CDEF

Смещение указывает на C. В рабочем импорте сохраняйте также идентичность и версию файла.

SEEK_END задаёт отсчёт от конца; -2 выбирает последние два байта. SEEK_SET задаёт отсчёт от начала.

Прочитать хвост и вернуться к началуСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/bytes.txt', 'rb');
if ($file->fseek(-2, SEEK_END) !== 0) { throw new RuntimeException('Переход не выполнен'); }
echo 'Хвост: ' . $file->fread(2) . "
";
$file->fseek(0, SEEK_SET);
echo 'Начало: ' . $file->fread(2) . "
";
Ожидаемый результат
Хвост: EF
Начало: AB

Содержимое не изменилось: изменялась только позиция чтения.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileObject::ftell

(PHP 5 >= 5.1.0, PHP 7, PHP 8) SplFileObject::ftell — Return current file position

Description

public function SplFileObject::ftell(): int|false

Returns the position of the file pointer which represents the current offset in the file stream.

Parameters

This function has no parameters.

Return Values

Returns the position of the file pointer as an integer, or false on error.

See Also

ftell() - Returns the current position of the file read/write pointer

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileObject::ftruncateУдалить хвост файла или расширить его нулевыми байтами.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileObject::ftruncate(int $size): bool

ftruncate изменяет размер уже открытого записываемого файла. Меньший размер удаляет данные; больший добавляет нулевые байты. Позицию чтения/записи задавайте отдельно.

ПараметрЧто означает в задаче
sizeЖелаемый размер файла в байтах: меньший удаляет хвост, больший дополняет нулевыми байтами.
Часть контрактаЧто важно
Сигнатураpublic function SplFileObject::ftruncate(int $size): bool
Результатtrue при успехе, false при неудаче.
Ошибки и особые значенияfalse при невозможности усечения; поток должен поддерживать изменение размера и быть открыт для записи.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Сначала создаём собственный draft.txt с PAID-junk. Размер 4 оставляет только ASCII-слово PAID; rewind возвращает чтение к началу.

Убрать учебный ошибочный хвостСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/draft.txt', 'w+b');
$file->fwrite('PAID-junk');
if (!$file->ftruncate(4)) { throw new RuntimeException('Усечение не выполнено'); }
$file->rewind();
echo $file->fread(100) . "
";
Ожидаемый результат
PAID

draft.txt теперь содержит четыре байта PAID без прежнего хвоста.

AB — два ASCII-байта. После увеличения размера до 5 читаем файл и применяем bin2hex: каждый байт показан двумя шестнадцатеричными цифрами.

Расширить двоичную записьСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/slot.bin', 'w+b');
$file->fwrite('AB');
$file->ftruncate(5);
$file->rewind();
echo 'Байты записи: ' . bin2hex($file->fread(5)) . "
";
Ожидаемый результат
Байты записи: 4142000000

41=A, 42=B, затем три нулевых байта 00. Это не три текстовые цифры «0».

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileObject::ftruncate

(PHP 5 >= 5.1.0, PHP 7, PHP 8) SplFileObject::ftruncate — Truncates the file to a given length

Description

public function SplFileObject::ftruncate(int $size): bool

Truncates the file to size bytes.

Parameters

size

The size to truncate to.

Note:

If size is larger than the file it is extended with null bytes.

If size is smaller than the file, the extra data will be lost.

Return Values

Returns true on success or false on failure.

See Also

ftruncate() - Truncates a file to a given length

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileObject::fwriteЗаписать сообщение и прочитать полученный файл.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileObject::fwrite(string $data, ?int $length = null): int|false

fwrite помещает байты в открытый поток. Режим задаёт, куда попадут данные: wb очищает прежнее содержимое, ab всегда дописывает в конец, c+b сохраняет существующий файл.

ПараметрЧто означает в задаче
dataСтрока байтов, которую требуется записать. Число символов UTF-8 может отличаться от числа байтов.
lengthКоличество байтов. В fread это верхняя граница чтения; в fwrite — необязательное ограничение записи, а не число букв.
Часть контрактаЧто важно
Сигнатураpublic function SplFileObject::fwrite(string $data, ?int $length = null): int|false
РезультатЧисло записанных байтов или false; до PHP 7.4 при неудаче возвращался 0. В PHP 8.5 length стал nullable.
Ошибки и особые значенияfalse при ошибке; частичная запись возможна. Не писать через объект, открытый только для чтения.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

Создаём receipt-copy.txt рядом с example.php. Строка содержит два перевода ; strlen измеряет байты для проверки записи. rewind нужен, потому что после записи позиция находится в конце.

Сохранить квитанциюСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/receipt-copy.txt', 'w+b');
$text = "Заказ 42
Оплачен
";
if ($file->fwrite($text) !== strlen($text)) { throw new RuntimeException('Квитанция записана не полностью'); }
$file->rewind();
echo $file->fgets();
echo $file->fgets();
Ожидаемый результат
Заказ 42
Оплачен

Полученный файл содержит ровно две показанные строки. В рабочем интерфейсе сообщение об успехе выводят только после проверки записи.

В новой учебной папке events.log отсутствует. a+b создаёт его и пишет в конец. length=3 берёт только END из ASCII-строки; для UTF-8 так можно разрезать букву.

Дополнить журнал и ограничить запись байтамиСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/events.log', 'a+b');
$file->fwrite("order=42 status=paid
");
$file->fwrite('END-unused', 3);
$file->fwrite("
");
$file->rewind();
echo $file->fread(1024);
Ожидаемый результат
order=42 status=paid
END

При повторном запуске в той же папке добавятся новые строки: append не очищает журнал.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileObject::fwrite

(PHP 5 >= 5.1.0, PHP 7, PHP 8) SplFileObject::fwrite — Write to file

Description

public function SplFileObject::fwrite(string $data, ?int $length = null): int|false

Writes the contents of data to the file

Parameters

data

The string to be written to the file.

length

If the length argument is int, writing will stop after length bytes have been written or the end of data is reached, whichever comes first.

Return Values

Returns the number of bytes written, or false on error.

Changelog

Version Description

8.5.0

length is now nullable.

7.4.0

The function now returns false instead of zero on failure.

See Also

fwrite() - Binary-safe file write

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileObject::getChildrenПонять, почему строки файла не образуют вложенное дерево.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileObject::getChildren(): null

SplFileObject реализует RecursiveIterator, но строки являются листьями: у них нет вложенных итераторов. Для дерева каталогов нужен RecursiveDirectoryIterator.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileObject::getChildren(): null
РезультатhasChildren всегда false; getChildren всегда null.
Ошибки и особые значенияЭти методы не читают подкаталоги; их постоянный результат является контрактом интерфейса, а не признаком ошибки.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

if проверяет наличие дочернего уровня; затем foreach последовательно получает строки. Мы выводим сами строки, чтобы показать смысл результата проверки.

Обойти листья файлаСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/receipt.txt', 'rb');
if ($file->getChildren() !== null) {
    throw new RuntimeException('Неожиданный дочерний итератор');
}
echo "Строки квитанции — конечные значения:
";
foreach ($file as $line) { echo $line; }
Ожидаемый результат
Строки квитанции — конечные значения:
Заказ 42
Кисть — 2 шт.
Итого: 300 руб.

У строки «Заказ 42» нет ребёнка: следующий товар — соседняя строка.

RecursiveIteratorIterator разворачивает дерево; здесь дерево имеет только один уровень листьев. new создаёт обходчик над уже открытым $file.

Передать файл общему рекурсивному обходчикуСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/receipt.txt', 'rb');
$tree = new RecursiveIteratorIterator($file);
foreach ($tree as $line) {
    if ($line === '') { continue; }
    echo 'Запись: ' . $line;
}
Ожидаемый результат
Запись: Заказ 42
Запись: Кисть — 2 шт.
Запись: Итого: 300 руб.

Обходчик сохранил все записи, но вложенных уровней не появилось.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileObject::getChildren

(PHP 5 >= 5.1.0, PHP 7, PHP 8) SplFileObject::getChildren — No purpose

Description

public function SplFileObject::getChildren(): null

An SplFileObject does not have children so this method returns null.

Parameters

This function has no parameters.

Return Values

Returns null.

See Also

RecursiveIterator::getChildren() - Returns an iterator for the current entry

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileObject::getCsvControlСогласовать формат CSV между записью и чтением.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileObject::getCsvControl(): array

setCsvControl задаёт правила последующего чтения: ";", двойную кавычку и явно пустой escape. Обратная косая черта не получает особого смысла. С PHP 8.4 полагаться на прежний escape по умолчанию устарело.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileObject::getCsvControl(): array
РезультатsetCsvControl ничего не возвращает. getCsvControl возвращает массив [separator, enclosure, escape]; третий элемент добавлен в 7.0.10, пустой escape поддержан с 7.4.
Ошибки и особые значенияsetCsvControl: ValueError для separator/enclosure не из одного байта и escape не из одного байта/пустой строки. getCsvControl возвращает действующие настройки, не анализирует формат файла.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

В stock.csv приложены заголовок name;qty, товар "Кисть; широкая";2, пустая строка и товар "Лак ""Матовый""";0. Разделитель — ;. Кавычки защищают разделитель внутри поля; двойная кавычка внутри названия удваивается. Все файлы сохранены в UTF-8. setCsvControl задаёт правила последующего чтения: ";", двойную кавычку и явно пустой escape. Обратная косая черта не получает особого смысла. С PHP 8.4 полагаться на прежний escape по умолчанию устарело. Запись [$a, $b, $c] раскладывает три элемента массива по переменным. Условие ? : выбирает одно из двух сообщений.

Показать действующие настройки и товарСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/stock.csv', 'rb');
$file->setCsvControl(';', '"', '');
[$separator, $enclosure, $escape] = $file->getCsvControl();
echo 'Разделитель: ' . $separator . "
";
echo 'Кавычка: ' . $enclosure . "
";
echo $escape === '' ? "Собственный escape отключён
" : "Собственный escape включён
";
$file->fgetcsv();
$row = $file->fgetcsv();
echo $row[0] . ': ' . $row[1] . " шт.
";
Ожидаемый результат
Разделитель: ;
Кавычка: "
Собственный escape отключён
Кисть; широкая: 2 шт.

fgetcsv без аргументов использует уже настроенный явно escape и разделитель этого объекта.

В supplier.csv записываем англоязычный товар с запятой внутри названия. Полученные getCsvControl настройки передаём обратно в fgetcsv. Затем пробуем двухбайтовый разделитель ";;" и ловим ValueError.

Другой поставщик и неверный разделительСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/supplier.csv', 'w+b');
$file->setCsvControl(',', '"', '');
$file->fputcsv(['brush, wide', 2]);
[$separator, $enclosure, $escape] = $file->getCsvControl();
$file->rewind();
$row = $file->fgetcsv($separator, $enclosure, $escape);
echo $row[0] . ': ' . $row[1] . " pcs
";
try { $file->setCsvControl(';;', '"', ''); }
catch (ValueError $error) { echo "Разделитель должен занимать один байт.
"; }
Ожидаемый результат
brush, wide: 2 pcs
Разделитель должен занимать один байт.

Настройки каждого объекта независимы; смена формата не должна молча портить колонки.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileObject::getCsvControl

(PHP 5 >= 5.2.0, PHP 7, PHP 8) SplFileObject::getCsvControl — Get the delimiter, enclosure and escape character for CSV

Description

public function SplFileObject::getCsvControl(): array

Gets the delimiter, enclosure and escape character used for parsing CSV fields.

Parameters

This function has no parameters.

Return Values

Returns an indexed array containing the delimiter, enclosure and escape character.

Changelog

Version Description

7.4.0

The escape character can now be an empty string.

7.0.10

Added the escape character to the returned array.

See Also

SplFileObject::setCsvControl() - Set the delimiter, enclosure and escape character for CSV

SplFileObject::fgetcsv() - Gets line from file and parse as CSV fields

SplFileObject::fputcsv() - Write a field array as a CSV line

fputcsv() - Format line as CSV and write to file pointer

fgetcsv() - Gets line from file pointer and parse for CSV fields

str_getcsv() - Parse a CSV string into an array

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileObject::getCurrentLineПрочитать строку настоящего текстового файла.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileObject::getCurrentLine(): string

SplFileObject открывает файл и сохраняет позицию чтения. Каждый следующий вызов fgets/getCurrentLine читает следующую строку. getCurrentLine — точный псевдоним fgets; current работает с текущим элементом итератора.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileObject::getCurrentLine(): string
РезультатКонструктор создаёт объект. Чтение возвращает строку с переводом строки; при DROP_NEW_LINE перевод убирается.
Ошибки и особые значенияНевозможность открыть/прочитать файл: RuntimeException. Конструктор для каталога: LogicException. getCurrentLine повторяет контракт fgets.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

В input/receipt.txt три строки: «Заказ 42», «Кисть — 2 шт.», «Итого: 300 руб.». new создаёт объект открытого файла; $file хранит его, а -> вызывает его метод. __DIR__ означает папку example.php. echo выводит полученную строку вместе с её переводом строки.

Открыть файл и прочитать первую строкуСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/receipt.txt', 'rb');
echo $file->getCurrentLine();
Ожидаемый результат
Заказ 42

После вызова указатель находится после первой строки. Остальные данные остались в файле.

Теперь тот же объект читается дважды. Затем открывается заведомо отсутствующий input/missing.txt. try выполняет действие, catch ловит RuntimeException и выводит сообщение для человека; $error содержит техническую ошибку.

Показать две строки, затем понятную ошибку отсутствующего файлаСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/receipt.txt', 'rb');
echo $file->getCurrentLine();
echo $file->getCurrentLine();
try {
    $missing = new SplFileObject(__DIR__ . '/input/missing.txt', 'rb');
} catch (RuntimeException $error) {
    echo "Уведомление ещё не создано.
";
}
Ожидаемый результат
Заказ 42
Кисть — 2 шт.
Уведомление ещё не создано.

Вторая строка не повторяет первую: объект помнит позицию. Ошибка другого файла не скрыта под видом пустого уведомления.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileObject::getCurrentLine

(PHP 5 >= 5.1.2, PHP 7, PHP 8) SplFileObject::getCurrentLine — Alias of SplFileObject::fgets()

Description

This method is an alias of: SplFileObject::fgets().

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileObject::getFlagsВыбрать поведение строк и CSV при обходе.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileObject::getFlags(): int

DROP_NEW_LINE убирает перевод строки. READ_AHEAD читает при rewind/next; это нужно SKIP_EMPTY для предсказуемого пропуска пустых элементов. READ_CSV возвращает массивы вместо строк.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileObject::getFlags(): int
РезультатsetFlags ничего не возвращает и заменяет маску; getFlags возвращает текущую маску int.
Ошибки и особые значенияМаска не валидирует CSV. Не заменяйте имена констант магическими числами; при setFlags прежние биты не сохраняются автоматически.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

В lines.txt первая строка first и перевод строки. Проверяем маску через &; echo окружает считанное значение квадратными скобками.

Убрать только завершающий перевод строкиСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/lines.txt');
$file->setFlags(SplFileObject::DROP_NEW_LINE);
if (($file->getFlags() & SplFileObject::DROP_NEW_LINE) !== 0) {
    echo "Перенос удаляется методом чтения:
";
}
echo '[' . $file->fgets() . "]
";
Ожидаемый результат
Перенос удаляется методом чтения:
[first]

Обе скобки остались на одной строке: DROP_NEW_LINE убрал перевод из результата.

В stock.csv приложены заголовок name;qty, товар "Кисть; широкая";2, пустая строка и товар "Лак ""Матовый""";0. Разделитель — ;. Кавычки защищают разделитель внутри поля; двойная кавычка внутри названия удваивается. Все файлы сохранены в UTF-8. setCsvControl задаёт правила последующего чтения: ";", двойную кавычку и явно пустой escape. Обратная косая черта не получает особого смысла. С PHP 8.4 полагаться на прежний escape по умолчанию устарело. В foreach $key => $row ключ — позиция, значение — массив CSV-полей. Заголовок с ключом 0 пропускается.

Обойти CSV без пустых записейСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/stock.csv', 'rb');
$file->setCsvControl(';', '"', '');
$file->setFlags(SplFileObject::READ_CSV | SplFileObject::READ_AHEAD | SplFileObject::SKIP_EMPTY | SplFileObject::DROP_NEW_LINE);
foreach ($file as $key => $row) {
    if ($key === 0) { continue; }
    echo $row[0] . ': ' . $row[1] . " шт.
";
}
Ожидаемый результат
Кисть; широкая: 2 шт.
Лак "Матовый": 0 шт.

Пустая физическая строка и финальный пустой элемент не стали товарами. Нулевое количество сохранено.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileObject::getFlags

(PHP 5 >= 5.1.0, PHP 7, PHP 8) SplFileObject::getFlags — Gets flags for the SplFileObject

Description

public function SplFileObject::getFlags(): int

Gets the flags set for an instance of SplFileObject as an int.

Parameters

This function has no parameters.

Return Values

Returns an int representing the flags.

See Also

SplFileObject::setFlags() - Sets flags for the SplFileObject

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileObject::getMaxLineLenПонять, как лимит разрезает длинную строку на фрагменты.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileObject::getMaxLineLen(): int

setMaxLineLen ограничивает длину чтения строки; getMaxLineLen возвращает заданное значение. Ноль означает отсутствие лимита. Это не проверка длины всей логической записи.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileObject::getMaxLineLen(): int
РезультатsetMaxLineLen ничего не возвращает; getMaxLineLen возвращает int, по умолчанию 0.
Ошибки и особые значенияsetMaxLineLen(-1) вызывает ValueError в PHP 8. Для потоков с недоверенными длинными строками один этот метод не гарантирует ограниченный суммарный расход памяти.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

input/long.txt содержит ABCDEFGH и перевод строки. Для наглядности это ASCII: каждый символ занимает один байт. Квадратные скобки отмечают границы результатов.

Увидеть два фрагмента одной строкиСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/long.txt');
$file->setMaxLineLen(4);
echo 'Лимит фрагмента: ' . $file->getMaxLineLen() . "
";
echo '[' . $file->fgets() . "]
";
echo '[' . $file->fgets() . "]
";
Ожидаемый результат
Лимит фрагмента: 4
[ABCD]
[EFGH]

Один физический ряд прочитан частями; лимит не отбросил остаток.

try/catch показывает ValueError для -1 в PHP 8. Значение 0 снимает ограничение, затем читается вся строка.

Снять лимит после неверного значенияСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/long.txt');
try { $file->setMaxLineLen(-1); }
catch (ValueError $error) { echo "Лимит не может быть отрицательным.
"; }
$file->setMaxLineLen(0);
echo $file->fgets();
Ожидаемый результат
Лимит не может быть отрицательным.
ABCDEFGH

Полный исходный ряд восстановлен обычным чтением без лимита.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileObject::getMaxLineLen

(PHP 5 >= 5.1.0, PHP 7, PHP 8) SplFileObject::getMaxLineLen — Get maximum line length

Description

public function SplFileObject::getMaxLineLen(): int

Gets the maximum line length as set by SplFileObject::setMaxLineLen().

Parameters

This function has no parameters.

Return Values

Returns the maximum line length if one has been set with SplFileObject::setMaxLineLen(), default is 0.

See Also

SplFileObject::setMaxLineLen() - Set maximum line length

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileObject::hasChildrenПонять, почему строки файла не образуют вложенное дерево.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileObject::hasChildren(): false

SplFileObject реализует RecursiveIterator, но строки являются листьями: у них нет вложенных итераторов. Для дерева каталогов нужен RecursiveDirectoryIterator.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileObject::hasChildren(): false
РезультатhasChildren всегда false; getChildren всегда null.
Ошибки и особые значенияЭти методы не читают подкаталоги; их постоянный результат является контрактом интерфейса, а не признаком ошибки.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

if проверяет наличие дочернего уровня; затем foreach последовательно получает строки. Мы выводим сами строки, чтобы показать смысл результата проверки.

Обойти листья файлаСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/receipt.txt', 'rb');
if ($file->hasChildren()) {
    throw new RuntimeException('Неожиданный дочерний итератор');
}
echo "Строки квитанции — конечные значения:
";
foreach ($file as $line) { echo $line; }
Ожидаемый результат
Строки квитанции — конечные значения:
Заказ 42
Кисть — 2 шт.
Итого: 300 руб.

У строки «Заказ 42» нет ребёнка: следующий товар — соседняя строка.

RecursiveIteratorIterator разворачивает дерево; здесь дерево имеет только один уровень листьев. new создаёт обходчик над уже открытым $file.

Передать файл общему рекурсивному обходчикуСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/receipt.txt', 'rb');
$tree = new RecursiveIteratorIterator($file);
foreach ($tree as $line) {
    if ($line === '') { continue; }
    echo 'Запись: ' . $line;
}
Ожидаемый результат
Запись: Заказ 42
Запись: Кисть — 2 шт.
Запись: Итого: 300 руб.

Обходчик сохранил все записи, но вложенных уровней не появилось.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileObject::hasChildren

(PHP 5 >= 5.1.2, PHP 7, PHP 8) SplFileObject::hasChildren — SplFileObject does not have children

Description

public function SplFileObject::hasChildren(): false

An SplFileObject does not have children so this method always return false.

Parameters

This function has no parameters.

Return Values

Returns false

See Also

RecursiveIterator::hasChildren() - Returns if an iterator can be created for the current entry

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileObject::keyУправлять строковой позицией и показывать выбранную строку.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileObject::key(): int

key возвращает номер от нуля. Для сообщения человеку прибавляем 1; скобки выполняют сложение до соединения строк точками.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileObject::key(): int
Результатkey возвращает int; next/rewind/seek ничего не возвращают. Данные читаются отдельным current/fgets.
Ошибки и особые значенияseek(-1): ValueError в PHP 8. rewind при невозможности перемотки: RuntimeException. seek за концом не гарантирует существование строки: результат нужно проверять.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

В input/receipt.txt три строки: «Заказ 42», «Кисть — 2 шт.», «Итого: 300 руб.». new создаёт объект открытого файла; $file хранит его, а -> вызывает его метод. __DIR__ означает папку example.php. echo выводит полученную строку вместе с её переводом строки. key возвращает номер от нуля. Для сообщения человеку прибавляем 1; скобки выполняют сложение до соединения строк точками.

Строковая позиция в квитанцииСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/receipt.txt', 'rb');
$file->seek(1);
echo "Строка " . ($file->key() + 1) . ": " . $file->current();
Ожидаемый результат
Строка 2: Кисть — 2 шт.

key возвращает номер от нуля. Для сообщения человеку прибавляем 1; скобки выполняют сложение до соединения строк точками.

В lines.txt строки first, 0, пустая строка, last. for содержит начало (rewind), условие (valid), шаг (next); тело печатает номер key + 1. continue пропускает только пустую строку и false; строка "0" сохраняется.

Номера строк без потери нуляСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/lines.txt', 'rb');
$file->setFlags(SplFileObject::DROP_NEW_LINE);
for ($file->rewind(); $file->valid(); $file->next()) {
    $line = $file->current();
    if ($line === '' || $line === false) { continue; }
    echo ($file->key() + 1) . ': ' . $line . "
";
}
Ожидаемый результат
1: first
2: 0
4: last

Показаны исходные данные после управления позицией; номера остаются привязаны к исходному файлу.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileObject::key

(PHP 5 >= 5.1.0, PHP 7, PHP 8) SplFileObject::key — Get line number

Description

public function SplFileObject::key(): int

Gets the current line number.

Note:

This number may not reflect the actual line number in the file if SplFileObject::setMaxLineLen() is used to read fixed lengths of the file.

Parameters

This function has no parameters.

Return Values

Returns the current line number.

See Also

SplFileObject::current() - Retrieve current line of file

SplFileObject::seek() - Seek to specified line

SplFileObject::next() - Read next line

SplFileObject::rewind() - Rewind the file to the first line

SplFileObject::valid() - Not at EOF

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileObject::nextУправлять строковой позицией и показывать выбранную строку.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileObject::next(): void

next сдвигает курсор итератора на следующий элемент; сам метод ничего не возвращает.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileObject::next(): void
Результатkey возвращает int; next/rewind/seek ничего не возвращают. Данные читаются отдельным current/fgets.
Ошибки и особые значенияseek(-1): ValueError в PHP 8. rewind при невозможности перемотки: RuntimeException. seek за концом не гарантирует существование строки: результат нужно проверять.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

В input/receipt.txt три строки: «Заказ 42», «Кисть — 2 шт.», «Итого: 300 руб.». new создаёт объект открытого файла; $file хранит его, а -> вызывает его метод. __DIR__ означает папку example.php. echo выводит полученную строку вместе с её переводом строки. next сдвигает курсор итератора на следующий элемент; сам метод ничего не возвращает.

Строковая позиция в квитанцииСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/receipt.txt', 'rb');
echo $file->current();
$file->next();
echo $file->current();
Ожидаемый результат
Заказ 42
Кисть — 2 шт.

next сдвигает курсор итератора на следующий элемент; сам метод ничего не возвращает.

В lines.txt строки first, 0, пустая строка, last. for содержит начало (rewind), условие (valid), шаг (next); тело печатает номер key + 1. continue пропускает только пустую строку и false; строка "0" сохраняется.

Номера строк без потери нуляСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/lines.txt', 'rb');
$file->setFlags(SplFileObject::DROP_NEW_LINE);
for ($file->rewind(); $file->valid(); $file->next()) {
    $line = $file->current();
    if ($line === '' || $line === false) { continue; }
    echo ($file->key() + 1) . ': ' . $line . "
";
}
Ожидаемый результат
1: first
2: 0
4: last

Показаны исходные данные после управления позицией; номера остаются привязаны к исходному файлу.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileObject::next

(PHP 5 >= 5.1.0, PHP 7, PHP 8) SplFileObject::next — Read next line

Description

public function SplFileObject::next(): void

Moves ahead to the next line in the file.

Parameters

This function has no parameters.

Return Values

No value is returned.

See Also

SplFileObject::current() - Retrieve current line of file

SplFileObject::key() - Get line number

SplFileObject::seek() - Seek to specified line

SplFileObject::rewind() - Rewind the file to the first line

SplFileObject::valid() - Not at EOF

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileObject::rewindУправлять строковой позицией и показывать выбранную строку.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileObject::rewind(): void

rewind возвращает к началу. После него первое чтение снова выдаёт заголовок заказа.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileObject::rewind(): void
Результатkey возвращает int; next/rewind/seek ничего не возвращают. Данные читаются отдельным current/fgets.
Ошибки и особые значенияseek(-1): ValueError в PHP 8. rewind при невозможности перемотки: RuntimeException. seek за концом не гарантирует существование строки: результат нужно проверять.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

В input/receipt.txt три строки: «Заказ 42», «Кисть — 2 шт.», «Итого: 300 руб.». new создаёт объект открытого файла; $file хранит его, а -> вызывает его метод. __DIR__ означает папку example.php. echo выводит полученную строку вместе с её переводом строки. rewind возвращает к началу. После него первое чтение снова выдаёт заголовок заказа.

Строковая позиция в квитанцииСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/receipt.txt', 'rb');
echo $file->fgets();
echo $file->fgets();
$file->rewind();
echo $file->fgets();
Ожидаемый результат
Заказ 42
Кисть — 2 шт.
Заказ 42

rewind возвращает к началу. После него первое чтение снова выдаёт заголовок заказа.

В lines.txt строки first, 0, пустая строка, last. for содержит начало (rewind), условие (valid), шаг (next); тело печатает номер key + 1. continue пропускает только пустую строку и false; строка "0" сохраняется.

Номера строк без потери нуляСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/lines.txt', 'rb');
$file->setFlags(SplFileObject::DROP_NEW_LINE);
for ($file->rewind(); $file->valid(); $file->next()) {
    $line = $file->current();
    if ($line === '' || $line === false) { continue; }
    echo ($file->key() + 1) . ': ' . $line . "
";
}
Ожидаемый результат
1: first
2: 0
4: last

Показаны исходные данные после управления позицией; номера остаются привязаны к исходному файлу.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileObject::rewind

(PHP 5 >= 5.1.0, PHP 7, PHP 8) SplFileObject::rewind — Rewind the file to the first line

Description

public function SplFileObject::rewind(): void

Rewinds the file back to the first line.

Parameters

This function has no parameters.

Return Values

No value is returned.

Errors/Exceptions

Throws a RuntimeException if cannot be rewound.

See Also

SplFileObject::current() - Retrieve current line of file

SplFileObject::key() - Get line number

SplFileObject::seek() - Seek to specified line

SplFileObject::next() - Read next line

SplFileObject::valid() - Not at EOF

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileObject::seekУправлять строковой позицией и показывать выбранную строку.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileObject::seek(int $line): void

seek(2) выбирает третью строку: нумерация начинается с нуля. current получает именно выбранную строку.

ПараметрЧто означает в задаче
lineНомер строки от нуля: 0 — первая, 2 — третья. Это не смещение в байтах.
Часть контрактаЧто важно
Сигнатураpublic function SplFileObject::seek(int $line): void
Результатkey возвращает int; next/rewind/seek ничего не возвращают. Данные читаются отдельным current/fgets.
Ошибки и особые значенияseek(-1): ValueError в PHP 8. rewind при невозможности перемотки: RuntimeException. seek за концом не гарантирует существование строки: результат нужно проверять.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

В input/receipt.txt три строки: «Заказ 42», «Кисть — 2 шт.», «Итого: 300 руб.». new создаёт объект открытого файла; $file хранит его, а -> вызывает его метод. __DIR__ означает папку example.php. echo выводит полученную строку вместе с её переводом строки. seek(2) выбирает третью строку: нумерация начинается с нуля. current получает именно выбранную строку.

Строковая позиция в квитанцииСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/receipt.txt', 'rb');
$file->seek(2);
echo $file->current();
Ожидаемый результат
Итого: 300 руб.

seek(2) выбирает третью строку: нумерация начинается с нуля. current получает именно выбранную строку.

Отрицательный номер проверяется через try/catch. После сообщения программа явно выбирает строку 0 и продолжает чтение.

Ошибка номера и восстановление чтенияСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/receipt.txt', 'rb');
try {
    $file->seek(-1);
} catch (ValueError $error) {
    echo "Номер строки должен быть не меньше нуля.
";
}
$file->seek(0);
echo $file->current();
Ожидаемый результат
Номер строки должен быть не меньше нуля.
Заказ 42

Показаны исходные данные после управления позицией; номера остаются привязаны к исходному файлу.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileObject::seek

(PHP 5 >= 5.1.0, PHP 7, PHP 8) SplFileObject::seek — Seek to specified line

Description

public function SplFileObject::seek(int $line): void

Seek to specified line in the file.

Parameters

line

The zero-based line number to seek to.

Return Values

No value is returned.

Errors/Exceptions

Throws a LogicException if the line is negative.

See Also

SplFileObject::current() - Retrieve current line of file

SplFileObject::key() - Get line number

SplFileObject::next() - Read next line

SplFileObject::rewind() - Rewind the file to the first line

SplFileObject::valid() - Not at EOF

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileObject::setCsvControlСогласовать формат CSV между записью и чтением.

PHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.4.0) · SPL

public function SplFileObject::setCsvControl(string $separator = ',', string $enclosure = '"', string $escape = '\\'): void

setCsvControl задаёт правила последующего чтения: ";", двойную кавычку и явно пустой escape. Обратная косая черта не получает особого смысла. С PHP 8.4 полагаться на прежний escape по умолчанию устарело.

ПараметрЧто означает в задаче
separatorРазделитель полей CSV: один байт, например ";" или ",". Строка из двух символов и многобайтовая буква не подходят.
enclosureОдин байт кавычки, обычно двойная кавычка. Кавычка внутри поля записывается дважды.
escapeВ новых примерах явно "": отключить собственный механизм обратной косой черты. Это не отключает удвоение enclosure внутри поля.
Часть контрактаЧто важно
Сигнатураpublic function SplFileObject::setCsvControl(string $separator = ',', string $enclosure = '"', string $escape = '\\'): void
РезультатsetCsvControl ничего не возвращает. getCsvControl возвращает массив [separator, enclosure, escape]; третий элемент добавлен в 7.0.10, пустой escape поддержан с 7.4.
Ошибки и особые значенияsetCsvControl: ValueError для separator/enclosure не из одного байта и escape не из одного байта/пустой строки. getCsvControl возвращает действующие настройки, не анализирует формат файла.
ВерсииPHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.4.0)

В stock.csv приложены заголовок name;qty, товар "Кисть; широкая";2, пустая строка и товар "Лак ""Матовый""";0. Разделитель — ;. Кавычки защищают разделитель внутри поля; двойная кавычка внутри названия удваивается. Все файлы сохранены в UTF-8. setCsvControl задаёт правила последующего чтения: ";", двойную кавычку и явно пустой escape. Обратная косая черта не получает особого смысла. С PHP 8.4 полагаться на прежний escape по умолчанию устарело. Запись [$a, $b, $c] раскладывает три элемента массива по переменным. Условие ? : выбирает одно из двух сообщений.

Показать действующие настройки и товарСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/stock.csv', 'rb');
$file->setCsvControl(';', '"', '');
[$separator, $enclosure, $escape] = $file->getCsvControl();
echo 'Разделитель: ' . $separator . "
";
echo 'Кавычка: ' . $enclosure . "
";
echo $escape === '' ? "Собственный escape отключён
" : "Собственный escape включён
";
$file->fgetcsv();
$row = $file->fgetcsv();
echo $row[0] . ': ' . $row[1] . " шт.
";
Ожидаемый результат
Разделитель: ;
Кавычка: "
Собственный escape отключён
Кисть; широкая: 2 шт.

fgetcsv без аргументов использует уже настроенный явно escape и разделитель этого объекта.

В supplier.csv записываем англоязычный товар с запятой внутри названия. Полученные getCsvControl настройки передаём обратно в fgetcsv. Затем пробуем двухбайтовый разделитель ";;" и ловим ValueError.

Другой поставщик и неверный разделительСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/supplier.csv', 'w+b');
$file->setCsvControl(',', '"', '');
$file->fputcsv(['brush, wide', 2]);
[$separator, $enclosure, $escape] = $file->getCsvControl();
$file->rewind();
$row = $file->fgetcsv($separator, $enclosure, $escape);
echo $row[0] . ': ' . $row[1] . " pcs
";
try { $file->setCsvControl(';;', '"', ''); }
catch (ValueError $error) { echo "Разделитель должен занимать один байт.
"; }
Ожидаемый результат
brush, wide: 2 pcs
Разделитель должен занимать один байт.

Настройки каждого объекта независимы; смена формата не должна молча портить колонки.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileObject::setCsvControl

(PHP 5 >= 5.2.0, PHP 7, PHP 8) SplFileObject::setCsvControl — Set the delimiter, enclosure and escape character for CSV

Description

public function SplFileObject::setCsvControl(string $separator = ",", string $enclosure = "\"", string $escape = "\\"): void

Sets the delimiter, enclosure and escape character for parsing CSV fields.

Parameters

separator

The separator parameter sets the field separator. It must be a single byte character.

enclosure

The enclosure parameter sets the field enclosure character. It must be a single byte character.

escape

The escape parameter sets the escape character. It must be a single byte character or the empty string. The empty string ("") disables the proprietary escape mechanism.

Warning

In the input stream, the enclosure character can always be escaped by doubling it inside a quoted string, resulting in a single enclosure character in the parsed result. The escape character works differently: If a sequence of escape and enclosure characters appear in the input, both characters will be present in the parsed result. So for the default parameters, a CSV line like "a""b","c\"d" will have the fields parsed as a"b and c\"d, respectively.

Warning

As of PHP 8.4.0, depending on the default value of escape is deprecated. It needs to be provided explicitly either positionally or by the use of named arguments.

Warning When escape is set to anything other than an empty string ("") it can result in CSV that is not compliant with » RFC 4180 or unable to survive a roundtrip through the PHP CSV functions. The default for escape is "\\" so it is recommended to set it to the empty string explicitly. The default value will change in a future version of PHP, no earlier than PHP 9.0.

Return Values

No value is returned.

Errors/Exceptions

Throws a ValueError if separator or enclosure is not one byte long.

Throws a ValueError if escape is not one byte long or the empty string.

Changelog

Version Description

8.4.0

Relying on the default value of escape is now deprecated.

7.4.0

The escape parameter now also accepts an empty string to disable the proprietary escape mechanism.

See Also

SplFileObject::getCsvControl() - Get the delimiter, enclosure and escape character for CSV

SplFileObject::fgetcsv() - Gets line from file and parse as CSV fields

SplFileObject::fputcsv() - Write a field array as a CSV line

fputcsv() - Format line as CSV and write to file pointer

fgetcsv() - Gets line from file pointer and parse for CSV fields

str_getcsv() - Parse a CSV string into an array

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileObject::setFlagsВыбрать поведение строк и CSV при обходе.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileObject::setFlags(int $flags): void

DROP_NEW_LINE убирает перевод строки. READ_AHEAD читает при rewind/next; это нужно SKIP_EMPTY для предсказуемого пропуска пустых элементов. READ_CSV возвращает массивы вместо строк.

ПараметрЧто означает в задаче
flagsБитовая маска. Оператор | объединяет DROP_NEW_LINE, READ_AHEAD, SKIP_EMPTY и READ_CSV; setFlags заменяет всю прежнюю маску.
Часть контрактаЧто важно
Сигнатураpublic function SplFileObject::setFlags(int $flags): void
РезультатsetFlags ничего не возвращает и заменяет маску; getFlags возвращает текущую маску int.
Ошибки и особые значенияМаска не валидирует CSV. Не заменяйте имена констант магическими числами; при setFlags прежние биты не сохраняются автоматически.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

В lines.txt первая строка first и перевод строки. Проверяем маску через &; echo окружает считанное значение квадратными скобками.

Убрать только завершающий перевод строкиСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/lines.txt');
$file->setFlags(SplFileObject::DROP_NEW_LINE);
if (($file->getFlags() & SplFileObject::DROP_NEW_LINE) !== 0) {
    echo "Перенос удаляется методом чтения:
";
}
echo '[' . $file->fgets() . "]
";
Ожидаемый результат
Перенос удаляется методом чтения:
[first]

Обе скобки остались на одной строке: DROP_NEW_LINE убрал перевод из результата.

В stock.csv приложены заголовок name;qty, товар "Кисть; широкая";2, пустая строка и товар "Лак ""Матовый""";0. Разделитель — ;. Кавычки защищают разделитель внутри поля; двойная кавычка внутри названия удваивается. Все файлы сохранены в UTF-8. setCsvControl задаёт правила последующего чтения: ";", двойную кавычку и явно пустой escape. Обратная косая черта не получает особого смысла. С PHP 8.4 полагаться на прежний escape по умолчанию устарело. В foreach $key => $row ключ — позиция, значение — массив CSV-полей. Заголовок с ключом 0 пропускается.

Обойти CSV без пустых записейСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/stock.csv', 'rb');
$file->setCsvControl(';', '"', '');
$file->setFlags(SplFileObject::READ_CSV | SplFileObject::READ_AHEAD | SplFileObject::SKIP_EMPTY | SplFileObject::DROP_NEW_LINE);
foreach ($file as $key => $row) {
    if ($key === 0) { continue; }
    echo $row[0] . ': ' . $row[1] . " шт.
";
}
Ожидаемый результат
Кисть; широкая: 2 шт.
Лак "Матовый": 0 шт.

Пустая физическая строка и финальный пустой элемент не стали товарами. Нулевое количество сохранено.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileObject::setFlags

(PHP 5 >= 5.1.0, PHP 7, PHP 8) SplFileObject::setFlags — Sets flags for the SplFileObject

Description

public function SplFileObject::setFlags(int $flags): void

Sets the flags to be used by the SplFileObject.

Parameters

flags

Bit mask of the flags to set. See SplFileObject constants for the available flags.

Return Values

No value is returned.

See Also

SplFileObject::getFlags() - Gets flags for the SplFileObject

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileObject::setMaxLineLenПонять, как лимит разрезает длинную строку на фрагменты.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileObject::setMaxLineLen(int $maxLength): void

setMaxLineLen ограничивает длину чтения строки; getMaxLineLen возвращает заданное значение. Ноль означает отсутствие лимита. Это не проверка длины всей логической записи.

ПараметрЧто означает в задаче
maxLengthМаксимальная длина читаемого фрагмента строки; 0 снимает ограничение. Отрицательное число недопустимо.
Часть контрактаЧто важно
Сигнатураpublic function SplFileObject::setMaxLineLen(int $maxLength): void
РезультатsetMaxLineLen ничего не возвращает; getMaxLineLen возвращает int, по умолчанию 0.
Ошибки и особые значенияsetMaxLineLen(-1) вызывает ValueError в PHP 8. Для потоков с недоверенными длинными строками один этот метод не гарантирует ограниченный суммарный расход памяти.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

input/long.txt содержит ABCDEFGH и перевод строки. Для наглядности это ASCII: каждый символ занимает один байт. Квадратные скобки отмечают границы результатов.

Увидеть два фрагмента одной строкиСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/long.txt');
$file->setMaxLineLen(4);
echo 'Лимит фрагмента: ' . $file->getMaxLineLen() . "
";
echo '[' . $file->fgets() . "]
";
echo '[' . $file->fgets() . "]
";
Ожидаемый результат
Лимит фрагмента: 4
[ABCD]
[EFGH]

Один физический ряд прочитан частями; лимит не отбросил остаток.

try/catch показывает ValueError для -1 в PHP 8. Значение 0 снимает ограничение, затем читается вся строка.

Снять лимит после неверного значенияСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/long.txt');
try { $file->setMaxLineLen(-1); }
catch (ValueError $error) { echo "Лимит не может быть отрицательным.
"; }
$file->setMaxLineLen(0);
echo $file->fgets();
Ожидаемый результат
Лимит не может быть отрицательным.
ABCDEFGH

Полный исходный ряд восстановлен обычным чтением без лимита.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileObject::setMaxLineLen

(PHP 5 >= 5.1.0, PHP 7, PHP 8) SplFileObject::setMaxLineLen — Set maximum line length

Description

public function SplFileObject::setMaxLineLen(int $maxLength): void

Sets the maximum length of a line to be read.

Parameters

maxLength

The maximum length of a line.

Return Values

No value is returned.

Errors/Exceptions

Throws DomainException when maxLength is less than zero.

See Also

SplFileObject::getMaxLineLen() - Get maximum line length

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileObject::__toStringВывести текущую строку объекта как текст.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileObject::__toString(): string

echo объекта вызывает __toString автоматически. В актуальном PHP это представление текущего элемента; SplFileInfo::__toString вместо этого возвращает путь.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileObject::__toString(): string
РезультатСтрока текущего элемента, в режиме READ_CSV — CSV-представление.
Ошибки и особые значенияМетод зависит от состояния чтения и флагов; не используйте его как универсальное имя файла.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

В input/receipt.txt три строки: «Заказ 42», «Кисть — 2 шт.», «Итого: 300 руб.». new создаёт объект открытого файла; $file хранит его, а -> вызывает его метод. __DIR__ означает папку example.php. echo выводит полученную строку вместе с её переводом строки. echo $file вызывает магический метод __toString без явной стрелки.

Вывести объект файлаСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/receipt.txt', 'rb');
echo $file;
echo $file;
Ожидаемый результат
Заказ 42
Заказ 42

На текущем PHP два вывода показывают один текущий элемент.

seek(2) выбирает третью строку; точка соединяет префикс со строковым представлением объекта.

Выбрать строку перед выводомСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/receipt.txt', 'rb');
$file->seek(2);
echo "К оплате — " . $file;
Ожидаемый результат
К оплате — Итого: 300 руб.

Для получения имени файла нужен getPathname, а не приведение SplFileObject к строке.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileObject::__toString

(PHP 5 >= 5.1.0, PHP 7, PHP 8) SplFileObject::__toString — Returns the current line as a string

Description

public function SplFileObject::__toString(): string

This method will return the current line as a string.

Parameters

This function has no parameters.

Return Values

Returns the current line as a string.

Changelog

Version Description

8.1.14, 8.2.1

Changed from an alias of SplFileObject::fgets() to an implementation of SplFileObject::current() which returns a CSV string when the SplFileObject::READ_CSV flag is set.

7.2.19, 7.3.6

Changed from an alias of SplFileObject::current() to an alias of SplFileObject::fgets().

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplFileObject::validПрочитать содержимое до конца, сохранив строку «0».

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplFileObject::valid(): bool

eof отвечает, достигнут ли конец потока; valid отвечает, можно ли продолжить итерацию. Значение флага не является данными файла. Конец нередко становится известен только после попытки чтения.

ПараметрЧто означает в задаче
Параметров нетМетод использует текущее состояние объекта; это состояние показано в примере до вызова.
Часть контрактаЧто важно
Сигнатураpublic function SplFileObject::valid(): bool
Результатeof: true при конце; valid: true пока итератор действителен.
Ошибки и особые значенияБулев результат не объясняет ошибку чтения. Исключение чтения нельзя считать обычным завершением файла.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

В input/receipt.txt три строки: «Заказ 42», «Кисть — 2 шт.», «Итого: 300 руб.». new создаёт объект открытого файла; $file хранит его, а -> вызывает его метод. __DIR__ означает папку example.php. echo выводит полученную строку вместе с её переводом строки. while повторяет тело, пока условие истинно; ! означает отрицание. break завершает цикл.

Вывести квитанцию до концаСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/receipt.txt', 'rb');
for ($file->rewind(); $file->valid(); $file->next()) {
    $line = $file->current();
    if ($line === false) { break; }
    echo $line;
}
Ожидаемый результат
Заказ 42
Кисть — 2 шт.
Итого: 300 руб.

Вывод совпадает с содержимым input/receipt.txt, а не только сообщает, что конец найден.

Оператор === сравнивает и значение, и тип; || означает «или». Пропускаем только пустую строку либо false. DROP_NEW_LINE убирает завершающий перевод строки.

Пустые строки и нулевое значениеСамостоятельный пример
<?php
declare(strict_types=1);

$file = new SplFileObject(__DIR__ . '/input/lines.txt', 'rb');
$file->setFlags(SplFileObject::DROP_NEW_LINE);
for ($file->rewind(); $file->valid(); $file->next()) {
    $line = $file->current();
    if ($line === false || $line === '') { continue; }
    echo "Значение: " . $line . "\n";
}
Ожидаемый результат
Значение: first
Значение: 0
Значение: last

Ноль выведен, пустая строка пропущена. Это правило импорта, а не автоматическая проверка корректности данных.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplFileObject::valid

(PHP 5 >= 5.1.0, PHP 7, PHP 8) SplFileObject::valid — Not at EOF

Description

public function SplFileObject::valid(): bool

Check whether EOF has been reached.

Parameters

This function has no parameters.

Return Values

Returns true if not reached EOF, false otherwise.

See Also

SplFileObject::current() - Retrieve current line of file

SplFileObject::key() - Get line number

SplFileObject::seek() - Seek to specified line

SplFileObject::next() - Read next line

SplFileObject::rewind() - Rewind the file to the first line

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

SplTempFileObject::__constructПодготовить временный документ с порогом хранения в памяти.

Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL

public function SplTempFileObject::__construct(int $maxMemory = 2097152)

Объект сразу готов к чтению и записи. По умолчанию первые 2 MiB хранятся в памяти; при превышении порога поток переносится во временный файл ОС. Отрицательный порог означает только память, нулевой — сразу временный файл.

ПараметрЧто означает в задаче
maxMemoryПорог в байтах, по умолчанию 2 MiB. При превышении данные переносятся во временный файл; 0 — сразу на диск, отрицательное значение — только память.
Часть контрактаЧто важно
Сигнатураpublic function SplTempFileObject::__construct(int $maxMemory = 2097152)
РезультатНовый временный файловый объект. После освобождения объекта временное хранилище закрывается; это не постоянный документ.
Ошибки и особые значенияRuntimeException при невозможности создать временный поток. Нужны доступная память и, после порога, доступный системный временный каталог.
ВерсииДоступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице

new SplTempFileObject() не требует filename. fwrite записывает данные; rewind возвращает указатель к началу перед чтением.

Записать временную квитанцию и прочитать еёСамостоятельный пример
<?php
declare(strict_types=1);

$temp = new SplTempFileObject();
$temp->fwrite("Заказ 42
Сумма: 300 руб.
");
$temp->rewind();
echo $temp->fgets();
echo $temp->fgets();
Ожидаемый результат
Заказ 42
Сумма: 300 руб.

Временный документ получен без создания постоянного receipt.txt.

Порог maxMemory=16 специально мал. Документ из 61 байта его превышает. fstat показывает размер данных потока; затем порции копируются в именованный saved-receipt.txt.

Превысить порог и сохранить полезные данныеСамостоятельный пример
<?php
declare(strict_types=1);

$temp = new SplTempFileObject(16);
$text = "Заказ 42
Кисть — 2 шт.
Итого: 300 руб.
";
$temp->fwrite($text);
$size = $temp->fstat()['size'];
echo 'Порог 16 байт; документ ' . $size . " байт.
";
$temp->rewind();
$file = new SplFileObject(__DIR__ . '/saved-receipt.txt', 'wb');
while (!$temp->eof()) {
    $chunk = $temp->fread(32);
    if ($chunk === false) { throw new RuntimeException('Ошибка чтения'); }
    if ($chunk === '') { break; }
    if ($file->fwrite($chunk) !== strlen($chunk)) { throw new RuntimeException('Ошибка записи'); }
}
$file->fflush();
echo file_get_contents(__DIR__ . '/saved-receipt.txt');
Ожидаемый результат
Порог 16 байт; документ 61 байт.
Заказ 42
Кисть — 2 шт.
Итого: 300 руб.

Все три строки сохранились после превышения порога. Сам факт перемещения на диск следует контракту php://temp; размер fstat не измеряет RAM и не раскрывает внутренний путь.

Полный официальный контракт и история версий (оригинал)

PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.

SplTempFileObject::__construct

(PHP 5 >= 5.1.2, PHP 7, PHP 8) SplTempFileObject::__construct — Construct a new temporary file object

Description

public function SplTempFileObject::__construct(int $maxMemory = 2 * 1024 * 1024)

Construct a new temporary file object.

Parameters

maxMemory

The maximum amount of memory (in bytes, default is 2 MB) for the temporary file to use. If the temporary file exceeds this size, it will be moved to a file in the system's temp directory.

If maxMemory is negative, only memory will be used. If maxMemory is zero, no memory will be used.

Errors/Exceptions

Throws a RuntimeException if an error occurs.

See Also

SplFileObject

PHP input/output streams (for php://temp and php://memory)

Полный маршрут: чтение, CSV и временный файл. Готовые задачи: импорт и журнал.

Вернуться к карте SPL. Базовые понятия: массив, цикл, функция, объект.

Источники и обсуждения

Код и руководство с собой

Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.

Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.

Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.