Кратко опишите стандартный ввод и вывод PHP.
Сегодня я хочу использовать PHP, чтобы решить некоторые проблемы онлайн в Sphere Online Judge. Мне нужно использовать стандартный ввод и вывод, но я не хочу писать на языке c, когда пишу php в последнее время. Обычно я пишу проекты, используя отправку форм. Я действительно не думал об этом, поэтому Прочтите документ.
1. Введение в PHP STDIN, STDOUT, STDERR:
STDIN 、 STDOUT 、 STDERR Потоки ввода и вывода команд используются для ввода и вывода содержимого на консоль (терминал оболочки Linux, терминал Windows cmd). Они открываются по умолчанию и могут быть прочитаны и записаны напрямую. Их можно читать и записывать только в CLI (интерфейс командной строки , Интерфейс командной строки), они не определены в режиме Http.
И их открытая копия php://stdin 、 php://stdout 、 php://stderr Невозможно вывести контент в браузер http после тестирования: написать php://stderr Содержимое будет занесено в журнал ошибок сайта по умолчанию, два других не действуют.
Введение в STDIN / STDOUT / STDERR:
Исходный поток | Открыть копию потока | описание |
---|---|---|
STDIN | php://stdin | Стандартный ввод (стандартный ввод), только для чтения, используется для ввода контента с консоли; |
STDOUT | php://stdout | Стандартный вывод (стандартный вывод), только запись, используется для вывода на консольНормальная информация; |
STDERR | php://stderr | Вывод ошибок (стандартная ошибка), только запись, используется для вывода на консольСообщение об ошибке; |
Официально рекомендуют использовать константы STDIN, STDOUT и STDERR для замены оболочек копирования, которые они открывают вручную. php://stdin 、 php://stdout с участием php://stderr 。
2. Использование PHP STDIN:
В языке PHP «STDIN» используется для чтения содержимого с консоли. Эта константа встречается или передается fopen() Функция открыта php://stdin Сценарий будет ждать ввода данных пользователем, пока пользователь не нажмет клавишу ввода для отправки.
Напиши stdin.php пройти тест:
echo "Пожалуйста, введите содержание:"; $jimmy = fgets(STDIN); echo sprintf("Введено содержание:% s \ n", $jimmy); $demo = fopen('php://stdin', 'r'); echo "пожалуйста, введите: "; $test = fread($demo, 12); // Считываем до 12 символов echo sprintf("Введено как:% s \ n", $test); fclose($demo);
Пожалуйста, введите содержание:sad Введенный контент: sad пожалуйста, введите: asdasdasdasdasdasd Введите как: asdasdasdasd (здесь потому что самый читаемый12Символы, установите больше, чтобы отобразить полностью)
В-третьих, использование PHP STDOUT:
Язык PHP STDOUT Используется для вывода стандартной информации на консоль; в эту константу или вfopen()Функция открыта php://stdout Записанный контент будет напрямую выводиться на консоль.Стандартный вывод; Можно использовать содержимое стандартного вывода «>«или»1>«Перенаправить в указанное место, например в файл.
Таким же образом пишем файл для тестирования
fwrite(STDOUT, "Пишите через STDOUT; \ n"); $demo = fopen("php://stdout", "w"); fwrite($demo, "Через php:// stdout write; "); fclose($demo);
☁ test php demo.php > a.txt ☁ test cat a.txt отSTDOUTНапишите Через php:// stdout write;% ☁ test php demo.php отSTDOUTНапишите Через php:// stdout write;% ☁ test
Четыре, использование PHP STDERR:
«STDERR» в языке PHP используется для вывода сообщений об ошибках на консоль; в константы или вfopen()Контент, записанный в «php: // stderr», открытый функцией, будет напрямую выводиться на консоль.Вывод ошибок; Содержимое вывода ошибки можно использовать «2>«Перенаправить в определенное место, например в файл; его также можно использовать»2>&1«Прямой вывод ошибок на стандартный вывод и объединение со стандартным выводом.
fwrite(STDERR, "Ошибка вывода, записанная STDERR; \ n"); fwrite(STDOUT, "Нормальный вывод, написанный STDOUT; \ n"); $stdout = fopen("php://stdout", "w"); fwrite($stdout, "php:// Нормальный вывод, записанный stdout; \ n "); fclose($stdout); $stderr = fopen("php://stderr", "w"); fwrite($stderr, "php:// вывод ошибок записан stderr; \ n "); fclose($stderr);
Нормальный вывод и вывод ошибок направляются в разные файлы:
☁ test php demo.php 1>demo.ok 2>demo.err ☁ test cat demo.ok STDOUTНормальный вывод для записи; php:// Нормальный вывод, записанный stdout; ☁ test cat demo.err STDERRВывод письменных ошибок; php:// вывод ошибок записан stderr;
Обычный вывод и вывод ошибок объединяются и направляются в единый файл:
☁ test php demo.php 1>AllInOne 2>&1 ☁ test cat AllInOne STDERRВывод письменных ошибок; STDOUTНормальный вывод для записи; php:// Нормальный вывод, записанный stdout; php:// вывод ошибок записан stderr;
Хорошо, тогда вы можете обратиться к судье Sphere Online, чтобы изменить ситуацию, сначала проверьте демонстрационную тему
// your code here $x=0; while($x!=42) $x = fgets(STDIN); if($x!=42) echo sprintf("%d\n",$x); > > ?>
Хахахаха, все в порядке, больше не ограничивается java и c, я могу использовать PHP для решения некоторых проблем, вы также можете попробовать
Stderr to file php
The CLI SAPI defines a few constants for I/O streams to make programming for the command line a bit easier.
An already opened stream to stdin . This saves opening it with
$line = trim ( fgets ( STDIN )); // reads one line from STDIN
fscanf ( STDIN , «%d\n» , $number ); // reads number from STDIN
?>?php
An already opened stream to stdout . This saves opening it with
An already opened stream to stderr . This saves opening it with
Given the above, you don’t need to open e.g. a stream for stderr yourself but simply use the constant instead of the stream resource:
php -r 'fwrite(STDERR, "stderr\n");'
You do not need to explicitly close these streams, as they are closed automatically by PHP when your script ends.
Note:
These constants are not available if reading the PHP script from 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.