Полный цикл в digital

Что такое потоки

В программировании постоянно приходиться работать с различными ресурсами: файлами, сокетами, http-соединениями. У всех есть некий интерфейс доступа, часто несовместимый друг с другом, чтобы устранить данные несоответствия и унифицировать работу с различными источниками данных, начиная с PHP 4.3 были придуманы PHP Streams потоки.

Поток, это передача данных между местами. В данном контексте, местом может быть - файл, ZIP-архив, соединение и даже процесс через командную строку.

Вы должны понимать разницу между открытием файла и открытием веб-страницы, у них обоих есть контент, но это два совершенно разных типа потоковых данных, поэтому для них требуются разные протоколы. Например, мы можем открыть веб-страницу, подключившись к удаленным веб-серверам с помощью HTTP, HTTPS, SSL. Эти протоколы называются потоковыми оболочками, они предоставляют уникальный интерфейс.

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

Обертка wrapper, дополнительный код который объясняет потоку особенности работы со специфичными протоколами или кодировками. Например, обертка http знает, как преобразовать URL в HTTP/1.0-запрос для файла на удаленном сервере. Существует множество оберток, как встроенных в PHP изначально, так и дополнительных.

Схема формирования потока

Каждый поток формируется из схемы и цели, в приведенном ниже формате:

схема://цель

Схема это название обертки. Например - file, http, https, ftp, ftps, compress.zlib, compress.bz2, php. На случай, если название обертки не указать, каждая функция, работающая с потоком, имеет свои умолчания, обычно это file://.

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

Поддерживаемые схемы

  • 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:// потоки для взаимодействия с процессами

Потоки PHP

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

Потоки PHP имеют функции, которые помогают разработчикам управлять различными ресурсами:

  • fopen()
  • fwrite()
  • fgets()
  • file_get_contents()

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.

Дополнительные обертки

Дополнительные обертки можно добавлять либо отдельным скриптом с помощью функции stream_wrapper_register(), либо напрямую из расширения, используя API Working with streams. Добавлять можно произвольное количество оберток, что делает возможности работы с потоками практически безграничными. Посмотреть список зарегистрированных на данный момент оберток можно с помощью функции stream_get_wrappers().

stream_wrapper_register() регистрирует обёртку URL, реализованную в виде PHP-класса, bool stream_wrapper_register ( string $protocol , string $classname [, int $flags = 0 ] ).

Позволяет реализовать собственные обработчики протоколов и потоков для использования со всеми другими функциями файловой системы, такими как fopen(), fread().

<?
$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
"
*/

Модуль CLI SAPI

Модуль CLI SAPI определяет несколько констант для потоков ввода/вывода для упрощения работы с командной строкой.

Константы, специфичные для модуля CLI SAPI:

  • STDIN уже открытый поток ввода stdin. Он предотвращает необходимость его открывать через fopen('php://stdin', 'r');
  • STDOUT уже открытый поток вывода stdout. Он предотвращает необходимость его открывать через $stdout = fopen('php://stdout', 'w');
  • STDERR уже открытый поток ошибок stderr. Он предотвращает необходимость его открывать через $stderr = fopen('php://stderr', 'w');
Заполните форму уже сегодня!
Для начала сотрудничества необходимо заполнить заявку или заказать обратный звонок. В ответ получите коммерческое предложение, которое будет содержать индивидуальную стратегию с учетом требований и поставленных задач
Работаем по будням с 9:00 до 18:00. Заявки, отправленные в выходные, обрабатываем в первый рабочий день до 12:00.
Спасибо, ваш запрос принят и будет обработан!
Эйч Маркетинг