Потоки
Потоки были впервые введены в PHP 4.3.0, как инструмент для работы с файлами, сетевого обмена, сжатия данных и выполнения других операций с помощью одного общего набора функций. Выражаясь простыми понятиями, поток (stream) - это ресурс (resource), который ведет себя, как источник непрерывной последовательности данных. То есть из потока можно последовательно читать данные, равно как и записывать в него. Также возможно перемещаться (fseek()) в разные позиции внутри потока.
Обертка (wrapper) - дополнительный код, который объясняет потоку особенности работы со специфичными протоколами или кодировками. Например, обертка http знает, как преобразовать URL в HTTP/1.0-запрос для файла на удаленном сервере. Существует множество оберток, как встроенных в PHP изначально, так и дополнительных. Дополнительные обертки можно добавлять либо отдельным скриптом с помощью функции stream_wrapper_register(), либо напрямую из расширения, используя API Working with streams. Добавлять можно произвольное количество оберток, что делает возможности работы с потоками практически безграничными. Посмотреть список зарегистрированных на данный момент оберток можно с помощью функции stream_get_wrappers().
Ссылка на поток записывается в следующем виде: scheme://target
scheme(строка) - Название обертки. Например, file, http, https, ftp, ftps, compress.zlib, compress.bz2, php. На случай, если название обертки не указать, каждая функция, работающая с потоком, имеет свои умолчания (обычно это file://). target - Зависит от того, какая обертка используется. Для потоков связанных с файловой системой это обычно путь и имя файла. Для сетевых потоков это, как правило, имя хоста (зачастую с добавлением к нему пути).
Поддерживаемые протоколы и обработчики (wrappers)
Замечание: URL синтаксис, используемый для описания обработчика, может быть только вида scheme://.... Варианты синтаксиса scheme:/ и scheme: не поддерживаются.
Схема | Описание |
---|---|
file:// | Доступ к локальной файловой системе |
http:// | Доступ к URL-адресам по протоколу HTTP(s) |
ftp:// | Доступ к URL-адресам по протоколу FTP(s) |
php:// | Доступ к различным потокам ввода-вывода |
zlib:// | Сжатые потоки |
data:// | Схема Data (RFC 2397) |
glob:// | Нахождение путей, соответствующих шаблону |
phar:// | PHP архив |
ssh2:// | Secure Shell 2 |
rar:// | RAR |
ogg:// | Аудио потоки |
expect:// | Потоки для взаимодействия с процессами |
stream_wrapper_register
Регистрирует обёртку URL, реализованную в виде PHP-класса. bool stream_wrapper_register ( string $protocol , string $classname [, int $flags = 0 ] )
- Позволяет реализовать собственные обработчики протоколов и потоков для использования со всеми другими функциями файловой системы (такими, как fopen(), fread() и т. д.).
<?php
$existed = in_array("var", stream_get_wrappers());
if ($existed) {
stream_wrapper_unregister("var");
}
stream_wrapper_register("var", "VariableStream");
$myvar = "";
$fp = fopen("var://myvar", "r+");
fwrite($fp, "line1\n");
fwrite($fp, "line2\n");
fwrite($fp, "line3\n");
rewind($fp);
while (!feof($fp)) {
echo fgets($fp);
}
fclose($fp);
var_dump($myvar);
if ($existed) {
stream_wrapper_restore("var");
}
/*
line1
line2
line3
string(18) "line1
line2
line3
"
*/
?>
php://
Описание
PHP предоставляет несколько разнообразных потоков ввода-вывода, которые позволяют получить доступ к собственным потокам ввода-вывода PHP,к дескрипторам стандартного ввода, вывода и потока ошибок, к временным файловым потокам в памяти и на диске, и фильтрам, которые могут манипулировать другими файловыми ресурсами по мере их считывания или записи.
php://stdin, php://stdout и php://stderr
php://stdin, php://stdout и php://stderr позволяют получить прямой доступ к соответствующим потокам ввода или вывода процесса PHP. Поток указывает на копию файлового дескриптора, таким образом, если вы откроете php://stdin и потом закроете его, вы закроете только вашу копию дескриптора. Актуальный поток, на который ссылается STDIN остается неизменным. Обратите внимание, что PHP демонстрировал ошибочное поведение в этом отношении до версии PHP 5.2.1. Рекомендуется просто использовать константы STDIN, STDOUT и STDERR вместо ручного открытия потоков, используя эти обертки.
Поток php://stdin предназначен только для чтения, тогда как php://stdout и php://stderr предназначены только для записи.
php://input
php://input является потоком только для чтения, который позволяет вам читать необработанные данные из тела запроса. В случае POST-запросов предпочтительней использовать php://input вместо $HTTP_RAW_POST_DATA, так как этот метод не зависит от специальных php.ini директив. Кроме того, в тех случаях, где $HTTP_RAW_POST_DATA не заполняется по умолчанию, это потенциально менее затратно для памяти, чем активация директивы always_populate_raw_post_data. php://input не доступен с типом содержимого enctype="multipart/form-data".
Замечание: До версии PHP 5.6, поток, открытый с php://input может быть прочтен только один раз. Поток не поддерживает операции поиска. Тем не менее, в зависимости от реализации SAPI интерфейса, может быть возможно открыть другой поток php://input и повторить чтение. Это возможно только если тело запроса заранее сохраняется. Это типично для случая с POST-запросом, но не для других методов запросов, таких как PUT или PROPFIND.
php://output
php://output является потоком только для записи, который позволяет вам записать данные в выходной буфер аналогично как это делают функции print и echo.
Потоки ввода/вывода
Модуль CLI SAPI определяет несколько констант для потоков ввода/вывода для упрощения работы с командной строкой.
Константы, специфичные для модуля CLI
Константа | Описание |
---|---|
STDIN | Уже открытый поток ввода (stdin). Он предотвращает необходимость его открывать через fopen('php://stdin', 'r');. |
STDOUT | Уже открытый поток вывода (stdout). Он предотвращает необходимость его открывать через $stdout = fopen('php://stdout', 'w'); |
STDERR | Уже открытый поток ошибок (stderr). Он предотвращает необходимость его открывать через $stderr = fopen('php://stderr', 'w'); |