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

Дерево руководства
Глава 75 · От первого результата к полному справочнику
SPL: полный справочник стандартной библиотеки PHP
Все интерфейсы, исключения, функции, структуры данных, итераторы и файловые классы SPL: от первой понятной задачи до точного контракта каждого официального метода.
Интерфейс SPL: договор, который соединяет ваш код с готовым алгоритмом
Интерфейс нужен, когда готовый алгоритм должен работать с разными объектами одинаковым способом. Например, обходчик дерева не обязан знать, хранится ли каталог в массиве, файлах или ответе API: ему достаточно договора RecursiveIterator. Интерфейс перечисляет обязательные методы и их типы, но не создаёт данные, не пишет реализацию и не запускает методы сам.
- Ваш класс пишет implements и реализует обязательные методы
- Клиент принимает объект по имени интерфейса
- Клиент вызывает только обещанные операции
- Конкретный объект сам решает, откуда взять данные
| Интерфейс | Реальная потребность | Готовый следующий инструмент |
|---|---|---|
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 |
| Посчитать или материализовать iterable | iterator_count, iterator_to_array |
| Настроить/проверить autoload | spl_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-массив остаётся универсальным и часто самым понятным вариантом.
- Нужны оба конца и порядок → SplDoublyLinkedList / SplQueue / SplStack
- Всегда нужна лучшая по правилу запись → SplHeap / SplPriorityQueue
- Известно точное число позиций → SplFixedArray
- Нужен объектный API вокруг PHP-массива → ArrayObject
- Ключом должен быть object → SplObjectStorage
Это модель операций, а не схема внутренней памяти байт-в-байт. Реальная стоимость зависит от версии PHP, типов значений и нагрузки. Измеряйте тот сценарий, который будет работать в приложении.
<?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 — сокращение от «первый пришёл, первый вышел».
- enqueue: Импорт → Отчёт
- dequeue: Импорт переходит в $job
- В очереди остаётся Отчёт
Модель похожа на очередь к одному окну. В 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::dequeue | SplQueue::dequeue |
| SplQueue::enqueue | SplQueue::enqueue |
Методы унаследованного списка разобраны ниже. Для последних изменений первым нужен стек, для срочности — приоритетная очередь.
SplStack: последняя сохранённая запись возвращается первой
Для отмены редактирования нужна последняя сохранённая цена, а не самая старая. Стек даёт такую дисциплину: push кладёт новое значение наверх, pop снимает верхнее.
- push 500, затем push 450
- Верх: 450; ниже: 500
- 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: цепочка с доступом с двух концов
Маршрут меняется с обоих концов: добавили гараж перед складом, новую доставку после магазина. Двусвязный список хранит для каждого узла соседей слева и справа.
- Начало: Гараж
- Гараж ↔ Склад ↔ Магазин
- Конец: Магазин
Стрелки объясняют соседство. 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::add | SplDoublyLinkedList::add |
| SplDoublyLinkedList::bottom | SplDoublyLinkedList::bottom |
| SplDoublyLinkedList::count | SplDoublyLinkedList::count |
| SplDoublyLinkedList::current | SplDoublyLinkedList::current |
| SplDoublyLinkedList::getIteratorMode | SplDoublyLinkedList::getIteratorMode |
| SplDoublyLinkedList::isEmpty | SplDoublyLinkedList::isEmpty |
| SplDoublyLinkedList::key | SplDoublyLinkedList::key |
| SplDoublyLinkedList::next | SplDoublyLinkedList::next |
| SplDoublyLinkedList::offsetExists | SplDoublyLinkedList::offsetExists |
| SplDoublyLinkedList::offsetGet | SplDoublyLinkedList::offsetGet |
| SplDoublyLinkedList::offsetSet | SplDoublyLinkedList::offsetSet |
| SplDoublyLinkedList::offsetUnset | SplDoublyLinkedList::offsetUnset |
| SplDoublyLinkedList::pop | SplDoublyLinkedList::pop |
| SplDoublyLinkedList::prev | SplDoublyLinkedList::prev |
| SplDoublyLinkedList::push | SplDoublyLinkedList::push |
| SplDoublyLinkedList::rewind | SplDoublyLinkedList::rewind |
| SplDoublyLinkedList::serialize | SplDoublyLinkedList::serialize |
| SplDoublyLinkedList::setIteratorMode | SplDoublyLinkedList::setIteratorMode |
| SplDoublyLinkedList::shift | SplDoublyLinkedList::shift |
| SplDoublyLinkedList::top | SplDoublyLinkedList::top |
| SplDoublyLinkedList::unserialize | SplDoublyLinkedList::unserialize |
| SplDoublyLinkedList::unshift | SplDoublyLinkedList::unshift |
| SplDoublyLinkedList::valid | SplDoublyLinkedList::valid |
SplHeap: наверху значение, выбранное правилом сравнения
Если каждый раз нужна работа с ближайшим сроком, порядок поступления уже не подходит. Куча поддерживает одну доступную вершину: после её извлечения выбирается следующая.
- Вход: 30, 10, 20 минут
- Правило: меньшая минута важнее
- 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::compare | SplHeap::compare |
| SplHeap::count | SplHeap::count |
| SplHeap::current | SplHeap::current |
| SplHeap::extract | SplHeap::extract |
| SplHeap::insert | SplHeap::insert |
| SplHeap::isCorrupted | SplHeap::isCorrupted |
| SplHeap::isEmpty | SplHeap::isEmpty |
| SplHeap::key | SplHeap::key |
| SplHeap::next | SplHeap::next |
| SplHeap::recoverFromCorruption | SplHeap::recoverFromCorruption |
| SplHeap::rewind | SplHeap::rewind |
| SplHeap::top | SplHeap::top |
| SplHeap::valid | SplHeap::valid |
SplMinHeap: меньшие значения выдаются первыми
Нужна ближайшая минута из заранее известных сроков. SplMinHeap наследует SplHeap и меняет сравнение так, чтобы минимум был наверху. Для однородных чисел собственный класс не нужен.
- Добавлены 30, 10, 20
- Первым вернётся 10
- Затем 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::compare | SplMinHeap::compare |
SplMaxHeap: больший объём выдаётся первым
Чтобы каждый раз выбирать самый крупный остаток, нужна максимальная вершина. SplMaxHeap — готовый наследник SplHeap с обычным сравнением PHP.
- Добавлены 12, 40, 25
- Первым вернётся 40
- После извлечения наверху 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::compare | SplMaxHeap::compare |
SplPriorityQueue: данные отдельно, срочность отдельно
У задания есть текст и срочность. FIFO не пропустит пароль перед давно ожидающим отчётом. Приоритетная очередь поддерживает максимальный приоритет, а в ответ отдаёт полезное задание.
- Отчёт: приоритет 10
- Сброс пароля: приоритет 50
- 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
<?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::compare | SplPriorityQueue::compare |
| SplPriorityQueue::count | SplPriorityQueue::count |
| SplPriorityQueue::current | SplPriorityQueue::current |
| SplPriorityQueue::extract | SplPriorityQueue::extract |
| SplPriorityQueue::getExtractFlags | SplPriorityQueue::getExtractFlags |
| SplPriorityQueue::insert | SplPriorityQueue::insert |
| SplPriorityQueue::isCorrupted | SplPriorityQueue::isCorrupted |
| SplPriorityQueue::isEmpty | SplPriorityQueue::isEmpty |
| SplPriorityQueue::key | SplPriorityQueue::key |
| SplPriorityQueue::next | SplPriorityQueue::next |
| SplPriorityQueue::recoverFromCorruption | SplPriorityQueue::recoverFromCorruption |
| SplPriorityQueue::rewind | SplPriorityQueue::rewind |
| SplPriorityQueue::setExtractFlags | SplPriorityQueue::setExtractFlags |
| SplPriorityQueue::top | SplPriorityQueue::top |
| SplPriorityQueue::valid | SplPriorityQueue::valid |
SplFixedArray: заранее известные места с числовыми индексами
Три датчика должны дать три показания, но второй ещё не ответил. Нужно сохранить его место, не смешивая отсутствие замера с нулевой температурой. Фиксированный массив начинает с заданного количества null-ячеек.
- Индексы: 0 | 1 | 2
- После записи: 18 | null | 21
- 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::__construct | SplFixedArray::__construct |
| SplFixedArray::count | SplFixedArray::count |
| SplFixedArray::current | SplFixedArray::current |
| SplFixedArray::fromArray | SplFixedArray::fromArray |
| SplFixedArray::getIterator | SplFixedArray::getIterator |
| SplFixedArray::getSize | SplFixedArray::getSize |
| SplFixedArray::jsonSerialize | SplFixedArray::jsonSerialize |
| SplFixedArray::key | SplFixedArray::key |
| SplFixedArray::next | SplFixedArray::next |
| SplFixedArray::offsetExists | SplFixedArray::offsetExists |
| SplFixedArray::offsetGet | SplFixedArray::offsetGet |
| SplFixedArray::offsetSet | SplFixedArray::offsetSet |
| SplFixedArray::offsetUnset | SplFixedArray::offsetUnset |
| SplFixedArray::rewind | SplFixedArray::rewind |
| SplFixedArray::__serialize | SplFixedArray::__serialize |
| SplFixedArray::setSize | SplFixedArray::setSize |
| SplFixedArray::toArray | SplFixedArray::toArray |
| SplFixedArray::__unserialize | SplFixedArray::__unserialize |
| SplFixedArray::valid | SplFixedArray::valid |
| SplFixedArray::__wakeup | SplFixedArray::__wakeup |
ArrayObject: когда массиву нужен объектный интерфейс
Задача: несколько методов проекта должны передавать и изменять один набор настроек через квадратные скобки, count() и foreach, а иногда подставлять собственный итератор. ArrayObject оборачивает PHP-массив в объект, реализующий ArrayAccess, Countable и IteratorAggregate. Обычный массив остаётся правильным и более простым выбором, если методы объекта не нужны.
- Исходный array передан в new ArrayObject
- Объект хранит свою таблицу key → value
- [] вызывает offsetGet/offsetSet
- foreach получает отдельный Iterator
- 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::append | ArrayObject::append |
| ArrayObject::asort | ArrayObject::asort |
| ArrayObject::__construct | ArrayObject::__construct |
| ArrayObject::count | ArrayObject::count |
| ArrayObject::exchangeArray | ArrayObject::exchangeArray |
| ArrayObject::getArrayCopy | ArrayObject::getArrayCopy |
| ArrayObject::getFlags | ArrayObject::getFlags |
| ArrayObject::getIterator | ArrayObject::getIterator |
| ArrayObject::getIteratorClass | ArrayObject::getIteratorClass |
| ArrayObject::ksort | ArrayObject::ksort |
| ArrayObject::natcasesort | ArrayObject::natcasesort |
| ArrayObject::natsort | ArrayObject::natsort |
| ArrayObject::offsetExists | ArrayObject::offsetExists |
| ArrayObject::offsetGet | ArrayObject::offsetGet |
| ArrayObject::offsetSet | ArrayObject::offsetSet |
| ArrayObject::offsetUnset | ArrayObject::offsetUnset |
| ArrayObject::serialize | ArrayObject::serialize |
| ArrayObject::setFlags | ArrayObject::setFlags |
| ArrayObject::setIteratorClass | ArrayObject::setIteratorClass |
| ArrayObject::uasort | ArrayObject::uasort |
| ArrayObject::uksort | ArrayObject::uksort |
| ArrayObject::unserialize | ArrayObject::unserialize |
SplObjectStorage: объект как ключ, данные как info
Задача: во время одного процесса отметить, какие конкретные объекты уже обработаны, и прикрепить к каждому служебное состояние, не меняя класс этих объектов. В обычном PHP-массиве object нельзя напрямую использовать как ключ. SplObjectStorage реализует карту «идентичность объекта → info» и может служить множеством объектов, если info не требуется.
- object-key: конкретный экземпляр Document
- hash: техническая идентичность внутри storage
- info: статус, счётчик или другие метаданные
- 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
<?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::addAll | SplObjectStorage::addAll |
| SplObjectStorage::attach | SplObjectStorage::attach |
| SplObjectStorage::contains | SplObjectStorage::contains |
| SplObjectStorage::count | SplObjectStorage::count |
| SplObjectStorage::current | SplObjectStorage::current |
| SplObjectStorage::detach | SplObjectStorage::detach |
| SplObjectStorage::getHash | SplObjectStorage::getHash |
| SplObjectStorage::getInfo | SplObjectStorage::getInfo |
| SplObjectStorage::key | SplObjectStorage::key |
| SplObjectStorage::next | SplObjectStorage::next |
| SplObjectStorage::offsetExists | SplObjectStorage::offsetExists |
| SplObjectStorage::offsetGet | SplObjectStorage::offsetGet |
| SplObjectStorage::offsetSet | SplObjectStorage::offsetSet |
| SplObjectStorage::offsetUnset | SplObjectStorage::offsetUnset |
| SplObjectStorage::removeAll | SplObjectStorage::removeAll |
| SplObjectStorage::removeAllExcept | SplObjectStorage::removeAllExcept |
| SplObjectStorage::rewind | SplObjectStorage::rewind |
| SplObjectStorage::seek | SplObjectStorage::seek |
| SplObjectStorage::serialize | SplObjectStorage::serialize |
| SplObjectStorage::setInfo | SplObjectStorage::setInfo |
| SplObjectStorage::unserialize | SplObjectStorage::unserialize |
| SplObjectStorage::valid | SplObjectStorage::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: несколько источников как один поток
Заказы сайта и магазина уже представлены отдельными итераторами. Их нужно обработать подряд и видеть источник каждой записи, не копируя всё в общий массив.
- append сохраняет ссылку на каждый Iterator
- current/key приходят из активного источника
- после его конца курсор переходит к следующему
Эта схема показывает значения и переходы именно приведённого примера. Внутри 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-протокол.
- new получает исходные элементы и флаги
- rewind/seek выбирают позицию; current/key читают её
- 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.
- valid всегда false
- foreach сразу завершает обход
- 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 специально запрещает выдавать выдуманное текущее значение или ключ.
<?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: повторяем цикл только под внешним пределом
Конечный шаблон смен или задержек нужно повторить заранее известное число раз.
- внутренний Iterator доходит до конца
- InfiniteIterator перематывает его
- 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. Обёртка добавляет нужный интерфейс без копирования дат.
- конструктор принимает Traversable
- внешний протокол делегируется Iterator-слою
- для DatePeriod PHP создаёт InternalIterator, который виден через getInnerIterator
Эта схема показывает значения и переходы именно приведённого примера. Внутри PHP объект хранит служебное состояние, а не нарисованные коробки или стрелки.
DatePeriod реализует Traversable, но не обычный Iterator. Декоратор нужен, когда следующий компонент требует именно 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: конечное окно существующего обхода
Экрану нужна только одна страница каталога, а циклической схеме — только несколько значений.
- offset пропускает предыдущие позиции
- limit разрешает ограниченное число current
- после окна 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: несколько колонок на одной позиции
Названия и остатки приходят отдельными упорядоченными источниками. На каждом шаге требуется составить одну строку отчёта.
- attachIterator связывает источник с именем
- rewind/next двигают все курсоры
- 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: не начинать поток заново
Первый потребитель прочитал часть одноразовой последовательности; второй должен продолжить с текущего места.
- rewind разрешает начальную позицию, но не возвращает назад
- current можно прочитать снова на той же позиции
- 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.
- Iterator ставит курсор на заказ №102.
- Callback получает массив заказа и проверяет status === paid.
- Предикат возвращает true, поэтому foreach видит заказ №102.
- Для следующего заказа вопрос задаётся заново; исходный массив не переписывается.
Callback — значение, по которому PHP может вызвать функцию: например, имя isPaidOrder или анонимная функция. Начните с именованной функции: её проще отдельно прочитать и проверить. Когда правило должно хранить настройки и повторно использоваться как самостоятельный тип, переходите к подклассу FilterIterator.
| Инструмент | Когда он понятнее |
|---|---|
| CallbackFilterIterator | Одно короткое правило для готового Iterator. |
| FilterIterator | Повторно используемый класс правила с параметрами и именем предметной области. |
| RegexIterator | Правило действительно описывает форму строки: префикс, расширение, шаблон журнала. |
| Обычный foreach | Нужно разложить элементы в accepted/rejected, изменить каждый элемент либо выполнить побочный эффект. |
CachingIterator: сосед справа и уже прочитанная часть потока
При формировании цепочки нужен признак следующего элемента, а при диагностике импорта — только уже прочитанные записи. CachingIterator оборачивает существующий Iterator и добавляет эти два вида состояния.
- rewind/next двигают внутренний Iterator и обновляют текущую позицию
- hasNext заглядывает к соседу, не отдавая его потребителю
- 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 заказов. Нужно оставить оплаченные строки или доступные позиции веб-витрины, не создавая новый массив и отдельный класс.
- конструктор получает внутренний Iterator и callable
- для текущего значения callback получает value, key и внутренний Iterator
- 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().
- подкласс вызывает parent::__construct с готовым Iterator
- rewind/next двигают источник до позиции, где accept вернул true
- 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 применяет регулярное выражение к значению либо ключу и может вернуть совпадение, все совпадения, части или замену.
- pattern описывает именно форму текста, режим определяет форму current()
- USE_KEY переносит сопоставление на ключ, INVERT_MATCH инвертирует принятие
- 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 оставляет только текущие узлы с детьми.
- Исходный RecursiveIterator ставит курсор на очередной узел.
- ParentIterator спрашивает hasChildren() и принимает только true.
- foreach получает parent; getChildren() открывает следующий уровень по запросу.
Эта схема показывает значения и переходы именно приведённого примера. Внутри PHP объект хранит служебное состояние, а не нарисованные коробки или стрелки.
До SPL задача формулируется просто: пройти первый уровень и оставить только значения-массивы.
<?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 пропускает листья и отдаёт узлы, в которые можно спуститься.
<?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 не скрывает это устройство: он добавляет к текущему курсору два явных действия — спросить о детях и открыть их.
- current/key указывают на один элемент массива.
- hasChildren() отличает вложенный контейнер от листа.
- 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, историю уже пройденных элементов каждого уровня.
- RecursiveIterator остаётся источником текущего уровня.
- Обёртка кэширует позицию и отвечает hasNext().
- Для ветви 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 обязан пропустить родителей, иначе обход не попадёт внутрь и потеряет даже разрешённые дочерние значения.
- Callback получает current, key и итератор текущего уровня.
- Если у узла есть дети, parent сохраняется ради спуска.
- Для листа 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(), листья — по отдельному правилу.
<?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, а символические ссылки по умолчанию не превращаются в ветви.
- Объект читает одну запись текущего каталога.
- hasChildren(false) разрешает спуск только в настоящий каталог, не следуя по ссылке.
- 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(). Родители сохраняются ради пути, а листья проходят предметную проверку.
- Подкласс получает RecursiveIterator в конструкторе.
- accept() читает current/key и отдельно пропускает parent.
- 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 поверх всей глубины
Нужно превратить вложенную конфигурацию в плоский поток, сохранив глубину и возможность восстановить путь. Сначала показана обычная рекурсивная функция, затем тот же стек ведёт стандартный обходчик.
- RecursiveIterator сообщает hasChildren()/getChildren().
- Обходчик хранит стек активных уровней и выбранный порядок LEAVES_ONLY, SELF_FIRST или CHILD_FIRST.
- 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.
<?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 должен принимать и нужные листья, и их родителей, иначе путь исчезнет до достижения совпадения.
- RegexIterator сопоставляет current или key согласно flags.
- Совпавший parent остаётся доступным для hasChildren().
- 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; линии помогают читать результат, но не становятся частью исходных данных.
- Рекурсивный обходчик выбирает очередной узел и знает соседей.
- Кэширующий слой определяет, продолжать ли вертикальную линию.
- 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() префикс ветвей.
<?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: одна папка как курсор
Нужно увидеть записи одной локальной папки и для каждой безопасно получить имя, расширение и тип, не загружая всё дерево в массив.
- new DirectoryIterator(path) открывает существующую папку
- курсор по очереди указывает на ., .. и реальные записи
- valid() разрешает чтение, current()/key() дают запись и позицию
- 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
При чтении папки нужно пропустить специальные переходы «эта папка» и «родительская папка», но оставить реальный конфигурационный файл с точкой в начале имени.
<?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
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 с размером. Требуется задать этот договор до цикла.
- KEY_AS_FILENAME или KEY_AS_PATHNAME задаёт форму key()
- CURRENT_AS_PATHNAME, CURRENT_AS_FILEINFO или CURRENT_AS_SELF задаёт current()
- SKIP_DOTS независимо убирает только . и ..
- 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
Перед отправкой файлов нужно узнать их размер, не открывая содержимое.
<?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(), но должен понимать, почему после небрежной смены режима внезапно появились . и ...
<?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.
<?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 за выбранный месяц.
- pattern содержит путь и glob-маску имени
- конструктор вычисляет совпавшие записи одного уровня
- count() сообщает число совпадений до или после foreach
- итерация возвращает формы key/current, выбранные флагами FilesystemIterator
Эта схема показывает значения и переходы именно приведённого примера. Внутри PHP объект хранит служебное состояние, а не нарисованные коробки или стрелки.
Генератор превью должен взять только JPG непосредственно из uploads и не читать notes.txt или вложенную папку.
<?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: сначала одна полезная строка
Задача начинается не с перечня методов. Есть сохранённая квитанция, и программе нужно показать её заголовок. Для этого достаточно пути, объекта открытого файла и одного чтения. Результат ниже можно увидеть сразу.
<?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 меняют то, что будет прочитано дальше. Поэтому два вызова подряд обычно возвращают разные части файла.
SplFileInfo— путь, имя, тип и метаданные.SplFileObject extends SplFileInfo— тот же путь плюс открытый поток, позиция и чтение/запись.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: байты требуют явной политики
<?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/fread | EOF отдельно от ошибки/пустой строки; кодировку и переносы. |
| Перебрать CSV | fgetcsv или 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 определяет, использовать ли исходные ключи.
| Параметр | Что означает в задаче |
|---|---|
$iterator | Traversable или array. |
$preserve_keys | true сохраняет ключи; 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 будет исчерпан.
| Параметр | Что означает в задаче |
|---|---|
$iterator | Traversable или, начиная с PHP 8.2, array. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | function iterator_count(Traversable|array $iterator): int |
| Результат | int — число пройденных элементов. |
| Ошибки и особые значения | Исключения из Iterator выходят наружу. Бесконечная последовательность не завершится. |
| Версии | Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице |
<?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.
<?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
<?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): voidSubject вызывает 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 не зависел от публичного изменяемого свойства.
<?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") был бы другим экземпляром и не снял бы эту подписку.
<?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 сам не создаёт очередь и не запускает параллельные задачи.
<?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.
| Параметр | Что означает в задаче |
|---|---|
$iterator | Traversable, который будет последовательно обходиться. |
$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; исторические изменения указаны по официальной странице |
<?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): boolPHP вызывает загрузчики по очереди, когда встречает ещё не объявленный class/interface/trait/enum. Callback получает полное имя без начального обратного слеша.
| Параметр | Что означает в задаче |
|---|---|
$callback | Callable загрузчика; null регистрирует стандартный spl_autoload. |
$throw | Исторический параметр; начиная с PHP 8 false игнорируется и сообщает notice. |
$prepend | true добавляет callback в начало, false — в конец. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | function spl_autoload_register(?callable $callback = null, bool $throw = true, bool $prepend = false): bool |
| Результат | true при успешной регистрации. |
| Ошибки и особые значения | Некорректный callback даёт TypeError. Исключение callback при загрузке выходит вызывающему коду. |
| Версии | PHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.0.0) |
<?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; исторические изменения указаны по официальной странице |
<?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; исторические изменения указаны по официальной странице |
<?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
Вызов с аргументом одновременно устанавливает и возвращает строку. Восстановление важно в общей среде теста, потому что настройка глобальна для процесса.
<?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; исторические изменения указаны по официальной странице |
<?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; исторические изменения указаны по официальной странице |
<?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): voidpush("Магазин") создаёт новый последний узел; существующий маршрут сохраняет порядок.
| Параметр | Что означает в задаче |
|---|---|
| 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): voidunshift("Гараж") делает новый первый узел. Числовые позиции прежних узлов меняются.
| Параметр | Что означает в задаче |
|---|---|
| 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(): mixedshift() потребляет физическое начало и возвращает его значение. Следующий узел становится началом.
| Параметр | Что означает в задаче |
|---|---|
| Параметров нет | Метод использует текущее состояние объекта; это состояние показано в примере до вызова. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | 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(): mixedtop() возвращает физически последний узел; повторное чтение оставляет список на месте.
| Параметр | Что означает в задаче |
|---|---|
| Параметров нет | Метод использует текущее состояние объекта; это состояние показано в примере до вызова. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | 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(): mixedbottom() возвращает физически первый узел. Даже при 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): voidoffsetSet(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): voidoffsetUnset(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(): intcount() возвращает число хранимых узлов, независимо от текущей позиции указателя. 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(): boolisEmpty() отвечает о всём контейнере. Это отличается от 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
<?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(): intkey() возвращает позицию ручного итератора. Номер не является идентификатором остановки; при удалении или другом направлении его смысл определяется текущим обходом.
| Параметр | Что означает в задаче |
|---|---|
| Параметров нет | Метод использует текущее состояние объекта; это состояние показано в примере до вызова. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | 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(): voidnext() перемещает ручной указатель в направлении режима. В 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(): voidprev() перемещает указатель против направления режима. В обычном 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(): voidrewind() ставит указатель на начало выбранного обхода: физическое начало при 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(): boolvalid() проверяет текущий ручной указатель. Непустой список может иметь недействительный указатель, если он уже прошёл конец.
| Параметр | Что означает в задаче |
|---|---|
| Параметров нет | Метод использует текущее состояние объекта; это состояние показано в примере до вызова. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | 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(): mixedtop() даёт следующего кандидата, сохраняя количество элементов.
| Параметр | Что означает в задаче |
|---|---|
| Параметров нет | Метод использует текущее состояние объекта; это состояние показано в примере до вызова. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | 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(): intkey() возвращает число оставшихся узлов минус один. Это технический ключ итератора, а не 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(): voidnext() потребляет верхний элемент без выдачи его значения. Для обработки сначала 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(): voidrewind() — 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(): boolvalid() разрешает чтение текущей вершины, пока узлы существуют. В отличие от связного списка отдельной позиции вне непустой кучи здесь нет.
| Параметр | Что означает в задаче |
|---|---|
| Параметров нет | Метод использует текущее состояние объекта; это состояние показано в примере до вызова. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | 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(): boolisCorrupted() сообщает о флаге нарушения после отказа сравнения. Это контроль состояния алгоритма, не проверка бизнес-валидности всех заданий.
| Параметр | Что означает в задаче |
|---|---|
| Параметров нет | Метод использует текущее состояние объекта; это состояние показано в примере до вызова. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | 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
<?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(): mixedtop() даёт следующего кандидата, сохраняя количество элементов.
| Параметр | Что означает в задаче |
|---|---|
| Параметров нет | Метод использует текущее состояние объекта; это состояние показано в примере до вызова. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | 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+ |
<?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(): intkey() возвращает число оставшихся узлов минус один. Это технический ключ итератора, а не 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
<?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(): voidnext() потребляет верхний элемент без выдачи его значения. Для обработки сначала 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(): voidrewind() — 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
<?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(): boolvalid() разрешает чтение текущей вершины, пока узлы существуют. В отличие от связного списка отдельной позиции вне непустой кучи здесь нет.
| Параметр | Что означает в задаче |
|---|---|
| Параметров нет | Метод использует текущее состояние объекта; это состояние показано в примере до вызова. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | 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(): boolisCorrupted() сообщает о флаге нарушения после отказа сравнения. Это контроль состояния алгоритма, не проверка бизнес-валидности всех заданий.
| Параметр | Что означает в задаче |
|---|---|
| Параметров нет | Метод использует текущее состояние объекта; это состояние показано в примере до вызова. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | 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
<?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
<?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
<?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 — пустой контейнер, а не автоматически растущий массив.
| Параметр | Что означает в задаче |
|---|---|
| size | int от 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(): intcount() равен 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(): intgetSize() даёт число мест; условие допустимости: 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): booloffsetExists(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): mixedoffsetGet(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): voidoffsetSet(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): voidoffsetUnset(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-массив. |
| preserveKeys | bool, по умолчанию 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(): arraytoArray сохраняет порядок и 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
<?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(): arrayjsonSerialize отдаёт значение для кодировщика, а json_encode создаёт строку. Это две разных операции с разными результатами.
| Параметр | Что означает в задаче |
|---|---|
| Параметров нет | Метод использует текущее состояние объекта; это состояние показано в примере до вызова. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | public function SplFixedArray::jsonSerialize(): array |
| Результат | array с последовательными индексами и null-местами; не JSON-строка. |
| Ошибки и особые значения | Неподдерживаемые вложенные значения/неверный UTF-8 могут вызвать ошибку именно на этапе json_encode. Используйте JSON_THROW_ON_ERROR и согласованную схему. |
| Версии | PHP 8.1+ |
<?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+ |
<?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+ |
<?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 |
<?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
<?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 используют те же записи, если в описании не сказано о копии.
| Параметр | Что означает в задаче |
|---|---|
| flags | SORT_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
<?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
<?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
<?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+ |
<?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+ |
<?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+ |
<?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+ |
<?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
<?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+ |
<?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
$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
$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.
| Параметр | Что означает в задаче |
|---|---|
| mode | COUNT_NORMAL или COUNT_RECURSIVE. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | public function SplObjectStorage::count(int $mode = COUNT_NORMAL): int |
| Результат | int: число записей storage. |
| Ошибки и особые значения | Неверный тип mode — TypeError. |
| Версии | PHP 5.1+ |
<?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
<?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
$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
<?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
<?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
<?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+ |
<?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+ |
<?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
$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
<?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
<?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
<?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+ |
<?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
<?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): voidAppendIterator::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(): mixedAppendIterator::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(): ArrayIteratorAppendIterator::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(): ?intAppendIterator::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(): mixedAppendIterator::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(): voidAppendIterator::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(): voidAppendIterator::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(): boolAppendIterator::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): voidArrayIterator::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(): intArrayIterator::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(): mixedArrayIterator::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. Этот пример раскрывает тот же порядок явно.
<?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(): arrayArrayIterator::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(): intArrayIterator::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|nullArrayIterator::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. Этот пример раскрывает тот же порядок явно.
<?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(): voidArrayIterator::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. Этот пример раскрывает тот же порядок явно.
<?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): boolArrayIterator::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): mixedArrayIterator::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): voidArrayIterator::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): voidArrayIterator::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(): voidArrayIterator::rewind нужен, чтобы попытаться установить курсор на первый элемент. В этой задаче ArrayIterator помогает обходить и изменять массив через объект с явным курсором, сортировкой, позиционированием и ArrayAccess. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.
| Параметр | Что означает в задаче |
|---|---|
| Параметров нет | Метод использует текущее состояние объекта; это состояние показано в примере до вызова. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | public function ArrayIterator::rewind(): void |
| Результат | void: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет. |
| Ошибки и особые значения | Не каждый Traversable можно повторить. NoRewindIterator намеренно игнорирует повторную перемотку, а Generator после завершения может выбросить исключение. |
| Версии | Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице |
foreach сам вызывает пять методов Iterator. Этот пример раскрывает тот же порядок явно.
<?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): voidArrayIterator::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. Этот пример раскрывает тот же порядок явно.
<?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(): stringArrayIterator::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): voidArrayIterator::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): voidArrayIterator::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(): boolArrayIterator::valid нужен, чтобы проверить, указывает ли курсор на существующий элемент. В этой задаче ArrayIterator помогает обходить и изменять массив через объект с явным курсором, сортировкой, позиционированием и ArrayAccess. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.
| Параметр | Что означает в задаче |
|---|---|
| Параметров нет | Метод использует текущее состояние объекта; это состояние показано в примере до вызова. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | public function ArrayIterator::valid(): bool |
| Результат | bool: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование. |
| Ошибки и особые значения | false означает отсутствие текущего элемента, а не ошибку бизнес-данных. Ошибки источника могут возникнуть отдельно. |
| Версии | Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице |
foreach сам вызывает пять методов Iterator. Этот пример раскрывает тот же порядок явно.
<?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): trueArrayIterator::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): trueArrayIterator::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(): trueArrayIterator::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(): trueArrayIterator::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): trueArrayIterator::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): trueArrayIterator::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(): neverEmptyIterator::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 специально запрещает выдавать выдуманное текущее значение или ключ.
<?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(): neverEmptyIterator::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 специально запрещает выдавать выдуманное текущее значение или ключ.
<?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(): voidEmptyIterator::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 специально запрещает выдавать выдуманное текущее значение или ключ.
<?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(): voidEmptyIterator::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 специально запрещает выдавать выдуманное текущее значение или ключ.
<?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(): falseEmptyIterator::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 специально запрещает выдавать выдуманное текущее значение или ключ.
<?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(): voidInfiniteIterator::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.
<?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(): mixedIteratorIterator::current нужен, чтобы получить текущее значение без продвижения курсора. В этой задаче IteratorIterator помогает обернуть Traversable, который ещё не является Iterator, и затем подключить фильтр или другой декоратор. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.
| Параметр | Что означает в задаче |
|---|---|
| Параметров нет | Метод использует текущее состояние объекта; это состояние показано в примере до вызова. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | public function IteratorIterator::current(): mixed |
| Результат | mixed: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование. |
| Ошибки и особые значения | Сначала вызывайте valid(). На недействительном курсоре особое значение зависит от класса и не должно смешиваться с настоящим null. |
| Версии | Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице |
DatePeriod реализует Traversable, но не обычный Iterator. Декоратор нужен, когда следующий компонент требует именно 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(): ?IteratorIteratorIterator::getInnerIterator нужен, чтобы получить непосредственно обёрнутый итератор текущего уровня. В этой задаче IteratorIterator помогает обернуть Traversable, который ещё не является Iterator, и затем подключить фильтр или другой декоратор. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.
| Параметр | Что означает в задаче |
|---|---|
| Параметров нет | Метод использует текущее состояние объекта; это состояние показано в примере до вызова. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | public function IteratorIterator::getInnerIterator(): ?Iterator |
| Результат | ?Iterator: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование. |
| Ошибки и особые значения | TypeError и исключения вложенного источника не скрываются. Особые значения, предупреждения и версии перечислены в полном официальном контракте ниже. |
| Версии | Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице |
DatePeriod реализует Traversable, но не обычный Iterator. Декоратор нужен, когда следующий компонент требует именно 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(): mixedIteratorIterator::key нужен, чтобы получить ключ или позицию текущего элемента. В этой задаче IteratorIterator помогает обернуть Traversable, который ещё не является Iterator, и затем подключить фильтр или другой декоратор. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.
| Параметр | Что означает в задаче |
|---|---|
| Параметров нет | Метод использует текущее состояние объекта; это состояние показано в примере до вызова. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | public function IteratorIterator::key(): mixed |
| Результат | mixed: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование. |
| Ошибки и особые значения | Сначала вызывайте valid(). Ключ может быть int, string или составным массивом и не обязан быть бизнес-идентификатором. |
| Версии | Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице |
DatePeriod реализует Traversable, но не обычный Iterator. Декоратор нужен, когда следующий компонент требует именно 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(): voidIteratorIterator::next нужен, чтобы перевести курсор к следующему элементу. В этой задаче IteratorIterator помогает обернуть Traversable, который ещё не является Iterator, и затем подключить фильтр или другой декоратор. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.
| Параметр | Что означает в задаче |
|---|---|
| Параметров нет | Метод использует текущее состояние объекта; это состояние показано в примере до вызова. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | public function IteratorIterator::next(): void |
| Результат | void: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет. |
| Ошибки и особые значения | Продвижение одноразового источника нельзя отменить. Исключение из вложенного источника передаётся вызывающему коду. |
| Версии | Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице |
DatePeriod реализует Traversable, но не обычный Iterator. Декоратор нужен, когда следующий компонент требует именно 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(): voidIteratorIterator::rewind нужен, чтобы попытаться установить курсор на первый элемент. В этой задаче IteratorIterator помогает обернуть Traversable, который ещё не является Iterator, и затем подключить фильтр или другой декоратор. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.
| Параметр | Что означает в задаче |
|---|---|
| Параметров нет | Метод использует текущее состояние объекта; это состояние показано в примере до вызова. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | public function IteratorIterator::rewind(): void |
| Результат | void: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет. |
| Ошибки и особые значения | Не каждый Traversable можно повторить. NoRewindIterator намеренно игнорирует повторную перемотку, а Generator после завершения может выбросить исключение. |
| Версии | Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице |
DatePeriod реализует Traversable, но не обычный Iterator. Декоратор нужен, когда следующий компонент требует именно 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(): boolIteratorIterator::valid нужен, чтобы проверить, указывает ли курсор на существующий элемент. В этой задаче IteratorIterator помогает обернуть Traversable, который ещё не является Iterator, и затем подключить фильтр или другой декоратор. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.
| Параметр | Что означает в задаче |
|---|---|
| Параметров нет | Метод использует текущее состояние объекта; это состояние показано в примере до вызова. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | public function IteratorIterator::valid(): bool |
| Результат | bool: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование. |
| Ошибки и особые значения | false означает отсутствие текущего элемента, а не ошибку бизнес-данных. Ошибки источника могут возникнуть отдельно. |
| Версии | Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице |
DatePeriod реализует Traversable, но не обычный Iterator. Декоратор нужен, когда следующий компонент требует именно 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(): mixedLimitIterator::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(): intLimitIterator::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(): mixedLimitIterator::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(): voidLimitIterator::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(): voidLimitIterator::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): intLimitIterator::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(): boolLimitIterator::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): voidMultipleIterator::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): boolMultipleIterator::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(): intMultipleIterator::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(): arrayMultipleIterator::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): voidMultipleIterator::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(): intMultipleIterator::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(): arrayMultipleIterator::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(): voidMultipleIterator::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(): voidMultipleIterator::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): voidMultipleIterator::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(): boolMultipleIterator::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(): mixedNoRewindIterator::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(): mixedNoRewindIterator::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(): voidNoRewindIterator::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(): voidNoRewindIterator::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(): boolNoRewindIterator::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(): intcount() относится к уже наполненному 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 без полного кеша, а позднее попытался читать его как массив. Пример делает отказ видимым и затем включает нужный режим явно.
<?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(): mixedcurrent() возвращает значение внутреннего 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(): arraygetCache() возвращает обычный массив 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 без полного кеша, а позднее попытался читать его как массив. Пример делает отказ видимым и затем включает нужный режим явно.
<?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(): intgetFlags() возвращает одно целое число, в котором отдельные биты обозначают 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(): boolhasNext() отвечает, есть ли у внутреннего 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(): mixedkey() делегирует ключ внутреннему 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(): voidnext() переводит обёрнутый 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): boolCachingIterator::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 без полного кеша, а позднее попытался читать его как массив. Пример делает отказ видимым и затем включает нужный режим явно.
<?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): mixedCachingIterator::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 без полного кеша, а позднее попытался читать его как массив. Пример делает отказ видимым и затем включает нужный режим явно.
<?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): voidCachingIterator::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): voidCachingIterator::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(): voidrewind() вызывает перемотку внутреннего 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): voidsetFlags() принимает новую полную маску. В одном примере строковое представление переключается с ключа на значение; в другом 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 без полного кеша, а позднее попытался читать его как массив. Пример делает отказ видимым и затем включает нужный режим явно.
<?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(): boolvalid() сообщает, можно ли безопасно читать 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 заказов/остатков; курсор остаётся общим с фильтром. |
| callback | Callable, принимающий 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(): boolCallbackFilterIterator вызывает переданный 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; наружу видны только принятые позиции.
| Параметр | Что означает в задаче |
|---|---|
| iterator | Iterator, который будет лениво продвигаться до каждой принятой позиции. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | 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(): boolaccept() применяет 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.
| Параметр | Что означает в задаче |
|---|---|
| iterator | Iterator строковых значений либо ключей; данные не копируются. |
| pattern | PCRE-выражение с разделителями и модификаторами, например /\.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(): intgetFlags() возвращает битовую маску специальных флагов 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-флаги.
<?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(): intgetMode() сообщает, какую форму 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-флаги.
<?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(): intgetPregFlags() возвращает настройки 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-флаги.
<?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(): stringgetRegex() возвращает ровно шаблон, переданный конструктору, например /^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-флаги.
<?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): voidsetFlags() выбирает, сопоставлять 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-флаги.
<?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): voidsetMode() переключает 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-флаги.
<?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): voidsetPregFlags() передаёт настройки соответствующей 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(): boolParentIterator::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(): ?RecursiveFilterIteratorParentIterator::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(): boolParentIterator::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(): voidParentIterator::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(): voidParentIterator::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(): ?RecursiveArrayIteratorRecursiveArrayIterator::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(): boolRecursiveArrayIterator::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(): ?RecursiveCachingIteratorRecursiveCachingIterator::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: при печати маршрутов видно, есть ли следующий сосед.
<?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(): boolRecursiveCachingIterator::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 снова пропускаются только ради доступа к листьям.
<?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(): RecursiveCallbackFilterIteratorRecursiveCallbackFilterIterator::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(): boolRecursiveCallbackFilterIterator::hasChildren. Ответ относится к текущей позиции и не двигает курсор. После rewind текущий принятый узел database остаётся ветвью. hasChildren() относится к исходной структуре, уже обёрнутой фильтром. Во второй независимой ситуации: Первый текущий элемент — массив room, второй — булево значение online. Оба приняты callback, но только у первого есть дети. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.
| Параметр | Что означает в задаче |
|---|---|
| Параметров нет | Метод использует текущее состояние объекта; это состояние показано в примере до вызова. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | public function RecursiveCallbackFilterIterator::hasChildren(): bool |
| Результат | bool: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование. |
| Ошибки и особые значения | TypeError и исключения внутреннего источника не превращаются в пустой результат. У файлов явно передавайте false, если политика запрещает следовать по символическим ссылкам. |
| Версии | Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице |
После rewind текущий принятый узел database остаётся ветвью. hasChildren() относится к исходной структуре, уже обёрнутой фильтром.
<?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(): RecursiveDirectoryIteratorRecursiveDirectoryIterator::getChildren. Метод открывает ровно следующий уровень и возвращает новый рекурсивный итератор. Когда current — каталог docs, getChildren() создаёт RecursiveDirectoryIterator для этого пути. Во второй независимой ситуации: Тот же метод открывает папку archive внутри logs и возвращает объект того же рекурсивного класса. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.
| Параметр | Что означает в задаче |
|---|---|
| Параметров нет | Метод использует текущее состояние объекта; это состояние показано в примере до вызова. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | public function RecursiveDirectoryIterator::getChildren(): RecursiveDirectoryIterator |
| Результат | RecursiveDirectoryIterator: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование. |
| Ошибки и особые значения | TypeError и исключения внутреннего источника не превращаются в пустой результат. Сначала проверяйте hasChildren(), если форма данных заранее не гарантирована. |
| Версии | Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице |
Когда current — каталог docs, getChildren() создаёт RecursiveDirectoryIterator для этого пути.
<?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(): stringRecursiveDirectoryIterator::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(): stringRecursiveDirectoryIterator::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): boolRecursiveDirectoryIterator::hasChildren. Ответ относится к текущей позиции и не двигает курсор. hasChildren(false) проверяет текущую запись и запрещает считать символическую ссылку дочерним каталогом. Во второй независимой ситуации: Вторая проверка строит карту первого уровня workspace и снова передаёт false как политику ссылок. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.
| Параметр | Что означает в задаче |
|---|---|
| allowLinks | false запрещает считать ссылку дочерним каталогом; 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(): stringRecursiveDirectoryIterator::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(): voidRecursiveDirectoryIterator::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(): voidRecursiveDirectoryIterator::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(): ?RecursiveFilterIteratorRecursiveFilterIterator::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(): boolRecursiveFilterIterator::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(): voidRecursiveIteratorIterator::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(): voidRecursiveIteratorIterator::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(): ?RecursiveIteratorRecursiveIteratorIterator::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.
<?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.
<?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(): boolRecursiveIteratorIterator::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() активного рекурсивного источника.
<?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: строка не открывает дочерний уровень.
<?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: сначала приходит родитель, затем его содержимое.
<?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 отдаёт листья до родительского узла. Это удобно, когда родительский итог зависит от уже обработанных детей.
<?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(): mixedRecursiveIteratorIterator::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(): voidRecursiveIteratorIterator::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(): voidRecursiveIteratorIterator::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(): intRecursiveIteratorIterator::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(): RecursiveIteratorRecursiveIteratorIterator::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|falseRecursiveIteratorIterator::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): ?RecursiveIteratorRecursiveIteratorIterator::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(): mixedRecursiveIteratorIterator::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(): voidRecursiveIteratorIterator::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(): voidRecursiveIteratorIterator::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(): voidRecursiveIteratorIterator::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): voidRecursiveIteratorIterator::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(): boolRecursiveIteratorIterator::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(). |
| pattern | PCRE-выражение с разделителями. При 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(): RecursiveRegexIteratorRecursiveRegexIterator::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.
<?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.
<?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(): boolRecursiveRegexIterator::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-итератор.
<?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, но наличие детей определяется структурой их значений.
<?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(): voidRecursiveTreeIterator::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(): voidRecursiveTreeIterator::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(): ?RecursiveIteratorRecursiveTreeIterator::callGetChildren. Это явный вызов getChildren() активного источника; обычный foreach делает его сам. callGetChildren() возвращает RecursiveIterator активного parent shop до декоративного форматирования строк. Во второй независимой ситуации: Дочерний источник возвращает исходные ключи cache/debug и значения без префикса дерева. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.
| Параметр | Что означает в задаче |
|---|---|
| Параметров нет | Метод использует текущее состояние объекта; это состояние показано в примере до вызова. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | public function RecursiveTreeIterator::callGetChildren(): ?RecursiveIterator |
| Результат | ?RecursiveIterator: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование. |
| Ошибки и особые значения | TypeError и исключения внутреннего источника не превращаются в пустой результат. Прямой вызов нужен в основном подклассу и диагностике; не рассинхронизируйте внутренний курсор. |
| Версии | Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице |
callGetChildren() возвращает RecursiveIterator активного parent 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 и значения без префикса дерева.
<?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(): boolRecursiveTreeIterator::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.
<?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: строка является конечным значением.
<?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.
<?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(): mixedRecursiveTreeIterator::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(): voidRecursiveTreeIterator::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(): voidRecursiveTreeIterator::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(): stringRecursiveTreeIterator::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, потому что исходное значение — массив.
<?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(): stringRecursiveTreeIterator::getPostfix. Возвращается точная общая строка после entry; по умолчанию она пуста. По умолчанию getPostfix() возвращает пустую строку длины 0. Во второй независимой ситуации: После setPostfix() метод возвращает точную строку с ведущим пробелом. Оба примера начинают с данных задачи и показывают точный результат вызова, а полный официальный контракт ниже сохраняет особые случаи и историю версий.
| Параметр | Что означает в задаче |
|---|---|
| Параметров нет | Метод использует текущее состояние объекта; это состояние показано в примере до вызова. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | public function RecursiveTreeIterator::getPostfix(): string |
| Результат | string: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование. |
| Ошибки и особые значения | TypeError и исключения внутреннего источника не превращаются в пустой результат. Точный тип возврата, особые значения и изменения по версиям перечислены в таблице и полном официальном контракте. |
| Версии | Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице |
По умолчанию getPostfix() возвращает пустую строку длины 0.
<?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(): stringRecursiveTreeIterator::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(): mixedRecursiveTreeIterator::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 без линий дерева.
<?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().
<?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(): voidRecursiveTreeIterator::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(): voidRecursiveTreeIterator::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(): voidRecursiveTreeIterator::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): voidRecursiveTreeIterator::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): voidRecursiveTreeIterator::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 меняет только выбранные части: окончание с соседом и окончание последнего узла.
<?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(): boolRecursiveTreeIterator::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(): mixedDirectoryIterator::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
Инструмент диагностики должен вручную поставить курсор на известный файл, прочитать запись и понять, когда элементы закончились.
<?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 = ''): stringDirectoryIterator::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(): stringDirectoryIterator::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(): stringDirectoryIterator::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
При чтении папки нужно пропустить специальные переходы «эта папка» и «родительская папка», но оставить реальный конфигурационный файл с точкой в начале имени.
<?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(): boolDirectoryIterator::isDot нужен, чтобы распознать специальные записи текущей и родительской папки. В этой задаче DirectoryIterator помогает прочитать записи одной локальной папки и для каждой получить имя, расширение и тип. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.
| Параметр | Что означает в задаче |
|---|---|
| Параметров нет | Метод использует текущее состояние объекта; это состояние показано в примере до вызова. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | public function DirectoryIterator::isDot(): bool |
| Результат | bool: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование. |
| Ошибки и особые значения | TypeError и исключения вложенного источника не скрываются. Особые значения, предупреждения и версии перечислены в полном официальном контракте ниже. |
| Версии | Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице |
При чтении папки нужно пропустить специальные переходы «эта папка» и «родительская папка», но оставить реальный конфигурационный файл с точкой в начале имени.
<?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
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(): mixedDirectoryIterator::key нужен, чтобы получить ключ или позицию текущего элемента. В этой задаче DirectoryIterator помогает прочитать записи одной локальной папки и для каждой получить имя, расширение и тип. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.
| Параметр | Что означает в задаче |
|---|---|
| Параметров нет | Метод использует текущее состояние объекта; это состояние показано в примере до вызова. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | public function DirectoryIterator::key(): mixed |
| Результат | mixed: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование. |
| Ошибки и особые значения | Сначала вызывайте valid(). Ключ может быть int, string или составным массивом и не обязан быть бизнес-идентификатором. |
| Версии | Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице |
Инструмент диагностики должен вручную поставить курсор на известный файл, прочитать запись и понять, когда элементы закончились.
<?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(): voidDirectoryIterator::next нужен, чтобы перевести курсор к следующему элементу. В этой задаче DirectoryIterator помогает прочитать записи одной локальной папки и для каждой получить имя, расширение и тип. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.
| Параметр | Что означает в задаче |
|---|---|
| Параметров нет | Метод использует текущее состояние объекта; это состояние показано в примере до вызова. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | public function DirectoryIterator::next(): void |
| Результат | void: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет. |
| Ошибки и особые значения | Продвижение одноразового источника нельзя отменить. Исключение из вложенного источника передаётся вызывающему коду. |
| Версии | Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице |
Инструмент диагностики должен вручную поставить курсор на известный файл, прочитать запись и понять, когда элементы закончились.
<?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);
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(): voidDirectoryIterator::rewind нужен, чтобы попытаться установить курсор на первый элемент. В этой задаче DirectoryIterator помогает прочитать записи одной локальной папки и для каждой получить имя, расширение и тип. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.
| Параметр | Что означает в задаче |
|---|---|
| Параметров нет | Метод использует текущее состояние объекта; это состояние показано в примере до вызова. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | public function DirectoryIterator::rewind(): void |
| Результат | void: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет. |
| Ошибки и особые значения | Не каждый Traversable можно повторить. NoRewindIterator намеренно игнорирует повторную перемотку, а Generator после завершения может выбросить исключение. |
| Версии | Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице |
Инструмент диагностики должен вручную поставить курсор на известный файл, прочитать запись и понять, когда элементы закончились.
<?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);
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): voidDirectoryIterator::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
Инструмент диагностики должен вручную поставить курсор на известный файл, прочитать запись и понять, когда элементы закончились.
<?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(): stringDirectoryIterator::__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
Инструмент диагностики должен вручную поставить курсор на известный файл, прочитать запись и понять, когда элементы закончились.
<?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(): boolDirectoryIterator::valid нужен, чтобы проверить, указывает ли курсор на существующий элемент. В этой задаче DirectoryIterator помогает прочитать записи одной локальной папки и для каждой получить имя, расширение и тип. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.
| Параметр | Что означает в задаче |
|---|---|
| Параметров нет | Метод использует текущее состояние объекта; это состояние показано в примере до вызова. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | public function DirectoryIterator::valid(): bool |
| Результат | bool: значение возвращается на место вызова; пример показывает его фактическую форму и дальнейшее использование. |
| Ошибки и особые значения | false означает отсутствие текущего элемента, а не ошибку бизнес-данных. Ошибки источника могут возникнуть отдельно. |
| Версии | Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице |
Инструмент диагностики должен вручную поставить курсор на известный файл, прочитать запись и понять, когда элементы закончились.
<?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);
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|stringFilesystemIterator::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
Перед отправкой файлов нужно узнать их размер, не открывая содержимое.
<?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(): intFilesystemIterator::getFlags нужен, чтобы прочитать действующую битовую маску режима объекта. В этой задаче FilesystemIterator помогает обойти одну папку и заранее выбрать, что считать ключом и текущим значением. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.
| Параметр | Что означает в задаче |
|---|---|
| Параметров нет | Метод использует текущее состояние объекта; это состояние показано в примере до вызова. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | public function FilesystemIterator::getFlags(): int |
| Результат | int: полная битовая маска. Режим с нулевой константой, например CURRENT_AS_FILEINFO, проверяют как ($flags & CURRENT_MODE_MASK) === CURRENT_AS_FILEINFO. |
| Ошибки и особые значения | TypeError и исключения вложенного источника не скрываются. Особые значения, предупреждения и версии перечислены в полном официальном контракте ниже. |
| Версии | Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице |
Код меняет форму current(), но должен понимать, почему после небрежной смены режима внезапно появились . и ...
<?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(): stringFilesystemIterator::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(): voidFilesystemIterator::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.
<?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(): voidFilesystemIterator::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): voidFilesystemIterator::setFlags нужен, чтобы заменить действующую битовую маску режима. В этой задаче FilesystemIterator помогает обойти одну папку и заранее выбрать, что считать ключом и текущим значением. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.
| Параметр | Что означает в задаче |
|---|---|
| flags | Битовая маска режима. Оператор | объединяет совместимые константы; setFlags заменяет прежнюю маску целиком. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | public function FilesystemIterator::setFlags(int $flags): void |
| Результат | void: метод изменяет курсор, режим или контейнер; полезного значения на месте вызова нет. |
| Ошибки и особые значения | Метод принимает int и заменяет всю маску. Забытый SKIP_DOTS возвращает . и ..; несовместимая форма current/key ломает ожидания потребителя даже без исключения. |
| Версии | PHP; изменения по версиям перечислены в карточке и официальном источнике (в тексте встречается 8.2) |
Код меняет форму current(), но должен понимать, почему после небрежной смены режима внезапно появились . и ...
<?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 или вложенную папку.
<?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(): intGlobIterator::count нужен, чтобы получить число элементов, которое определяет этот класс. В этой задаче GlobIterator помогает получить только локальные пути, совпавшие с файловой маской, и узнать их число. Вызов относится к конкретному объекту слева от ->; аргументы попадают в параметры сигнатуры, после чего метод либо возвращает значение на место вызова, либо изменяет состояние курсора/объекта.
| Параметр | Что означает в задаче |
|---|---|
| Параметров нет | Метод использует текущее состояние объекта; это состояние показано в примере до вызова. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | public function GlobIterator::count(): int |
| Результат | int: число путей, совпавших с маской. Ноль означает пустой результат, а не автоматически ошибку файловой системы. |
| Ошибки и особые значения | TypeError и исключения вложенного источника не скрываются. Особые значения, предупреждения и версии перечислены в полном официальном контракте ниже. |
| Версии | Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице |
Генератор превью должен взять только JPG непосредственно из uploads и не читать notes.txt или вложенную папку.
<?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 для одинакового вывода.
<?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): SplFileInfogetFileInfo создаёт карточку того же файла, 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|falseInode — идентификатор объекта внутри файловой системы; для глобального сравнения нужен также номер устройства 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|falsegetLinkTarget возвращает текст цели ссылки: он может быть относительным, например receipt.txt. Это не обязательно абсолютный путь. getRealPath отдельно пытается разрешить всю цепочку до существующего объекта.
| Параметр | Что означает в задаче |
|---|---|
| Параметров нет | Метод использует текущее состояние объекта; это состояние показано в примере до вызова. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | public function SplFileInfo::getLinkTarget(): string|false |
| Результат | Строка цели ссылки; в объявленном типе также false. Официальная страница отдельно указывает RuntimeException при ошибке. |
| Ошибки и особые значения | Для не-ссылки или ошибки следуйте официальному договору string|false и RuntimeException; предварительная isLink-проверка делает намерение явным, но не устраняет гонку файловой системы. |
| Версии | Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице |
Проверка isLink защищает ветку getLinkTarget. Для обычного приложенного файла программа не вызывает метод, которому нужна ссылка, и продолжает полезное чтение.
<?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 для одинакового вывода.
<?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): ?SplFileInfogetFileInfo создаёт карточку того же файла, 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|falseisDir проверяет каталог, 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(): boolisDir проверяет каталог, 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(): boolisDir проверяет каталог, 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::isLinkОтличить символическую ссылку от обычного файла до чтения.
Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице · SPL
public function SplFileInfo::isLink(): boolСимволическая ссылка — отдельная запись файловой системы, которая перенаправляет путь к другой записи. isLink отвечает о самой записи пути; isFile может одновременно вернуть true, если ссылка ведёт к обычному файлу. Поэтому политика «ссылки запрещены» начинается именно с isLink, а не с isFile.
| Параметр | Что означает в задаче |
|---|---|
| Параметров нет | Метод использует текущее состояние объекта; это состояние показано в примере до вызова. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | public function SplFileInfo::isLink(): bool |
| Результат | true, если данный путь является символической ссылкой; false для обычного файла, отсутствующего пути или отрицательной проверки. |
| Ошибки и особые значения | Метод возвращает false для отрицательной проверки; предупреждения/ошибки создания ссылки относятся к symlink, а не к isLink. Для подробной причины фактическое открытие и создание обрабатываются отдельно. |
| Версии | Доступно в текущем PHP 8.5.11; исторические изменения указаны по официальной странице |
В архиве receipt.txt — настоящий обычный файл. Условие сначала спрашивает о записи пути, затем чтение отдельно показывает содержимое.
<?php
declare(strict_types=1);
$info = new SplFileInfo(__DIR__ . '/input/receipt.txt');
if ($info->isLink()) {
echo "Документ перенаправлен ссылкой.
";
} else {
echo "Обычный документ: не символическая ссылка.
";
}
echo $info->openFile('rb')->fgets();
Ожидаемый результат
Обычный документ: не символическая ссылка.
Заказ 42
false здесь означает конкретный проверенный факт об приложенном пути, а не ошибку чтения.
Это условный пример для Linux/macOS или Windows с разрешённым созданием symlink. Он действительно вызывает symlink и isLink; при запрете полномочий честно завершается исключением. В текущем Windows-стенде capability-проверка получила 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('Ожидалась ссылка'); }
echo "Ссылка обнаружена.
";
echo $info->openFile('rb')->fgets();
При поддержке первая строка подтверждает ссылку, вторая показывает целевой документ. При запрете среда сообщает об отсутствии полномочий; копия файла не имитирует ссылку.
Полный официальный контракт и история версий (оригинал)
PHP Documentation Group, PHP Manual, CC BY 3.0. Оригинальные нормативные правила сохранены; учебные примеры ниже написаны для этого руководства.
SplFileInfo::isLink
(PHP 5 >= 5.1.2, PHP 7, PHP 8) SplFileInfo::isLink — Tells if the file is a link
Description
public function SplFileInfo::isLink(): bool
Use this method to check if the file referenced by the SplFileInfo object is a link.
Parameters
This function has no parameters.
Return Values
Returns true if the file is a link, false otherwise.
See Also
SplFileInfo::getRealPath() - Gets absolute path to file
Полный маршрут: чтение, 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): SplFileObjectgetFileInfo создаёт карточку того же файла, getPathInfo — родителя. setInfoClass задаёт совместимый подкласс SplFileInfo для этих фабрик; setFileClass — подкласс SplFileObject для openFile. Существующий объект не превращается в другой класс.
| Параметр | Что означает в задаче |
|---|---|
| mode | Режим открытия: rb — чтение; wb — создание с немедленной очисткой; xb — создание только нового; c+b — чтение/запись без очистки; a+b — запись всегда в конец. b сохраняет байтовые смещения на Windows. |
| useIncludePath | false: использовать данный путь. true: дополнительно искать относительное имя в include_path. Здесь файлы задаются через __DIR__, поиск не нужен. |
| context | null — стандартные настройки потока. Для обёртки можно передать ресурс 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'): voidgetFileInfo создаёт карточку того же файла, 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'): voidgetFileInfo создаёт карточку того же файла, 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. |
| useIncludePath | false: использовать данный путь. true: дополнительно искать относительное имя в include_path. Здесь файлы задаются через __DIR__, поиск не нужен. |
| context | null — стандартные настройки потока. Для обёртки можно передать ресурс 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|falsecurrent читает значение текущего элемента итератора; повторный 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] выбирают её поля.
<?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(): booleof отвечает, достигнут ли конец потока; 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. Второй объект моделирует следующую стадию обработки уже сброшенного файла.
<?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(): stringSplFileObject открывает файл и сохраняет позицию чтения. Каждый следующий вызов 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');
Ожидаемый результат
<b>Заказ 42</b> готов.
В 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 позволяет сразу получить отказ вместо ожидания.
| Параметр | Что означает в задаче |
|---|---|
| operation | LOCK_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(): intfpassthru передаёт в вывод все байты от текущей позиции до 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|falsefputcsv принимает массив значений и самостоятельно ставит необходимые кавычки. Результат пригоден для последующего 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 возвращает к началу после записи.
<?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|falsefread запрашивает не больше 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|nullfscanf сопоставляет текст строки с шаблоном. %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): intftell узнаёт позицию, fseek изменяет её. Сохранять смещение удобно после полной записи журнала или CSV: следующий запуск может продолжить с него, если исходный файл не изменён.
| Параметр | Что означает в задаче |
|---|---|
| offset | Смещение в байтах. Отрицательное значение позволяет идти назад относительно SEEK_CUR или SEEK_END. |
| whence | SEEK_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(): arrayfstat возвращает сведения об открытом файле, в отличие от проверки нового пути через 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|falseftell узнаёт позицию, 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): boolftruncate изменяет размер уже открытого записываемого файла. Меньший размер удаляет данные; больший добавляет нулевые байты. Позицию чтения/записи задавайте отдельно.
| Параметр | Что означает в задаче |
|---|---|
| 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|falsefwrite помещает байты в открытый поток. Режим задаёт, куда попадут данные: 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(): nullSplFileObject реализует 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(): arraysetCsvControl задаёт правила последующего чтения: ";", двойную кавычку и явно пустой 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(): stringSplFileObject открывает файл и сохраняет позицию чтения. Каждый следующий вызов 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(): intDROP_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 пропускается.
<?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(): intsetMaxLineLen ограничивает длину чтения строки; 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(): falseSplFileObject реализует 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(): intkey возвращает номер от нуля. Для сообщения человеку прибавляем 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(): voidnext сдвигает курсор итератора на следующий элемент; сам метод ничего не возвращает.
| Параметр | Что означает в задаче |
|---|---|
| Параметров нет | Метод использует текущее состояние объекта; это состояние показано в примере до вызова. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | 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(): voidrewind возвращает к началу. После него первое чтение снова выдаёт заголовок заказа.
| Параметр | Что означает в задаче |
|---|---|
| Параметров нет | Метод использует текущее состояние объекта; это состояние показано в примере до вызова. |
| Часть контракта | Что важно |
|---|---|
| Сигнатура | 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): voidseek(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 = '\\'): voidsetCsvControl задаёт правила последующего чтения: ";", двойную кавычку и явно пустой 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): voidDROP_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 пропускается.
<?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): voidsetMaxLineLen ограничивает длину чтения строки; 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(): stringecho объекта вызывает __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(): booleof отвечает, достигнут ли конец потока; 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. Базовые понятия: массив, цикл, функция, объект.
Источники и обсуждения
- PHP Manual: AppendIterator::append
- PHP Manual: AppendIterator::__construct
- PHP Manual: AppendIterator::current
- PHP Manual: AppendIterator::getArrayIterator
- PHP Manual: AppendIterator::getIteratorIndex
- PHP Manual: AppendIterator::key
- PHP Manual: AppendIterator::next
- PHP Manual: AppendIterator::rewind
- PHP Manual: AppendIterator::valid
- PHP Manual: ArrayIterator::append
- PHP Manual: ArrayIterator::asort
- PHP Manual: ArrayIterator::__construct
- PHP Manual: ArrayIterator::count
- PHP Manual: ArrayIterator::current
- PHP Manual: ArrayIterator::getArrayCopy
- PHP Manual: ArrayIterator::getFlags
- PHP Manual: ArrayIterator::key
- PHP Manual: ArrayIterator::ksort
- PHP Manual: ArrayIterator::natcasesort
- PHP Manual: ArrayIterator::natsort
- PHP Manual: ArrayIterator::next
- PHP Manual: ArrayIterator::offsetExists
- PHP Manual: ArrayIterator::offsetGet
- PHP Manual: ArrayIterator::offsetSet
- PHP Manual: ArrayIterator::offsetUnset
- PHP Manual: ArrayIterator::rewind
- PHP Manual: ArrayIterator::seek
- PHP Manual: ArrayIterator::serialize
- PHP Manual: ArrayIterator::setFlags
- PHP Manual: ArrayIterator::uasort
- PHP Manual: ArrayIterator::uksort
- PHP Manual: ArrayIterator::unserialize
- PHP Manual: ArrayIterator::valid
- PHP Manual: ArrayObject::append
- PHP Manual: ArrayObject::asort
- PHP Manual: ArrayObject::__construct
- PHP Manual: ArrayObject::count
- PHP Manual: ArrayObject::exchangeArray
- PHP Manual: ArrayObject::getArrayCopy
- PHP Manual: ArrayObject::getFlags
- PHP Manual: ArrayObject::getIterator
- PHP Manual: ArrayObject::getIteratorClass
- PHP Manual: ArrayObject::ksort
- PHP Manual: ArrayObject::natcasesort
- PHP Manual: ArrayObject::natsort
- PHP Manual: ArrayObject::offsetExists
- PHP Manual: ArrayObject::offsetGet
- PHP Manual: ArrayObject::offsetSet
- PHP Manual: ArrayObject::offsetUnset
- PHP Manual: ArrayObject::serialize
- PHP Manual: ArrayObject::setFlags
- PHP Manual: ArrayObject::setIteratorClass
- PHP Manual: ArrayObject::uasort
- PHP Manual: ArrayObject::uksort
- PHP Manual: ArrayObject::unserialize
- PHP Manual: Standard PHP Library (SPL)
- PHP Manual: CachingIterator::__construct
- PHP Manual: CachingIterator::count
- PHP Manual: CachingIterator::current
- PHP Manual: CachingIterator::getCache
- PHP Manual: CachingIterator::getFlags
- PHP Manual: CachingIterator::hasNext
- PHP Manual: CachingIterator::key
- PHP Manual: CachingIterator::next
- PHP Manual: CachingIterator::offsetExists
- PHP Manual: CachingIterator::offsetGet
- PHP Manual: CachingIterator::offsetSet
- PHP Manual: CachingIterator::offsetUnset
- PHP Manual: CachingIterator::rewind
- PHP Manual: CachingIterator::setFlags
- PHP Manual: CachingIterator::__toString
- PHP Manual: CachingIterator::valid
- PHP Manual: CallbackFilterIterator::accept
- PHP Manual: CallbackFilterIterator::__construct
- PHP Manual: The AppendIterator class
- PHP Manual: The ArrayIterator class
- PHP Manual: The ArrayObject class
- PHP Manual: The BadFunctionCallException class
- PHP Manual: The BadMethodCallException class
- PHP Manual: The CachingIterator class
- PHP Manual: The CallbackFilterIterator class
- PHP Manual: The DirectoryIterator class
- PHP Manual: The DomainException class
- PHP Manual: The EmptyIterator class
- PHP Manual: The FilesystemIterator class
- PHP Manual: The FilterIterator class
- PHP Manual: The GlobIterator class
- PHP Manual: The InfiniteIterator class
- PHP Manual: The InvalidArgumentException class
- PHP Manual: The IteratorIterator class
- PHP Manual: The LengthException class
- PHP Manual: The LimitIterator class
- PHP Manual: The LogicException class
- PHP Manual: The MultipleIterator class
- PHP Manual: The NoRewindIterator class
- PHP Manual: The OuterIterator interface
- PHP Manual: The OutOfBoundsException class
- PHP Manual: The OutOfRangeException class
- PHP Manual: The OverflowException class
- PHP Manual: The ParentIterator class
- PHP Manual: The RangeException class
- PHP Manual: The RecursiveArrayIterator class
- PHP Manual: The RecursiveCachingIterator class
- PHP Manual: The RecursiveCallbackFilterIterator class
- PHP Manual: The RecursiveDirectoryIterator class
- PHP Manual: The RecursiveFilterIterator class
- PHP Manual: The RecursiveIterator interface
- PHP Manual: The RecursiveIteratorIterator class
- PHP Manual: The RecursiveRegexIterator class
- PHP Manual: The RecursiveTreeIterator class
- PHP Manual: The RegexIterator class
- PHP Manual: The RuntimeException class
- PHP Manual: The SeekableIterator interface
- PHP Manual: The SplDoublyLinkedList class
- PHP Manual: The SplFileInfo class
- PHP Manual: The SplFileObject class
- PHP Manual: The SplFixedArray class
- PHP Manual: The SplHeap class
- PHP Manual: The SplMaxHeap class
- PHP Manual: The SplMinHeap class
- PHP Manual: The SplObjectStorage class
- PHP Manual: The SplObserver interface
- PHP Manual: The SplPriorityQueue class
- PHP Manual: The SplQueue class
- PHP Manual: The SplStack class
- PHP Manual: The SplSubject interface
- PHP Manual: The SplTempFileObject class
- PHP Manual: The UnderflowException class
- PHP Manual: The UnexpectedValueException class
- PHP Manual: DirectoryIterator::__construct
- PHP Manual: DirectoryIterator::current
- PHP Manual: DirectoryIterator::getBasename
- PHP Manual: DirectoryIterator::getExtension
- PHP Manual: DirectoryIterator::getFilename
- PHP Manual: DirectoryIterator::isDot
- PHP Manual: DirectoryIterator::key
- PHP Manual: DirectoryIterator::next
- PHP Manual: DirectoryIterator::rewind
- PHP Manual: DirectoryIterator::seek
- PHP Manual: DirectoryIterator::__toString
- PHP Manual: DirectoryIterator::valid
- PHP Manual: EmptyIterator::current
- PHP Manual: EmptyIterator::key
- PHP Manual: EmptyIterator::next
- PHP Manual: EmptyIterator::rewind
- PHP Manual: EmptyIterator::valid
- PHP Manual: FilesystemIterator::__construct
- PHP Manual: FilesystemIterator::current
- PHP Manual: FilesystemIterator::getFlags
- PHP Manual: FilesystemIterator::key
- PHP Manual: FilesystemIterator::next
- PHP Manual: FilesystemIterator::rewind
- PHP Manual: FilesystemIterator::setFlags
- PHP Manual: FilterIterator::accept
- PHP Manual: FilterIterator::__construct
- PHP Manual: FilterIterator::current
- PHP Manual: FilterIterator::key
- PHP Manual: FilterIterator::next
- PHP Manual: FilterIterator::rewind
- PHP Manual: FilterIterator::valid
- PHP Manual: class_implements
- PHP Manual: class_parents
- PHP Manual: class_uses
- PHP Manual: iterator_apply
- PHP Manual: iterator_count
- PHP Manual: iterator_to_array
- PHP Manual: spl_autoload
- PHP Manual: spl_autoload_call
- PHP Manual: spl_autoload_extensions
- PHP Manual: spl_autoload_functions
- PHP Manual: spl_autoload_register
- PHP Manual: spl_autoload_unregister
- PHP Manual: spl_classes
- PHP Manual: spl_object_hash
- PHP Manual: spl_object_id
- PHP Manual: GlobIterator::__construct
- PHP Manual: GlobIterator::count
- PHP Manual: InfiniteIterator::__construct
- PHP Manual: InfiniteIterator::next
- PHP Manual: IteratorIterator::__construct
- PHP Manual: IteratorIterator::current
- PHP Manual: IteratorIterator::getInnerIterator
- PHP Manual: IteratorIterator::key
- PHP Manual: IteratorIterator::next
- PHP Manual: IteratorIterator::rewind
- PHP Manual: IteratorIterator::valid
- PHP Manual: LimitIterator::__construct
- PHP Manual: LimitIterator::current
- PHP Manual: LimitIterator::getPosition
- PHP Manual: LimitIterator::key
- PHP Manual: LimitIterator::next
- PHP Manual: LimitIterator::rewind
- PHP Manual: LimitIterator::seek
- PHP Manual: LimitIterator::valid
- PHP Manual: MultipleIterator::attachIterator
- PHP Manual: MultipleIterator::__construct
- PHP Manual: MultipleIterator::containsIterator
- PHP Manual: MultipleIterator::countIterators
- PHP Manual: MultipleIterator::current
- PHP Manual: MultipleIterator::detachIterator
- PHP Manual: MultipleIterator::getFlags
- PHP Manual: MultipleIterator::key
- PHP Manual: MultipleIterator::next
- PHP Manual: MultipleIterator::rewind
- PHP Manual: MultipleIterator::setFlags
- PHP Manual: MultipleIterator::valid
- PHP Manual: NoRewindIterator::__construct
- PHP Manual: NoRewindIterator::current
- PHP Manual: NoRewindIterator::key
- PHP Manual: NoRewindIterator::next
- PHP Manual: NoRewindIterator::rewind
- PHP Manual: NoRewindIterator::valid
- PHP Manual: OuterIterator::getInnerIterator
- PHP Manual: ParentIterator::accept
- PHP Manual: ParentIterator::__construct
- PHP Manual: ParentIterator::getChildren
- PHP Manual: ParentIterator::hasChildren
- PHP Manual: ParentIterator::next
- PHP Manual: ParentIterator::rewind
- PHP Manual: RecursiveArrayIterator::getChildren
- PHP Manual: RecursiveArrayIterator::hasChildren
- PHP Manual: RecursiveCachingIterator::__construct
- PHP Manual: RecursiveCachingIterator::getChildren
- PHP Manual: RecursiveCachingIterator::hasChildren
- PHP Manual: RecursiveCallbackFilterIterator::__construct
- PHP Manual: RecursiveCallbackFilterIterator::getChildren
- PHP Manual: RecursiveCallbackFilterIterator::hasChildren
- PHP Manual: RecursiveDirectoryIterator::__construct
- PHP Manual: RecursiveDirectoryIterator::getChildren
- PHP Manual: RecursiveDirectoryIterator::getSubPath
- PHP Manual: RecursiveDirectoryIterator::getSubPathname
- PHP Manual: RecursiveDirectoryIterator::hasChildren
- PHP Manual: RecursiveDirectoryIterator::key
- PHP Manual: RecursiveDirectoryIterator::next
- PHP Manual: RecursiveDirectoryIterator::rewind
- PHP Manual: RecursiveFilterIterator::__construct
- PHP Manual: RecursiveFilterIterator::getChildren
- PHP Manual: RecursiveFilterIterator::hasChildren
- PHP Manual: RecursiveIterator::getChildren
- PHP Manual: RecursiveIterator::hasChildren
- PHP Manual: RecursiveIteratorIterator::beginChildren
- PHP Manual: RecursiveIteratorIterator::beginIteration
- PHP Manual: RecursiveIteratorIterator::callGetChildren
- PHP Manual: RecursiveIteratorIterator::callHasChildren
- PHP Manual: RecursiveIteratorIterator::__construct
- PHP Manual: RecursiveIteratorIterator::current
- PHP Manual: RecursiveIteratorIterator::endChildren
- PHP Manual: RecursiveIteratorIterator::endIteration
- PHP Manual: RecursiveIteratorIterator::getDepth
- PHP Manual: RecursiveIteratorIterator::getInnerIterator
- PHP Manual: RecursiveIteratorIterator::getMaxDepth
- PHP Manual: RecursiveIteratorIterator::getSubIterator
- PHP Manual: RecursiveIteratorIterator::key
- PHP Manual: RecursiveIteratorIterator::next
- PHP Manual: RecursiveIteratorIterator::nextElement
- PHP Manual: RecursiveIteratorIterator::rewind
- PHP Manual: RecursiveIteratorIterator::setMaxDepth
- PHP Manual: RecursiveIteratorIterator::valid
- PHP Manual: RecursiveRegexIterator::__construct
- PHP Manual: RecursiveRegexIterator::getChildren
- PHP Manual: RecursiveRegexIterator::hasChildren
- PHP Manual: RecursiveTreeIterator::beginChildren
- PHP Manual: RecursiveTreeIterator::beginIteration
- PHP Manual: RecursiveTreeIterator::callGetChildren
- PHP Manual: RecursiveTreeIterator::callHasChildren
- PHP Manual: RecursiveTreeIterator::__construct
- PHP Manual: RecursiveTreeIterator::current
- PHP Manual: RecursiveTreeIterator::endChildren
- PHP Manual: RecursiveTreeIterator::endIteration
- PHP Manual: RecursiveTreeIterator::getEntry
- PHP Manual: RecursiveTreeIterator::getPostfix
- PHP Manual: RecursiveTreeIterator::getPrefix
- PHP Manual: RecursiveTreeIterator::key
- PHP Manual: RecursiveTreeIterator::next
- PHP Manual: RecursiveTreeIterator::nextElement
- PHP Manual: RecursiveTreeIterator::rewind
- PHP Manual: RecursiveTreeIterator::setPostfix
- PHP Manual: RecursiveTreeIterator::setPrefixPart
- PHP Manual: RecursiveTreeIterator::valid
- PHP Manual: SPL Functions
- PHP Manual: RegexIterator::accept
- PHP Manual: RegexIterator::__construct
- PHP Manual: RegexIterator::getFlags
- PHP Manual: RegexIterator::getMode
- PHP Manual: RegexIterator::getPregFlags
- PHP Manual: RegexIterator::getRegex
- PHP Manual: RegexIterator::setFlags
- PHP Manual: RegexIterator::setMode
- PHP Manual: RegexIterator::setPregFlags
- PHP Manual: SeekableIterator::seek
- PHP Manual: Datastructures
- PHP Manual: Exceptions
- PHP Manual: File Handling
- PHP Manual: Interfaces
- PHP Manual: Iterators
- PHP Manual: SplDoublyLinkedList::add
- PHP Manual: SplDoublyLinkedList::bottom
- PHP Manual: SplDoublyLinkedList::count
- PHP Manual: SplDoublyLinkedList::current
- PHP Manual: SplDoublyLinkedList::getIteratorMode
- PHP Manual: SplDoublyLinkedList::isEmpty
- PHP Manual: SplDoublyLinkedList::key
- PHP Manual: SplDoublyLinkedList::next
- PHP Manual: SplDoublyLinkedList::offsetExists
- PHP Manual: SplDoublyLinkedList::offsetGet
- PHP Manual: SplDoublyLinkedList::offsetSet
- PHP Manual: SplDoublyLinkedList::offsetUnset
- PHP Manual: SplDoublyLinkedList::pop
- PHP Manual: SplDoublyLinkedList::prev
- PHP Manual: SplDoublyLinkedList::push
- PHP Manual: SplDoublyLinkedList::rewind
- PHP Manual: SplDoublyLinkedList::serialize
- PHP Manual: SplDoublyLinkedList::setIteratorMode
- PHP Manual: SplDoublyLinkedList::shift
- PHP Manual: SplDoublyLinkedList::top
- PHP Manual: SplDoublyLinkedList::unserialize
- PHP Manual: SplDoublyLinkedList::unshift
- PHP Manual: SplDoublyLinkedList::valid
- PHP Manual: SplFileInfo::__construct
- PHP Manual: SplFileInfo::getATime
- PHP Manual: SplFileInfo::getBasename
- PHP Manual: SplFileInfo::getCTime
- PHP Manual: SplFileInfo::getExtension
- PHP Manual: SplFileInfo::getFileInfo
- PHP Manual: SplFileInfo::getFilename
- PHP Manual: SplFileInfo::getGroup
- PHP Manual: SplFileInfo::getInode
- PHP Manual: SplFileInfo::getLinkTarget
- PHP Manual: SplFileInfo::getMTime
- PHP Manual: SplFileInfo::getOwner
- PHP Manual: SplFileInfo::getPath
- PHP Manual: SplFileInfo::getPathInfo
- PHP Manual: SplFileInfo::getPathname
- PHP Manual: SplFileInfo::getPerms
- PHP Manual: SplFileInfo::getRealPath
- PHP Manual: SplFileInfo::getSize
- PHP Manual: SplFileInfo::getType
- PHP Manual: SplFileInfo::isDir
- PHP Manual: SplFileInfo::isExecutable
- PHP Manual: SplFileInfo::isFile
- PHP Manual: SplFileInfo::isLink
- PHP Manual: SplFileInfo::isReadable
- PHP Manual: SplFileInfo::isWritable
- PHP Manual: SplFileInfo::openFile
- PHP Manual: SplFileInfo::setFileClass
- PHP Manual: SplFileInfo::setInfoClass
- PHP Manual: SplFileInfo::__toString
- PHP Manual: SplFileObject::__construct
- PHP Manual: SplFileObject::current
- PHP Manual: SplFileObject::eof
- PHP Manual: SplFileObject::fflush
- PHP Manual: SplFileObject::fgetc
- PHP Manual: SplFileObject::fgetcsv
- PHP Manual: SplFileObject::fgets
- PHP Manual: SplFileObject::fgetss
- PHP Manual: SplFileObject::flock
- PHP Manual: SplFileObject::fpassthru
- PHP Manual: SplFileObject::fputcsv
- PHP Manual: SplFileObject::fread
- PHP Manual: SplFileObject::fscanf
- PHP Manual: SplFileObject::fseek
- PHP Manual: SplFileObject::fstat
- PHP Manual: SplFileObject::ftell
- PHP Manual: SplFileObject::ftruncate
- PHP Manual: SplFileObject::fwrite
- PHP Manual: SplFileObject::getChildren
- PHP Manual: SplFileObject::getCsvControl
- PHP Manual: SplFileObject::getCurrentLine
- PHP Manual: SplFileObject::getFlags
- PHP Manual: SplFileObject::getMaxLineLen
- PHP Manual: SplFileObject::hasChildren
- PHP Manual: SplFileObject::key
- PHP Manual: SplFileObject::next
- PHP Manual: SplFileObject::rewind
- PHP Manual: SplFileObject::seek
- PHP Manual: SplFileObject::setCsvControl
- PHP Manual: SplFileObject::setFlags
- PHP Manual: SplFileObject::setMaxLineLen
- PHP Manual: SplFileObject::__toString
- PHP Manual: SplFileObject::valid
- PHP Manual: SplFixedArray::__construct
- PHP Manual: SplFixedArray::count
- PHP Manual: SplFixedArray::current
- PHP Manual: SplFixedArray::fromArray
- PHP Manual: SplFixedArray::getIterator
- PHP Manual: SplFixedArray::getSize
- PHP Manual: SplFixedArray::jsonSerialize
- PHP Manual: SplFixedArray::key
- PHP Manual: SplFixedArray::next
- PHP Manual: SplFixedArray::offsetExists
- PHP Manual: SplFixedArray::offsetGet
- PHP Manual: SplFixedArray::offsetSet
- PHP Manual: SplFixedArray::offsetUnset
- PHP Manual: SplFixedArray::rewind
- PHP Manual: SplFixedArray::__serialize
- PHP Manual: SplFixedArray::setSize
- PHP Manual: SplFixedArray::toArray
- PHP Manual: SplFixedArray::__unserialize
- PHP Manual: SplFixedArray::valid
- PHP Manual: SplFixedArray::__wakeup
- PHP Manual: SplHeap::compare
- PHP Manual: SplHeap::count
- PHP Manual: SplHeap::current
- PHP Manual: SplHeap::extract
- PHP Manual: SplHeap::insert
- PHP Manual: SplHeap::isCorrupted
- PHP Manual: SplHeap::isEmpty
- PHP Manual: SplHeap::key
- PHP Manual: SplHeap::next
- PHP Manual: SplHeap::recoverFromCorruption
- PHP Manual: SplHeap::rewind
- PHP Manual: SplHeap::top
- PHP Manual: SplHeap::valid
- PHP Manual: SplMaxHeap::compare
- PHP Manual: SplMinHeap::compare
- PHP Manual: SplObjectStorage::addAll
- PHP Manual: SplObjectStorage::attach
- PHP Manual: SplObjectStorage::contains
- PHP Manual: SplObjectStorage::count
- PHP Manual: SplObjectStorage::current
- PHP Manual: SplObjectStorage::detach
- PHP Manual: SplObjectStorage::getHash
- PHP Manual: SplObjectStorage::getInfo
- PHP Manual: SplObjectStorage::key
- PHP Manual: SplObjectStorage::next
- PHP Manual: SplObjectStorage::offsetExists
- PHP Manual: SplObjectStorage::offsetGet
- PHP Manual: SplObjectStorage::offsetSet
- PHP Manual: SplObjectStorage::offsetUnset
- PHP Manual: SplObjectStorage::removeAll
- PHP Manual: SplObjectStorage::removeAllExcept
- PHP Manual: SplObjectStorage::rewind
- PHP Manual: SplObjectStorage::seek
- PHP Manual: SplObjectStorage::serialize
- PHP Manual: SplObjectStorage::setInfo
- PHP Manual: SplObjectStorage::unserialize
- PHP Manual: SplObjectStorage::valid
- PHP Manual: SplObserver::update
- PHP Manual: SplPriorityQueue::compare
- PHP Manual: SplPriorityQueue::count
- PHP Manual: SplPriorityQueue::current
- PHP Manual: SplPriorityQueue::extract
- PHP Manual: SplPriorityQueue::getExtractFlags
- PHP Manual: SplPriorityQueue::insert
- PHP Manual: SplPriorityQueue::isCorrupted
- PHP Manual: SplPriorityQueue::isEmpty
- PHP Manual: SplPriorityQueue::key
- PHP Manual: SplPriorityQueue::next
- PHP Manual: SplPriorityQueue::recoverFromCorruption
- PHP Manual: SplPriorityQueue::rewind
- PHP Manual: SplPriorityQueue::setExtractFlags
- PHP Manual: SplPriorityQueue::top
- PHP Manual: SplPriorityQueue::valid
- PHP Manual: SplQueue::dequeue
- PHP Manual: SplQueue::enqueue
- PHP Manual: SplSubject::attach
- PHP Manual: SplSubject::detach
- PHP Manual: SplSubject::notify
- PHP Manual: SplTempFileObject::__construct
Код и руководство с собой
Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.
Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.
Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.


