如何从php中的popen获取进程的输出?

时间:2013-04-13 13:35:23

标签: php popen

档案a.php:

<?php
echo "abcdef";
?>

文件b.php:

<?php
$h=popen('php a.php',r);
pclose($h);
?>

问题:

我无法在控制台上看到回音结果; 为什么以及如何看待它?

我不想在文件b.php中这样做:echo stream_get_contents($h);

3 个答案:

答案 0 :(得分:7)

检查popen文档中的第二个示例,它显示了如何执行此操作:

<?php
error_reporting(E_ALL);

/* Add redirection so we can get stderr. */
$handle = popen('/path/to/executable 2>&1', 'r');
echo "'$handle'; " . gettype($handle) . "\n";
$read = fread($handle, 2096);
echo $read;
pclose($handle);

此代码段从stderr读取。删除管道以从标准输出读取。

答案 1 :(得分:3)

您无法在控制台上看到回显结果,因为它从未进入控制台。通过以读模式打开进程,其STDOUT被链接到打开进程的文件句柄。输出到达控制台的唯一方法是从该文件句柄读取,然后回显它。

换句话说,流程就是这个。

  • b.php开始运行 - 其STDIN和STDOPUT像往常一样链接到您的控制台
  • 它在读取模式下调用popen并将流资源存储在$ h
  • 这会导致a.php开始运行,其STDOUT链接到$ h中的文件描述符,其STDIN没有链接到任何内容
  • 这意味着,正如您所看到的,a.php无法直接访问启动b.php的控制台
  • a.php将其输出写入该流,然后完成运行
  • b.php从不对$ h中的流做任何事情,它只是关闭它,所以a.php的输出都会丢失。

希望能解释这里发生的事情。如果你想在控制台上看到a.php的输出,那么b.php需要在$ h中从流中读取它,然后回显它,因为只有b.php可以访问控制台。

或者,如果使用system()而不是popen(),输出将自动在调用脚本的控制台上输出,因为使用system()将主脚本的STDIN和STOUT移交给您调用的程序或脚本

答案 2 :(得分:0)

尝试一下:

while (@ ob_end_flush()); // end all output buffers if any
$proc = popen('/path/to/executable 2>&1', 'r');
while (!feof($proc))
{
    echo fread($proc, 4096);
    @ flush();
}