我有一個PHP腳本(我們稱之爲execute.php
),它在開始時繪製整個頁面(HTML標籤和body標籤等),並且在一開始就執行一些命令(C++程序)背景。然後它會等待這些程序終止(有些依賴於其他人的結果,因此可能會按順序執行),然後有一個JavaScript自動將表單提交給另一個PHP腳本(我們稱之爲results.php
),因爲results.php
需要來自前面腳本的POST信息。PHP腳本意外不會繼續
execute.php
:
<?php
print"
<html>
<body>
Some HTML code here
</body>
</html>
";
// Here come some C++-program calls
$pid_program1 = run_in_background($program1)
$pid_program2 = run_in_background($program2)
while (is_running($pid_program1) or is_running($pid_program2))
{
//echo(".");
sleep(1);
}
// Here come some later C++-program calls that execute quickly
$pid_program3 = run_in_background($program3)
$pid_program4 = run_in_background($program4)
while (is_running($pid_program3) or is_running($pid_program4))
{
sleep(1);
}
...
// We are now finished
print "
<form action=\"results.php\" id=\"go_to_results\" method=\"POST\">
<input type='hidden' name=\"session_id\" value=\"XYZ\">
</form>
<script type=\"text/javascript\">
AutoSubmitForm('go_to_results');
</script>
";
這很好地工作,如果C++程序1和2的執行速度。但是,當他們花費時間(總共大約25分鐘)時,PHP腳本似乎無法繼續。有趣的是,C++程序3和4被執行但併產生預期的輸出等
然而,當我把echo(".");
在第一while循環的sleep()
之前,它的工作原理,並且繼續直到JavaScript的自動提交。
因此在我看來,剩餘的PHP代碼(包括自動提交)無論何種原因,在第一個循環中沒有輸出時都不會發送。
我也嘗試過使用set_time_limit(0)
和ignore_user_abort(true)
以及其他不同的東西,比如寫入輸出緩衝區(不想混亂已經顯示的網頁)而不是echo,但這些都不起作用。
當我在具有多個內核的機器上運行相同的腳本,以便program1和2可以並行執行時,它也可以工作,不需要echo(".")
。
所以我目前非常困惑,無法在apache日誌或PHP日誌中找到任何錯誤消息,因此會真正感謝您對此問題的看法。再次感謝您的建議
編輯 感謝這麼遠。 我現在已經採用了一個涉及(非常簡單)AJAX的解決方案,並且這種方式絕對更好。然而,如果C++程序執行時間較長,它不會自動提交到這次實際創建的結果頁面(以前沒有這樣做)。 基本上我所做的是:
process.php:
<?php
$params = "someparam=1";
?>
<html>
<body>
<script type="text/javascript">
function run_analyses(params){
// Use AJAX to execute the programs independenantly in the background
// Allows for the user to close the process-page and come back at a later point to the results-link, w/o need to wait.
if (window.XMLHttpRequest)
{
http_request = new XMLHttpRequest();
}
else
{
//Fallback for IE5 and IE6, as these don't support the above writing/code
http_request = new ActiveXObject("Microsoft.XMLHTTP");
}
//Is http_request still false
if (!http_request)
{
alert('Ende :(Kann keine XMLHTTP-Instanz erzeugen');
}
http_request.onreadystatechange=function(){
if (http_request.readyState==4 && http_request.status==200){
// Maybe used to display the progress of the execution
//document.getElementById("output").innerHTML=http_request.responseText;
// Call of programs is finished -> Go to the results-page
document.getElementById("go_to_results").submit();
}
};
http_request.open("POST","execute.php",true);
//Send the proper header information along with the request
http_request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http_request.setRequestHeader("Content-length", params.length);
http_request.setRequestHeader("Connection", "close");
http_request.send(params);
};
</script>
<?php
// Do some HTML-markup
...
// Start the programs!
print "
<script type=\"text/javascript\">
run_analyses('".$params."');
</script>
<form action=\"results.html" id=\"go_to_results\" method=\"POST\">
<input type='hidden' name=\"session_id\" value=\"XYZ\">
</form>
?>
</html>
</body>
和execute.php包含C++ - 程序調用,等待例程,最後,通過「包括(」 results.php「)」創建的結果頁。 同樣,對於「不太長」的程序執行,自動提交按預期工作,但如果需要「更長」,則不會。 「更長」我的意思是大約25分鐘。
我完全不知道什麼可能導致這一點再次沒有錯誤信息被發現。 我是否缺少一個關鍵的配置選項(Apache,PHP等)?
編輯 事實證明,讓請求的PHP腳本重複「回聲」的東西可以防止超時。因此,它基本上與沒有AJAX的PHP解決方案相同,但是這次由於AJAX請求的responseText不一定是必需的,所以進度頁面不會混亂,可用作解決方法。具體而言,我不一定會將其推薦爲一般解決方案或良好實踐。
你是如何調用'execute.php'?通過'http'請求或命令行? –
通過http請求。 – Shadow