2017-07-11 62 views
0

我有2個PHP腳本爲caller.phptask.phpcaller.php被稱爲與jQuery Ajax請求,然後caller.php啓動一個進程來運行PHP文件中的背景像下面的代碼PHP不proc_open後立即返回()

JQuery的AJAX請求

var xhr = $.ajax({ 
    url: "https://www.example.com/caller.php", 
    type: "post", 
    data: "" 
    }).done(function(){} 
}); 

Caller.php

$cmd = 'php task.php &';  // To call task.php in background 
$descriptorspec = array(
    0 => array('pipe', 'r'), // STDIN 
    1 => array('pipe', 'w'), // STDOUT 
    2 => array('pipe', 'w') // STDERR 
); 
$pipes = array(); 

$process = proc_open($cmd, $descriptorspec, $pipes); 

do { 
    // get the pid of the child process and it's exit code 
    $status = proc_get_status($process); 
} while($status['running'] !== FALSE); 

$pid = $status['pid']; 
$exitcode = $status['exitcode']; 

proc_close($process); 

if($exitcode == 0){echo 'Task.php is running.';} 

我上面的代碼學到Running a php script via ajax, but only if it is not already running

上面的代碼運行完美,但proc_open()等待,直到task.php沒有完成自己的工作。我想task.php在後臺運行,並得到caller.php立即響應。

我也試過exec()shell_exec()但其中不工作。他們等待task.php完成全部工作,然後回覆。

我也是在阿賈克斯試圖xhr.abort()見好就收Ajax響應,但後來我發現,xhr.abort()不會關閉與服務器的連接。

請注意,我已經削減了代碼,並去掉了一些基本的會話和用戶登錄等措施,使代碼更短。

P.S.我有一個VPS,這樣,我有足夠的權限才能啓用/禁用PHP函數等

+0

你已經把你的命令的末尾,所以這將使它在後臺工作但我認爲你所做的while循環是阻止你的腳本caller.php。 你可以將狀態返回給你的ajax並進行測試。 –

+0

@seifeddineBesbes我認爲你是對的。請繼續,以便我可以檢查它。 –

+0

@seifeddineBesbes Nop。在刪除do-while模塊並直接響應之後,即使這樣做也行不通。 –

回答

0

好吧,我覺得找你缺少的flush()語句將狀態恢復到AJAX例如:

do { 
    // get the pid of the child process and it's exit code 
    $status = proc_get_status($process); 
    echo $status['running']; 
    ob_flush();flush(); // Send output to browser immediately 

} while($status['running'] !== FALSE); 

請記住,如果你使用ob_flush()和flush(),你將得到的結果不是在done函數中,而是在xhr.onprogress事件中,這裏是一個解釋的例子https://www.sitepoint.com/php-streaming-output-buffering-explained/

希望它有幫助。

+0

Nop不工作。 –

+0

我編輯了我的回覆並添加了一個可能對您有用的示例鏈接。 –

+0

不工作:(:( –