Linux — пытается понять разницу между / dev / stdin и php: // stdin

В качестве простого доказательства концепции я попытался разделить строку между разветвленными процессами от узла к узлу или от узла к php.

Возьмите этот простой PHP-код, который должен регистрировать вывод stdin в соответствии с PHP документы:

echo 'test' | php -r 'echo trim(fgets(STDIN));'

Работает нормально, но когда я запускаю процесс из 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)));

Почему php://stdin пусто? Безопасно ли использовать /dev/stdin? В чем разница между /dev/stdin а также php://stdin тем не мение?

Обратите внимание, что у меня есть такое поведение также между процессами с двумя узлами: process.stdin пусто, но /dev/stdin имеет ожидаемый результат.

3

Решение

Я тестировал с помощью следующего скрипта ( stdin_test.php ) с помощью:

> 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);

Я вернусь :

STDIN :test
php://stdin :
/dev/stdin :

Если я тогда закомментирую строку:

//echo trim(fgets(STDIN));

Я вернусь:

STDIN :
php://stdin :test
/dev/stdin :

Если я закомментирую оба первых эха stdin (и указатели на обработчик файлов), я получу:

STDIN :
php://stdin :
/dev/stdin : test

Глядя на документацию по php://input и как его можно использовать один раз, если (после 5.6) «тело запроса не сохранено», что типично для запросов POST, но не для запросов PUT (очевидно). Это заставляет меня думать, что они называются «потоками», потому что вы однажды можете в них ходить.

2

Другие решения

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

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector