2012-06-06 11 views
3

如果我有一個PHP頁面正在執行需要很長時間的任務,並且我嘗試從同一個站點同時加載另一個頁面,那麼在第一個頁面超時之前,該頁面將不會加載。例如,如果我的超時設置爲60秒,那麼我將無法加載任何其他頁面,直到需要很長時間才能加載/超時的頁面60秒之後。據我所知這是預期的行爲。PHP超時會阻止人們在同一網絡加載頁面嗎?

我想弄清楚的是,造成上述情況的錯誤/長時間加載的PHP腳本是否也會影響同一網絡上的其他人。我個人認爲這是一個瀏覽器問題(即,如果我在chrome中加載了http://somesite.com/myscript.php,並且它開始工作,它在後臺顯示爲魔術,我無法再加載http://somesite.com/myscript2.php,直到超時,但我可能會在的頁面中加載Firefox) 。但是,我聽到了矛盾的說法,說超時會發生在同一網絡上的每個人(IP地址?)。

我的腳本適用於從聖人導入的一些數據,並且需要相當長的時間才能運行 - 它可以在它完成之前超時(即,如果明智的鼠尾草導入崩潰),所以我再次運行它,它離開的地方。我擔心辦公室裏的其他員工在運行時無法訪問該網站。

+0

你能否讓「我聽到矛盾的言論」更清楚一點?你從哪裏聽到的,你爲什麼相信它,你能得到一個信息源? – Nanne

回答

3

您在這裏遇到的問題實際上與您正在使用sessions(我猜測)有關。這可能有一點延伸,但它會完全說明你描述的內容。

這實際上並不是「預期的行爲」,除非您的Web服務器設置爲使用單個線程運行單個進程,我非常懷疑。這會造成網絡服務器在任何時候只能處理單個請求的情況,這會影響網絡上的每個人。這正是爲什麼你的網絡服務器可能不會像這樣設置 - 事實上我懷疑你會發現這樣配置你的服務器是不可能的,因爲它會使服務器有些無用。在一些聰明的alec和「Node.js怎麼樣?」之前呢? - 這是一個特例,因爲我相信你已經很清楚。

當一個PHP腳本打開一個會話時,它將對會話數據存儲的文件進行排它鎖定。這意味着任何後續請求都會在調用session_start()時阻塞,而PHP嘗試獲取會話數據文件上的獨佔鎖定 - 它不能這樣做,因爲您之前的請求中仍有一個請求。一旦您的上一個請求完成,它就釋放它對文件的鎖定,並且下一個請求可以完成。由於會話是每臺計算機(實際上按照瀏覽器會話,顧名思義,這就是爲什麼它在不同的瀏覽器中工作的原因),這不會影響您的網絡的其他用戶,但會離開您的網站設置,以便這是一個問題,即使只是對你而言是不好的做法,很容易避免。

解決此問題的方法是在完成給定腳本中的會話數據後立即致電session_write_close()。這會導致腳本關閉會話文件並釋放它的鎖定。您應該在開始長時間運行過程之前嘗試完成會話數據,或者在完成之前不要致電session_start()

從理論上講,你可以打電話session_write_close(),稍後再在腳本中調用session_start(),但我發現PHP在這方面有時表現出錯誤行爲(我認爲這是與cookie相關的,但不要引用我的話) 。顯然,請注意設置cookie會修改標題的事實,因此您必須在輸出任何數據或啓用輸出緩衝之前調用session_start()

例如,請考慮此腳本:

<?php 

    session_start(); 

    if (!isset($_SESSION['someval'])) { 
    $_SESSION['someval'] = 1; 
    } else { 
    $_SESSION['someval']++; 
    } 

    echo "someval is {$_SESSION['someval']}"; 

    sleep(10); 

有了上面的腳本,你將不得不等待10秒,你可以進行第二次請求之前。但是,如果您在echo行後面添加對session_write_close()的呼叫,則可以在前一個請求完成之前發出另一個請求。

+0

我與OP描述的問題完全相同,但是這完全解決了它 - 感謝您提供如此廣泛的答案! – Jeroen

+1

@Jeroen不用擔心,這是一個相對簡單但看似鮮爲人知的會話限制,人們很少在效果和原因之間做出跳躍,因爲它並不明顯。通常在腳本的頂部附近調用'session_start()',這會阻止腳本在會話鎖定時執行任何操作,所以您自然會認爲服務器尚未啓動腳本。這個問題已經出現在這裏,但是你不會在搜索中找到它,因爲人們通常不會在問題中提及「會話」,再加上你不知道你應該尋找它們。 – DaveRandom

0

嗯......我沒有檢查,但我認爲每個請求到web服務器都是在它自己的線程中處理的。因此不應該阻止不同的請求。試試:-)在大腳本運行時使用不同的瀏覽器並訪問您的頁面!

錯誤..我只是看到,這對你有用:-)它也應該爲其他人。