Trying to understand the difference between / dev / stdin and php: // stdin
As a simple proof of concept, I tried to split the string between forked processes from node to node or from node to php.
Take this simple php code that should log the output stdin
according to the php docs :
echo 'test' | php -r 'echo trim(fgets(STDIN));'
Works fine, but when I create a process from nodejs:
spawner.js
var fs = require('fs'); var spawn = require('child_process').spawn;
//dummy stdin file
var stdin = fs.openSync('stdin_file', 'w+');
//write the string
fs.writeSync(stdin, 'test');
spawn('php', ['stdin_test.php'], {
cwd: __dirname,
detached: true,
//to fully detach the process nothing should be piped from or to the parent process
stdio: [stdin, fs.openSync('out.log', 'a'), fs.openSync('err.log', 'a')]
})
stdin_test.php
<?php
error_log('php://stdin');
//this should log 'test' but outputs a newline
error_log(trim(fgets(STDIN)));
$t = fopen('/dev/stdin', 'r');
error_log('/dev/stdin:');
//this is working as expected
error_log(trim(fgets($t)));
Why is it php://stdin
empty? Is it safe to use /dev/stdin
? What is the difference between /dev/stdin
and php://stdin
?
Note that I also have this behavior between 2 node: process.stdin
empty but /dev/stdin
has the expected result.
source to share
I tested with the following script ( stdin_test.php
) using:
> echo test | php stdin_test.php
stdin_test.php
<?
echo 'STDIN :' ;
echo trim(fgets(STDIN)) ;
echo PHP_EOL;
$stdin_stream = fopen('php://stdin', 'r');
echo 'php://stdin :';
echo trim(fgets($stdin_stream));
echo PHP_EOL;
fclose($stdin_stream);
$stdin_file = fopen('/dev/stdin', 'r');
echo '/dev/stdin :';
echo trim(fgets($stdin_file));
echo PHP_EOL;
fclose($stdin_file);
I'm coming back:
STDIN :test
php://stdin :
/dev/stdin :
If I then comment out the line:
//echo trim(fgets(STDIN));
I'm coming back:
STDIN :
php://stdin :test
/dev/stdin :
If I comment out both of the first stdin echoes (and the file handler pointers), I get:
STDIN :
php://stdin :
/dev/stdin : test
A look at the documentation for php://input
and how it is one-off, if only (after 5.6) the "request body is saved", which is typical for POST requests, but not PUT requests (apparently). This makes me think they are called "streams" because you can walk in them once.
source to share