PHP-检测STDIO输入

PHP-检测STDIO输入,php,stdio,Php,Stdio,我想要的是能够选择性地将STDIO管道传输到PHP脚本。否则,它将从文件中获取输入。所以有时候我只是简单地运行脚本,其他时候我会做类似的事情 grep text logfile | php parseLog.php 我有一个非常像这样的循环,当STDIO存在时,它可以正常工作: while (FALSE !== ($line = fgets(STDIN))) { $customLogArr[]=$line; } 当没有STDIO时,虽然它会停止等待,但它甚至不会进入循环 我想

我想要的是能够选择性地将STDIO管道传输到PHP脚本。否则,它将从文件中获取输入。所以有时候我只是简单地运行脚本,其他时候我会做类似的事情

grep text logfile | php parseLog.php
我有一个非常像这样的循环,当STDIO存在时,它可以正常工作:

while (FALSE !== ($line = fgets(STDIN)))
{
        $customLogArr[]=$line;
}
当没有STDIO时,虽然它会停止等待,但它甚至不会进入循环


我想做的是能够检测我是否有STDIO输入。有办法吗?

这就是你要找的吗?如果我误解了,请原谅,在没有输入STDIN的情况下,这不应该占用您的时间

stream_set_blocking(STDIN, 1);

function CheckSTDIN() {
    $read = array(STDIN);
    $wrte = NULL;
    $expt = NULL;
    $a = stream_select($read, $wrte, $expt, 0);
    if ($a && in_array(STDIN, $read)) {
        // you can read from STDIN now, it'll only be available if there is anything in STDIN
        // you can return the value or pass it to global or class variable
        return fread(STDIN, 255); // set your desired string length
    } else return false;
}

while (FALSE !== ($line = CheckSTDIN())) {
        $customLogArr[]=$line;
}

上述解决方案对我不起作用。这是一个有效的方法

if ($args = stream_get_contents(fopen("php://stdin", "r"))) {

    var_dump($args);

} else {
    echo 'No input';
}
注意:这将以字符串形式读取传输到脚本的数据:echo“Hello World”| php test.php将输出字符串(12)“Hello World”(+末尾的新行…),因此,如果需要,您需要进一步将数据处理到数组中。explode()似乎是一种简单的方法

if(FALSE !== ftell(STDIN))
{
    while (FALSE !== ($line = fgets(STDIN)))
    {
        $customLogArr[]=$line;
    }
}

对于STDIN,如果无法读取任何内容,
ftell()
将返回false。

看起来有什么变化,或者这些答案都不正确。您不能简单地
ftell(STDIN)
查看是否有来自
STDIN的数据

<?php

$stdin = fopen('php://stdin', 'r');
var_dump(ftell($stdin));
这是来自带有输出的
php-v

PHP 7.0.22-0ubuntu0.16.04.1 (cli) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies
    with Zend OPcache v7.0.22-0ubuntu0.16.04.1, Copyright (c) 1999-2017, by Zend Technologies
    with Xdebug v2.4.0, Copyright (c) 2002-2016, by Derick Rethans
当我尝试使用STDIN常量时,我得到

PHP Notice:  Use of undefined constant STDIN - assumed 'STDIN' in - on line 3

考虑这样一个脚本:

#/usr/bin/env-php
使用
posix_isatty()
函数可能会简单一些

  • | Manual@PHP.net

上次我检查STDIN位置时,从STDIN读取时从未归零,它始终是一个非负整数,因此
ftell
始终返回
integer
@dededeee是的,您是对的。因此,false仅表示当前进程没有STDIN。正确,直到STDIN关闭。php7@version 7
php7.0.22-0ubuntu0.16.04.1(cli)(NTS)
似乎抱怨没有定义STDIN<代码>PHP注意:在第3行中使用未定义的常量STDIN-假定为“STDIN”
奇怪,它不适用于您,我从我的OOP项目中提取了它,它按照我所描述的方式工作。我重新运行,是的,但是:
fread()只需要2个参数,1个给定的
哦,我假设第二个参数是默认值,我在我的例子中使用了
1
,这是一个如何检索流内容的示例。编辑:修复了
fread
@ErickRobertson在上面的评论中,我说我是从自己的项目中提取的。这是一个Windows Apache项目。它确实起作用了。我没有Apache。我只有窗户。它在Windows上不工作。您需要Apache或Linux,但当一个STDIN中没有任何内容时,它会挂起。这正是OP想要解决的问题。没错,不幸的是,在没有STDIN的情况下,这是行不通的。我希望……)问题是试图在没有
ftell($resource)
的情况下首先获取内容。如果您只知道自己在做什么以及为什么要做,那么此页面上的大多数代码都可以工作。
PHP Notice:  Use of undefined constant STDIN - assumed 'STDIN' in - on line 3
$ ./test.php 
NULL
$ ./test.php < ./test.php 
string(173) "#!/usr/bin/env php
<?php

$fhandle = fopen("php://stdin", 'r');
$stdinData = ftell($fhandle) === false // strict comparison required
    ? null
    : stream_get_contents($fhandle);
var_dump($stdinData);
"
$ echo 'foo' > ./logfile.txt

$ cat logfile.txt | php parseLog.php
foo

$ php parseLog.php
no stdin