заставить Proc_Open работать синхронно

У меня был 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.


person Liam Arbel    schedule 01.08.2014    source источник
comment
как насчет того, чтобы добавить код, чтобы показать нам, что вы там делаете?   -  person Twisted1919    schedule 01.08.2014
comment
Судя по вашему коду, я не думаю, что проблема в php, скорее, в вашем js-коде, где он не блокируется, и, скорее всего, скрипт завершает выполнение до обработки обратного вызова. Возможно, заблокируйте после вызова page.open и отпустите, когда этот вызов завершится.   -  person Twisted1919    schedule 01.08.2014
comment
скрученный, вы можете быть более конкретными о блоке в коде js. Я не большой эксперт по js, и мне не помешало бы немного больше рекомендаций! благодарю вас   -  person Liam Arbel    schedule 01.08.2014
comment
это из моего очень небольшого опыта работы с nodejs, не знаю, применимо ли оно здесь. Ваш вызов 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