获取PHP proc_open()来读取一个PhantomJS流,只要png被创建


Get PHP proc_open() to read a PhantomJS stream for as long as png is created

我有一个依赖于shell_exec()的PHP脚本,并且(作为结果)99%的时间工作。该脚本执行了一个生成图像文件的PhantomJS脚本。然后使用更多的PHP对图像文件进行一定的处理。问题是shell_exec()有时会挂起并导致可用性问题。读这篇文章https://github.com/ariya/phantomjs/issues/11463我了解到shell_exec()是问题,切换到proc_open可以解决悬挂问题。

问题是,当shell_exec()等待执行的命令完成时,proc_open却没有,因此跟随它并处理生成的图像的PHP命令在仍在生成图像时失败。我在Windows上工作,所以pcntl_waitpid不是一个选项。

我要做的是不断地让PhantomJS输出一些东西(任何东西),以便proc_open将通过它的stdin管道读取,这样我就可以计时图像处理PHP函数,以便在目标图像文件准备好后立即开始工作。

这是我的phantomJS脚本:
interval = setInterval(function() {
  console.log("x");
}, 250);
var page = require('webpage').create();
var args = require('system').args;
page.open('http://www.cnn.com', function () {
  page.render('test.png');
  phantom.exit();
});

和我的PHP代码:

ob_implicit_flush(true);
$descriptorspec = array(
    0 => array("pipe", "r"),  // stdin
    1 => array("pipe", "w"),  // stdout
    2 => array("pipe", "w")   // stderr 
);
$process = proc_open ("c:'phantomjs'phantomjs.exe /test.js", $descriptorspec, $pipes);
if (is_resource($process))
{
while( ! feof($pipes[1]))
  {
     $return_message = fgets($pipes[1], 1024);
     if (strlen($return_message) == 0) break;
     echo $return_message.'<br />';
     ob_flush();
     flush();
  }
}

生成了test.png,但是我没有得到一个$return_message。我做错了什么?

正如Bill Shander在链接github问题中建议的那样,您可以使用:

Proc_Close(Proc_Open("phantomjs test.js &", Array (), $foo));

来运行你的phantomjs脚本(基于这个答案)。看起来您只需要图像,所以在这种情况下管道是不必要的。

完整的参考脚本在这里,并在windows上工作。