PHP Pipe into a background process

雨燕双飞 提交于 2020-01-11 07:31:11

问题


I'm trying to use popen to run a php script in the background. However, I need to pass a (fairly large) serialized object.

$cmd = "php background_test.php >log/output.log &";
$fh = popen($cmd, 'w');
fwrite($fh, $data); 
fclose($fh);
//pclose($fh);

Without the ampersand this code executes fine but the parent script will wait until the child is finished running. With the ampersand STDIN gets no data.

Any ideas?


回答1:


As far as I know there is no way in php to send a process in background and continue to feed its STDIN (but maybe I'm wrong). You have two other choices here:

  1. Refactor your background_test.php to get its input from command line and transform your command line in php background_test.php arg1 arg2 ... >log/output.log &
  2. If your input is pretty long, write it to a temporary file and then feed the background_test.php script with that file as in the following code

Example for point 2:

<?
$tmp_file = tempnam();
file_put_content($tmp_file, $data);
$cmd = "php background_test.php < $tmp_name > log/output.log &";
exec($cmd);



回答2:


You can try forking letting child process to write data and main script continue as normal.

Something like this

// Fork a child process
$pid = pcntl_fork();

// Unable to fork
if ($pid == -1) {
    die('error');
}

// We are the parent
elseif ($pid) {

   // do nothing 
}

// We are the child
else {

    $cmd = "php background_test.php >log/output.log";
    $fh = popen($cmd, 'w');
    fwrite($fh, $data); 
    fclose($fh);
    exit();
}


// parent will continue here
// child will exit above

Read more about it here: https://sites.google.com/a/van-steenbeek.net/archive/php_pcntl_fork

Also check function pcntl_waitpid() (zombies be gone) in php documentation.




回答3:


Make a background processes listen to a socket file. Then open socket file from PHP and send your serialized data there. When your background daemon receives connection through the socket, make it fork, read data then process.

You would need to do some reading, but I think that's the best way to achieve this. By socket i mean unix socket file, but you can also use this over the network.

http://gearman.org/ is also a good alternative as mentioned by @Joshua



来源:https://stackoverflow.com/questions/7590521/php-pipe-into-a-background-process

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!