Самоучитель: PHP под капотом: runtime и стандартная библиотека
Глава 11 из 20IV. Потоки и протоколы120 минут

Глава 11. Streams, wrappers и filters без чтения всего файла

Stream унифицирует последовательный ввод, но wrapper задаёт доверие и возможности; универсальный API не делает удалённый ресурс локальным и безопасным.

После главы вы сможете
  • работать с stream resource
  • ограничивать wrapper
  • проектировать backpressure

Ресурс как открытое обязательство

fopen возвращает resource, который несёт позицию, режим и связь с внешней системой. Pulse читает строку через fgets, проверяет длину до JSON decode и закрывает handle в finally. Если открытие не удалось, дальнейший код не притворяется, что получил пустой файл.

feof отвечает осмысленно после попытки чтения. Цикл строится вокруг результата fgets, иначе последняя строка без перевода или ошибка могут быть обработаны неверно.

Потоковая граница

Ограниченное чтениеДо чтения известны разрешённая схема, лимиты и политика ошибки; ресурс закрывается на всех маршрутах.WrapperschemeContextoptionsResourceopenReadboundedFilterexplicitClosefinally
До чтения известны разрешённая схема, лимиты и политика ошибки; ресурс закрывается на всех маршрутах.

Wrapper определяет угрозу

file://, php://memory и https:// используют похожий API, но имеют разные риски. Пользователь не выбирает произвольную схему. Внутренние php://filter и data:// способны изменить прочитанные данные и не должны становиться способом обхода allowlist путей.

allow_url_fopen не является разрешением бизнес-логики принимать любой URL. Удалённое чтение требует отдельного клиента, timeout, ограничения ответа, проверки redirect и защиты от SSRF.

Context и metadata

Stream context настраивает транспорт до открытия. После операции stream_get_meta_data показывает timeout, blocking mode и URI, но не заменяет проверку кода протокола. Для socket задаются connect и read budgets, а partial read считается нормальной возможностью.

Pulse сохраняет только безопасную диагностическую часть metadata. URI с query может содержать токен и не попадает в журнал без очистки.

Filters и backpressure

Filter преобразует поток порциями: например, меняет кодировку заранее известного источника. Он не должен молча исправлять повреждённые данные. Версия преобразования и число замен становятся частью отчёта.

Backpressure означает, что producer не заполняет память быстрее consumer. В синхронном Pulse это достигается чтением следующей строки только после обработки текущей и ограниченным batch flush.

Лаборатория

Прочитайте NDJSON из php://temp и обычного файла одним EventStream. Запретите переданный data:// URI, ограничьте строку 64 КБ и смоделируйте ошибку чтения.

  • Wrapper выбирается конфигурацией, не пользователем.
  • Handle закрывается в finally.
  • Частичная или слишком длинная строка имеет отдельную причину.
Локальный прогресс

Закрепите материал

Отметка, заметка, чек-лист и ответы остаются в localStorage этого браузера и не отправляются в аналитику.

Контрольная карта лаборатории

Выполнено: 0 из 3

Локальный тест

1. Делает ли общий stream API все wrappers одинаково безопасными?
2. Как ограничить память при чтении большого файла?

Перелинковка со справочником

Проверка актуальности

  • php.nethttps://www.php.net/manual/en/book.stream.phpПервичный источник для актуализации фактов. Адрес приведён как текст и не является активной ссылкой.
  • php.nethttps://www.php.net/manual/en/book.filesystem.phpПервичный источник для актуализации фактов. Адрес приведён как текст и не является активной ссылкой.

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

Данные этого сервиса

Настройки cookie и локальных данных

Аналитика

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

Локальные данные

Удаление затрагивает только ключи PHP-сервиса в этом браузере и требует подтверждения.

Политики

Политика конфиденциальности · Политика использования файлов cookie