2011-09-28 89 views
1

我想用popen在後臺運行一個php腳本。但是,我需要傳遞一個(相當大)的序列化對象。PHP管道進入後臺進程

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

沒有&符此代碼執行得很好,但父腳本將等待,直到孩子完成運行。使用&符STDIN不獲取數據。

任何想法?

回答

0

據我所知,沒有辦法在PHP發送後臺進程並繼續提供其STDIN(但也許我錯了)。您這裏有另外兩個選擇:

  1. 重構您background_test.php從命令行得到它的輸入和改變你的命令行中php background_test.php arg1 arg2 ... >log/output.log &
  2. 如果你的輸入很長,寫入到一個臨時文件,然後喂background_test.php腳本與該文件,如以下代碼

示例點2:

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

你可以嘗試讓子進程寫數據和主腳本繼續正常。

像這樣的事情

// 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 

瞭解更多關於在這裏:​​https://sites.google.com/a/van-steenbeek.net/archive/php_pcntl_fork

還要檢查功能pcntl_waitpid()(殭屍消失)PHP文檔。

+0

提到真的小心殭屍進程,如果你將要分叉腳本。另一種可能的選擇是像Gearman這樣的隊列管理器。 –

+0

好點,加入了waitpid的參考 –

0

使後臺進程偵聽套接字文件。然後從PHP打開套接字文件並將您的序列化數據發送到那裏。當您的後臺守護進程通過套接字接收連接時,使其分叉,讀取數據然後處理。

你需要做一些閱讀,但我認爲這是實現這一目標的最好方法。通過套接字我的意思是unix套接字文件,但你也可以在網絡上使用它。

http://gearman.org/也是一個不錯的選擇,因爲通過@Joshua