Php поток ввода вывода

Php поток ввода вывода

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://output

php://output является потоком только для записи, который позволяет вам записать данные в выходной буфер аналогично, как это делают функции print и echo .

Читайте также:  Print 2 20 python результат

php://fd

php://fd предоставляет прямой доступ к указанному файловому дескриптору. Например, php://fd/3 относится к файловому дескриптору 3.

php://memory и php://temp

php://memory и php://temp являются потоками для чтения/записи и позволяют сохранять временные данные в файлоподобной обертке. Единственная разница между ними заключается в том, что php://memory будет всегда хранить данные в оперативной памяти, тогда как php://temp будет использовать временный файл в том случае, когда объем хранимой информации достигнет заданного лимита (по умолчанию 2 Мб). Расположение этого временного файла определяется аналогично функции sys_get_temp_dir() .

Размер лимита для php://temp может устанавливаться путем добавления /maxmemory:NN , где NN — это максимальный размер данных в байтах для хранения в памяти перед использованием временного файла.

php://filter

php://filter — это вид мета-обертки, предназначенный для разрешения применения фильтров к потоку во время открытия. Это полезно для функционально полных файловых функций, таких как readfile() , file() и file_get_contents() , где нет возможности применить фильтр к потоку до того, как содержимое будет прочитано.

Поток php://filter принимает следующие параметры как часть своего пути. В одном пути можно указать несколько цепочек фильтров. Пожалуйста, ознакомьтесь с примерами и особенностями при использовании этих параметров.

Параметры для php://filter

Название Описание
resource= Этот параметр является необходимым. Он указывает потоку, что его необходимо отфильтровать.
read= Этот параметр является необязательным. Одно или несколько имен фильтров может быть указано здесь, разделенных вертикальной чертой ( | ).
write= Этот параметр является необязательным. Одно или несколько имен фильтров может быть указано здесь, разделенных вертикальной чертой ( | ).
Любой список фильтров, которые используются без префиксов read= или write= , будет применен к обоим потокам на чтение и на запись при необходимости.

Опции

Основная информация (для php://filter смотрите информацию по обертке, которая подвергается фильтрации)

Атрибут Поддержка
Ограничение по allow_url_fopen Нет
Ограничение по allow_url_include только php://input , php://stdin , php://memory и php://temp .
Чтение только php://stdin , php://input , php://fd , php://memory и php://temp .
Запись только php://stdout , php://stderr , php://output , php://fd , php://memory и php://temp .
Добавление только php://stdout , php://stderr , php://output , php://fd , php://memory и php://temp . (Эквивалентно записи)
Одновременное чтение и запись только php://fd , php://memory и php://temp .
Поддержка stat() нет. Тем не менее, php://memory и php://temp поддерживают fstat() .
Поддержка unlink() Нет
Поддержка rename() Нет
Поддержка mkdir() Нет
Поддержка rmdir() Нет
Поддержка stream_select() только php://stdin , php://stdout , php://stderr , php://fd и php://temp .

Примеры

Пример #1 php://temp/maxmemory

Этот необязательный параметр позволяет установить лимит памяти до того, как php://temp начнет использовать временный файл.

// Установка предела в 5 MB.
$fiveMBs = 5 * 1024 * 1024 ;
$fp = fopen ( «php://temp/maxmemory: $fiveMBs » , ‘r+’ );

// Читаем то, что мы записали.
rewind ( $fp );
echo stream_get_contents ( $fp );
?>

Пример #2 php://filter/resource=

Этот параметр должен быть расположен в конце вашей спецификации php://filter и должен указывать на поток, который вы хотите фильтровать.

/* Это просто эквивалентно:
readfile(«http://www.example.com»);
так как на самом деле фильтры не указаны */

Пример #3 php://filter/read=

Этот параметр принимает один или более имен фильтров, разделенных вертикальной чертой | .

/* Этот скрипт выведет содержимое
www.example.com полностью в верхнем регистре */
readfile ( «php://filter/read=string.toupper/resource=http://www.example.com» );

/* Этот скрипт делает тоже самое, что вверхний, но
будет также кодировать алгоритмом ROT13 */
readfile ( «php://filter/read=string.toupper|string.rot13/resource=http://www.example.com» );
?>

Пример #4 php://filter/write=

Этот параметр принимает один или более имен фильтров, разделенных вертикальной чертой | .

/* Этот скрипт будет фильтровать строку «Hello World»
через фильтр rot13, затем записывать результат в
файл example.txt в текущей директории */
file_put_contents ( «php://filter/write=string.rot13/resource=example.txt» , «Hello World» );
?>

Пример #5 php://memory и php://temp нельзя переиспользовать

php://memory и php://temp нельзя переиспользовать, то есть после закрытия потоков невозможно сослаться на них снова.

file_put_contents(‘php://memory’, ‘PHP’);
echo file_get_contents(‘php://memory’); // ничего не напечатает

Источник

Php поток ввода вывода

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

Уже открытый поток ввода ( stdin ). Это предотвращает необходимость его открывать следующим способом:

$line = trim ( fgets ( STDIN )); // читает одну строку из STDIN
fscanf ( STDIN , «%d\n» , $number ); // читает число из STDIN
?>

Уже открытый поток вывода ( stdout ). Это предотвращает необходимость его открывать следующим способом:

Уже открытый поток ошибок ( stderr ). Это предотвращает необходимость его открывать следующим способом:

Учитывая вышесказанное, нет необходимости самому открывать поток, например, stderr , а можно просто использовать уже определённую константу ресурса потока:

php -r 'fwrite(STDERR, "stderr\n");'

Вам не нужно явно закрывать эти потоки, они будут закрыты PHP автоматически при окончании вашего скрипта.

Замечание:

Эти константы недоступны, если считывается PHP-скрипт из stdin .

User Contributed Notes 5 notes

Please remember in multi-process applications (which are best suited under CLI), that I/O operations often will BLOCK signals from being processed.

For instance, if you have a parent waiting on fread(STDIN), it won’t handle SIGCHLD, even if you defined a signal handler for it, until after the call to fread has returned.

Your solution in this case is to wait on stream_select() to find out whether reading will block. Waiting on stream_select(), critically, does NOT BLOCK signals from being processed.

Under Linux CLI — STDIN, STDOUT and STDERR can be closed and reconnected to a different php stream such as a file, pipe or even a UDP socket_stream. (I use this technique to send the output/errors of my long running background scripts to a file so I can debug if something goes wrong.)

For example: (The below creates/appends file «/tmp/php_stdout.txt»)
// This only works under CLI in Linux
// Note: Until we have closed it STDOUT will NOT be prefixed with a $

// Get the path to the current console for STDOUT so we can reconnect later!
$strOldSTDOUT =( posix_ttyname ( STDOUT ));

echo( «This will go to the current console\r\n» );
// Close the STDOUT resource
fclose ( STDOUT );

// Reopen $STDOUT as a file Note: All further $STDOUT usage will be prefixed with a $
$STDOUT = fopen ( «/tmp/php_stdout.txt» , «a» ); /
echo( «This should append the file /tmp/php_stdout.txt\r\n» );
// Close stdout again so we can reconnect the console. Note: We are still using
fclose ( $STDOUT );

// Use the path to the console we got earlier
$STDOUT = fopen ( $strOldSTDOUT , «r+» );
echo( «And we are back on the console\r\n» );

The command line interface data in STDIN is not made available until return is pressed.
By adding «readline_callback_handler_install(», function()<>);» before reading STDIN for the first time single key presses can be captured.

Note: This only seems to work under Linux CLI and will not work in Apache or Windows CLI.

This cam be used to obscure a password or used with ‘stream_select’ to make a non blocking keyboard monitor.

// Demo WITHOUT readline_callback_handler_install(», function()<>);
$resSTDIN = fopen ( «php://stdin» , «r» );
echo( «Type ‘x’. Then press return.» );
$strChar = stream_get_contents ( $resSTDIN , 1 );

echo( «\nYou typed: » . $strChar . «\n\n» );
fclose ( $resSTDIN );

// Demo WITH readline_callback_handler_install(», function()<>);
// This line removes the wait for on STDIN
readline_callback_handler_install ( » , function()<>);

$resSTDIN = fopen ( «php://stdin» , «r» );
echo( «We have now run: readline_callback_handler_install(», function()<>);\n» );
echo( «Press the ‘y’ key» );
$strChar = stream_get_contents ( $resSTDIN , 1 );
echo( «\nYou pressed: » . $strChar . «\nBut did not have to press \n» );
fclose ( $resSTDIN );
readline_callback_handler_remove ();
echo( «\nGoodbye\n» )
?>

It also hides text from the CLI so can be used for things like. password obscurification.
eg

readline_callback_handler_install ( » , function()<>);
echo( «Enter password followed by return. (Do not use a real one!)\n» );
echo( «Password: » );
$strObscured = » ;
while( true )
$strChar = stream_get_contents ( STDIN , 1 );
if( $strChar === chr ( 10 ))
break;
>
$strObscured .= $strChar ;
echo( «*» );
>
echo( «\n» );
echo( «You entered: » . $strObscured . «\n» );
?>

The following code shows how to test for input on STDIN. In this case, we were looking for CSV data, so we use fgetcsv to read STDIN, if it creates an array, we assume CVS input on STDIN, if no array was created, we assume there’s no input from STDIN, and look, later, to an argument with a CSV file name.

Note, without the stream_set_blocking() call, fgetcsv() hangs on STDIN, awaiting input from the user, which isn’t useful as we’re looking for a piped file. If it isn’t here already, it isn’t going to be.

stream_set_blocking ( STDIN , 0 );
$csv_ar = fgetcsv ( STDIN );
if ( is_array ( $csv_ar )) print «CVS on STDIN\n» ;
> else print «Look to ARGV for CSV file name.\n» ;
>
?>

I find a BUG with the constant STDIN, I don’t know if it si the Enter/Return key that make this proprem, when I use trim(fgets(STDIN)), that doesn’t trim anything, when I detect the length of fgets(STDIN), in windows, it is 2 characters longer than what I input, in Linux, it makes 1. I tried to trim(fgets(STDIN), ‘ \r\n’), but it still does not work.
So I have to substr the input manually, it seems like this way:
$STDIN = trim ( substr ( fgets ( STDIN ), 0 , ( PHP_OS == ‘WINNT’ ? 2 : 1 )));
?>
then I get what I want really.

Источник

Оцените статью