PHP - 检测 STDIO 输入
PHP - detect STDIO input
我想要的是能够可选地通过管道将 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 将输出 string(12) "Hello World" (+末尾的新行...)因此,如果需要,您需要将数据进一步处理到数组中。 explode() 似乎是一种简单的方法。
if(FALSE !== ftell(STDIN))
{
while (FALSE !== ($line = fgets(STDIN)))
{
$customLogArr[]=$line;
}
}
对于 STDIN,如果无法读取任何内容,ftell()
将 return 错误。
看起来有些地方发生了变化,或者 none 这些答案曾经是正确的。您不能简单地 ftell(STDIN)
查看是否有从 STDIN
传递的数据
<?php
$stdin = fopen('php://stdin', 'r');
var_dump(ftell($stdin));
输出
-:4:
bool(false)
这来自 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
<?php
$fhandle = fopen("php://stdin", 'r');
$stdinData = ftell($fhandle) === false // strict comparison required
? null
: stream_get_contents($fhandle);
var_dump($stdinData);
当没有提供 stdin
数据时,sript 输出:
$ ./test.php
NULL
脚本在 stdin
提供数据时输出:
$ ./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);
"
重要的部分是使用严格比较 (===
) 作为 ftell
returns 指针位置,其值为 0
以防句柄刚刚被已初始化。
对于 PHP 7.3 和更早版本,必须使用稍微不同的方法:
#!/usr/bin/env php
<?php
stream_set_blocking(STDIN, 0);
$stdinData = ftell(STDIN) === false // strict comparison required
? null
: stream_get_contents(STDIN);
var_dump($stdinData);
使用posix_isatty()
函数可能会简单一些。
- posix_isatty |手动@ PHP.net
<?php
/**
* parseLog.php
*/
echo (posix_isatty(STDIN)) ? 'no stdin' . PHP_EOL : file_get_contents('php://stdin');
$ echo 'foo' > ./logfile.txt
$ cat logfile.txt | php parseLog.php
foo
$ php parseLog.php
no stdin
posix_isatty(STDIN)
确定 STDIN
是否打开并连接到终端。因此,当从 STDIN
接收数据时,它将 return false
.
- REF: https://qiita.com/m_norii/items/cd2d66e5a82c11cac758 @Qiita(日文)
我想要的是能够可选地通过管道将 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 将输出 string(12) "Hello World" (+末尾的新行...)因此,如果需要,您需要将数据进一步处理到数组中。 explode() 似乎是一种简单的方法。
if(FALSE !== ftell(STDIN))
{
while (FALSE !== ($line = fgets(STDIN)))
{
$customLogArr[]=$line;
}
}
对于 STDIN,如果无法读取任何内容,ftell()
将 return 错误。
看起来有些地方发生了变化,或者 none 这些答案曾经是正确的。您不能简单地 ftell(STDIN)
查看是否有从 STDIN
<?php
$stdin = fopen('php://stdin', 'r');
var_dump(ftell($stdin));
输出
-:4:
bool(false)
这来自 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
<?php
$fhandle = fopen("php://stdin", 'r');
$stdinData = ftell($fhandle) === false // strict comparison required
? null
: stream_get_contents($fhandle);
var_dump($stdinData);
当没有提供 stdin
数据时,sript 输出:
$ ./test.php
NULL
脚本在 stdin
提供数据时输出:
$ ./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);
"
重要的部分是使用严格比较 (===
) 作为 ftell
returns 指针位置,其值为 0
以防句柄刚刚被已初始化。
对于 PHP 7.3 和更早版本,必须使用稍微不同的方法:
#!/usr/bin/env php
<?php
stream_set_blocking(STDIN, 0);
$stdinData = ftell(STDIN) === false // strict comparison required
? null
: stream_get_contents(STDIN);
var_dump($stdinData);
使用posix_isatty()
函数可能会简单一些。
- posix_isatty |手动@ PHP.net
<?php
/**
* parseLog.php
*/
echo (posix_isatty(STDIN)) ? 'no stdin' . PHP_EOL : file_get_contents('php://stdin');
$ echo 'foo' > ./logfile.txt
$ cat logfile.txt | php parseLog.php
foo
$ php parseLog.php
no stdin
posix_isatty(STDIN)
确定 STDIN
是否打开并连接到终端。因此,当从 STDIN
接收数据时,它将 return false
.
- REF: https://qiita.com/m_norii/items/cd2d66e5a82c11cac758 @Qiita(日文)