2010-12-07 99 views
9

我正在創建一個將通過命令行運行的PHP腳本。作爲這個腳本的一部分,有時候我可能需要產生/分叉一個可能需要很長時間才能完成的腳本。我不想阻止原始腳本完成。如果我使用JavaScript來完成這項工作,我可以在後臺運行AJAX請求。這基本上是我在這裏要做的。我不需要知道叉子何時完成,只是他們開始並完成自己。如何異步運行PHP腳本?

如何異步運行這些PHP腳本?

foreach ($lotsOfItems as $item) { 
    if ($item->needsExtraHelp) { 
     //start some asynchronous process here, and pass it $item 
    } 
} 
+0

你說「我不需要知道什麼時候叉完整的」和你的代碼說「並將它傳遞$項目」。你想獲得輸出嗎? – Jonas 2010-12-07 20:00:29

+0

PHP不起訴線程,你必須fork子進程,或者更好的方法是構建一個cron – RobertPitt 2010-12-07 20:07:06

回答

2
int pcntl_fork (void)

pcntl_fork()函數創建一個子過程,從僅在它的PID和PPID父進程不同。請參閱系統的fork(2)手冊頁,以獲取有關fork如何在您的系統上工作的具體細節。

細節:http://php.net/manual/en/function.pcntl-fork.php

相關的問題:PHP: What does pcntl_fork() really do?

過程控制不應該在Web服務器環境中啓用,如果任何過程控制功能在Web服務器中使用可能會發生意想不到的結果環境。

細節:http://www.php.net/manual/en/intro.pcntl.php

2

尋找用戶貢獻的高管指出,它看起來像你可以使用它,請查看:

http://de3.php.net/manual/en/function.exec.php#86329

<?php 
function execInBackground($cmd) { 
    if (substr(php_uname(), 0, 7) == "Windows"){ 
     pclose(popen("start /B ". $cmd, "r")); 
    } 
    else { 
     exec($cmd . " > /dev/null &"); 
    } 
} 
?> 

這將執行$ cmd在 背景(沒有cmd窗口)沒有PHP 等待它t o完成,在Windows和Unix上均爲 。

3
$pids = array(); 
foreach ($lotsOfItems as $item) { 
    if ($item->needsExtraHelp) { 
     $pid = pcntl_fork(); 
     if ($pid == 0) { 
      // you're in the child 
      var_dump($item); 
      exit(0); // don't forget this one!! 
     } else if ($pid == -1) { 
      // failed to fork process 
     } else { 
      // you're in the parent 
      $pids[] = $pid; 
     } 
    } 

    usleep(100); // prevent CPU from peaking 
    foreach ($pids as $pid) { 
     pcntl_waitpid($pid, $exitcode, WNOHANG); // prevents zombie processes 
    } 
}