2011-09-30 67 views
1

以下所有內容都基於Linux,最近的Apache,最近的PHP,用於Apache的PHP模塊。900秒後(15分鐘)混淆PHP/AJAX超時

我遇到了一個意外的行爲,因爲我的基於AJAX + PHP的web應用程序。 這是一個非常簡單的AJAX方法,基本上涉及到運行一段時間(幾秒到幾分鐘)的PHP腳本(execute.php)的請求。作爲一個測試設置,PHP腳本(execute.php)基本上只會睡一段時間。當這個數量是899秒時,它可以工作,但是當我將它設置爲900時,PHP腳本(simple echo())的答案似乎過期了或者類似的東西(究竟是什麼原因或原因實際上是未知的我),因爲請求沒有注意到它,因此沒有響應,並且各個innerHTML沒有按預期更新。 請找到下面的代碼。

我現在想知道900秒這個「超時」來自哪裏,甚至更重要的是,我怎樣才能防止這種情況發生?畢竟,我認爲這至少是AJAX處理異步調用的一般想法,並在請求改變狀態後立即通知客戶端!

process.php

<?php 
session_start(); 

include("functions.php"); 
include("env.php"); 

html_head("Processing..."); 

$sid = $_SESSION['my_sid']; 

?> 
<script type="text/javascript"> 
function run_analyses(params){ 
    <?php 
    print "var sid = \"". $sid ."\"; 
    "; 
    ?> 

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

    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 
$params "some_params"; 
print " 
Starting AJAX-call<br> 
<div style=\"width:400px; border: 1px black solid;\" id=\"output\">Use this to display an information about the progress</div> 
<script type=\"text/javascript\"> 
    run_analyses('".$params."'); 
</script> 
<form action=\"./usersets/". $sid ."/results.html\" id=\"go_to_results\" method=\"POST\"> 
<input type='hidden' name=\"session_id\" value=\"" .$sid. "\"> 
</form> 
"; 
html_foot(); 
?> 

和execute.php:

<?php 

session_start(); 

include("functions.php"); 
include("env.php"); 

$sid = $_SESSION['my_sid']; 

// Used to get the time at start of processing 
$time = microtime(); 
$time = explode(' ', $time); 
$time = $time[1] + $time[0]; 
$start = $time; 
session_write_close(); 

sleep(900); //899 here works 

session_start(); 
$time = microtime(); 
$time = explode(' ', $time); 
$time = $time[1] + $time[0]; 
$finish = $time; 
$total_time = round(($finish - $start), 3); 
//echo 'Page generated in '.$total_time.' seconds.'."\n"; 

// Make it accessible for the results 
$_SESSION['process_time'] = $total_time; 

echo("none"); 

?> 

所以 「啓動AJAX調用」 更新後的文字爲 「無」 時,PHP腳本休眠899秒,但如果該值爲900秒,則保持「使用此值顯示關於進度的信息」。

我真的很期待您的建議。

最佳,

陰影

編輯

grep max_execution $(locate php.ini)給出:

/etc/php5/apache2/php.ini:max_execution_time = 30 
/usr/share/doc/php5-common/examples/php.ini-development:max_execution_time = 30 
/usr/share/doc/php5-common/examples/php.ini-production:max_execution_time = 30 
/usr/share/php5/php.ini-production:max_execution_time = 30 
/usr/share/php5/php.ini-production-dist:max_execution_time = 30 
/usr/share/php5/php.ini-production.cli:max_execution_time = 30 

EDIT2 當調用本地腳本(在我的本地Linux上運行的Apache Web服務器MACHIN e)在我的瀏覽器中,有趣的是,它的行爲和預期一樣,並且要求返回請求。但是,當運行在另一臺機器上的網絡服務器上運行時,會出現上述意外的行爲。任何線索呢?因爲我沒有...抱歉。

+0

你檢查你的php.ini設置? max_execution_time? – lepe

+0

直接加載你的代碼(不是來自JS)並啓用錯誤顯示...檢查它顯示的內容。 – lepe

+0

編輯我的帖子,以表明它似乎**不**與max_execution_time有關。 – Shadow

回答

1

在你的php.ini中有一個max_execution_time,默認是30秒,所以它似乎已經被設置爲900.所以我會先在那裏檢查。信息:http://www.php.net/manual/en/info.configuration.php#ini.max-execution-time

至於解決它,你可以編輯php.ini設置該值真的很高(或無限制爲0),或者你也許可以使用這個功能:http://php.net/manual/en/function.set-time-limit.php在說300後重置它秒。

希望這會有所幫助!

編輯:增加了0值的max_execution_time李的建議

編輯2:

剛發現一些有趣的事情在這裏http://www.php.net/manual/en/function.set-time-limit.php#75557

請注意,在Linux下,睡眠時間被忽略,但在Windows,它算作執行時間。

所以,這可能是爲什麼它允許執行時間超過30秒,但仍然最終將其切斷。

+0

設置'max_execution_time = 0',表示無限的執行時間。 – Lee

+0

請參閱上文:編輯我的帖子以表明它似乎與max_execution_time沒有關係。 – Shadow

+0

看到編輯,有一個複雜的因素,在Linux上max_execution_time忽略睡眠(因爲沒有真正執行),請參閱我的編輯#2 – ctcherry

0

我試過你的例子,並把它放在不同的主機(不是本地主機)。在我的情況下,它運行良好,並在900秒後得到「無」的值。我刪除了SESSION調用來簡化示例...

嘗試不帶會話。如果這改變了一些東西,那麼「session.cookie_lifetime」值可能會相關。

0

搜索所有php.ini.htaccess值900:在源代碼中的900

grep -HR 900 $(locate php.ini) $(locate -e .htaccess) 

還搜索900和分數:

cd /var/www/ #path_to_yoursite 
grep --color=auto -HR "=\s*900\b" 
grep --color=auto -HR "=\s*20\s*\*\s*45\b" 
grep --color=auto -HR "=\s*15\s*\*\s*60\b" 
...