У меня был PHP-скрипт, который полагался на shell_exec() и (в результате) работал в 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. Вы можете увидеть, что я пробовал в этой теме:
Получить PHP proc_open() для чтения потока PhantomJS до тех пор, пока создается png
Я не мог заставить это работать, и, кажется, ни у кого больше нет решения для меня. Итак, теперь я спрашиваю, как заставить proc_open работать синхронно, как shell_exec. Мне нужно, чтобы остальные команды PHP в моих скриптах выполнялись только после завершения команды proc_open.
Добавление моего кода в соответствии с первым запросом комментария:
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();
}
}
Вот скрипт 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();
});
Если вместо «c:\phantomjs\phantomjs.exe /test.js» я использую пример формы ping cmd.exe, я получаю строку за строкой напечатанного $return_message, поэтому я знаю, что proc_open получает поток. Я пытаюсь сделать то же самое со сценарием Phantom.
page.open
в основном будет отправлять обратный вызов в фоновом режиме до тех пор, пока он не завершится, но обработка скрипта не остановится на этом вызове (поскольку он был отправлен в фоновом режиме) и продолжится без передачи вам какой-либо информации. Может быть, сделать что-то в этом роде:var isDone = 0; page.open('http://www.cnn.com', function (){page.render('test.png'); isDone = 1; }); setInterval(function(){ if(isDone) {phantom.exit();} }, 200)
- person Twisted1919   schedule 01.08.2014