The CLI SAPI defines a few constants for I/O streams to make programming for the command line a bit easier.
CLI specific Constants Constant DescriptionSTDIN
An already opened stream to stdin
. This saves opening it with
<?php
$stdin = fopen('php://stdin', 'r');
?>
stdin
, you can use
<?php
$line = trim(fgets(STDIN)); // reads one line from STDIN
fscanf(STDIN, "%d\n", $number); // reads number from STDIN
?>
STDOUT
An already opened stream to stdout
. This saves opening it with
<?php
$stdout = fopen('php://stdout', 'w');
?>
STDERR
An already opened stream to stderr
. This saves opening it with
<?php
$stderr = fopen('php://stderr', 'w');
?>
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.
Aurelien Marchand ¶Note:
These constants are not available if reading the PHP script from
stdin
.
14 years ago
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.
Aurelien
phil_php at zieaon dot com ¶
6 years ago
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.
<?php$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);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 <cr>\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
<?php
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");
?>
ecrist at secure-computing dot net ¶
13 years ago
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.
<?php
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";
}
?>
phil_php at zieaon dot com ¶
4 years ago
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")
<?php
$strOldSTDOUT=(posix_ttyname(STDOUT));
echo(
"This will go to the current console\r\n");
fclose(STDOUT); $STDOUT=fopen("/tmp/php_stdout.txt","a"); /
echo("This should append the file /tmp/php_stdout.txt\r\n");
fclose($STDOUT); $STDOUT=fopen($strOldSTDOUT,"r+");
echo("And we are back on the console\r\n");?>
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.3