如何检查PHP中是否存在stdin(php-cgi)?

cwd*_*cwd 8 php shell stdin

设置和背景

我正在编写需要运行的脚本,/usr/bin/php-cgi/usr/local/bin/php我无法检查stdin

如果我/usr/local/bin/php用作翻译,我可以做类似的事情

if defined('STDIN'){ ... }
Run Code Online (Sandbox Code Playgroud)

这似乎不适用于php-cgi - 看起来总是未定义.我检查了php-cgi手册页,但没有发现它非常有帮助.另外,如果我理解正确,STDIN常量是一个文件句柄php://stdin.我读到某个地方不应该有常数php-cgi

要求

  • shebang需要 #!/usr/bin/php-cgi -q
  • 该脚本有时会传递参数
  • 该脚本有时会通过接收输入 STDIN

当前脚本

#!/usr/bin/php-cgi -q
<?php

$stdin = '';
$fh = fopen('php://stdin', 'r');

if($fh)
{

    while ($line = fgets( $fh )) {
            $stdin .= $line;
    }
    fclose($fh);

}

echo $stdin;
Run Code Online (Sandbox Code Playgroud)

有问题的行为

这个工作正常:

$ echo hello | ./myscript.php 
hello
Run Code Online (Sandbox Code Playgroud)

这只是挂起:

./myscript.php 
Run Code Online (Sandbox Code Playgroud)

这些东西对我不起作用:

  • 检查defined('STDIN')//始终返回false
  • 期待看是否CONTENT_LENGTH已定义
  • 检查变量和常量

我已将此添加到脚本中并以两种方式运行:

print_r(get_defined_constants());
print_r($GLOBALS);
print_r($_COOKIE);
print_r($_ENV);
print_r($_FILES);
print_r($_GET);
print_r($_POST);
print_r($_REQUEST);
print_r($_SERVER);
echo shell_exec('printenv');
Run Code Online (Sandbox Code Playgroud)

然后我对输出进行了差异化,它是一样的.

如果没有锁定脚本,我不知道检查/获取stdin通过的任何其他方法php-cgi.

/usr/bin/php-cgi -v 收益率: PHP 5.4.17 (cgi-fcgi)

小智 5

您可以使用选择功能,例如:

$stdin = '';
$fh = fopen('php://stdin', 'r');
$read  = array($fh);
$write = NULL;
$except = NULL;
if ( stream_select( $read, $write, $except, 0 ) === 1 ) {
    while ($line = fgets( $fh )) {
            $stdin .= $line;
    }
}
fclose($fh);
Run Code Online (Sandbox Code Playgroud)


Cyc*_*ode 0

问题是您while($line = fgets($fh))在代码中创建了一个无限循环。

$stdin = '';
$fh = fopen('php://stdin','r');
if($fh) {
  // read *one* line from stdin upto "\r\n"
  $stdin = fgets($fh);
  fclose($fh);
}
echo $stdin;
Run Code Online (Sandbox Code Playgroud)

如果您传递像这样的参数,echo foo=bar | ./myscript.php并且在您调用它时会读取一行,那么上面的方法就可以工作./myscript.php 如果您想读取更多行并保留原始代码,您可以发送退出信号CTRL + D

要像这样传递参数,./myscript.php foo=bar您可以检查变量的内容$argv,其中第一个参数始终是执行脚本的名称:

 ./myscript.php foo=bar

 // File: myscript.php
 $stdin = '';
 for($i = 1; $i < count($argv); i++) {
    $stdin .= $argv[$i];
 }
Run Code Online (Sandbox Code Playgroud)

我不确定这是否能解决任何问题,但也许它会给您一些想法。