Получите PHP proc_open() для чтения потока PhantomJS до тех пор, пока создается png

У меня был 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 обработки изображений, чтобы они начали работать, как только целевой файл изображения будет готов.

вот мой скрипт 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. Что я делаю не так?


person Liam Arbel    schedule 31.07.2014    source источник
comment
Помог ли мой ответ? Есть ли проблемы? Если это вам помогло, вы можете принять это.   -  person Artjom B.    schedule 07.08.2014


Ответы (1)


Как предложил Билл Шандер прямо в связанной с вами задаче на github, вы можете использовать :

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

для запуска вашего сценария phantomjs (который основан на этом ответе). Кажется, что вам нужно только изображение, поэтому трубы в этом случае не нужны.

Полный скрипт для справки находится здесь и работает в Windows как есть.

person Artjom B.    schedule 01.08.2014