解决AJAX请求使PHP反应时间过长的问题
現(xiàn)在我們開(kāi)發(fā)了很多依賴于Ajax請(qǐng)求的應(yīng)用,在某些情況下,甚至全部頁(yè)面都依賴Ajax。有時(shí)我們會(huì)注意到,當(dāng)一個(gè)網(wǎng)頁(yè)發(fā)送兩個(gè)或者更多Ajax請(qǐng)求時(shí),PHP的反應(yīng)時(shí)間會(huì)很長(zhǎng)并會(huì)同時(shí)返回響應(yīng)內(nèi)容。
這個(gè)問(wèn)題很可能是你處理PHP會(huì)話的方式造成的,跟著本文去理解這個(gè)問(wèn)題,并做一些處理來(lái)避免這個(gè)問(wèn)題。
內(nèi)容
什么是PHP會(huì)話?
什么是Ajax?
具體問(wèn)題
造成的原因
問(wèn)題的解決方法
總結(jié)
什么是PHP會(huì)話?
為了理解這個(gè)問(wèn)題,有必要先了解一下PHP會(huì)話和Ajax,以及它們是怎么干擾的。
假設(shè)你正在開(kāi)發(fā)一個(gè)Web應(yīng)用,想要識(shí)別不同用戶。你想要記住是誰(shuí)每次瀏覽了所有頁(yè)面但都沒(méi)有登錄,這種情況下,你可以使用cookies或sessions。
可以你已經(jīng)意識(shí)到了,sessions是一種存儲(chǔ)用戶信息的方式,它可以在任何頁(yè)面重新取回用戶信息。跟Cookies不同,Sessions是存儲(chǔ)在服務(wù)器上的,所有用戶不能直接改變這些信息。
默認(rèn)情況下,Sessions在用戶關(guān)閉瀏覽器之前均有效,或者用戶在PHP配置文件中指定的時(shí)間內(nèi)沒(méi)有活動(dòng)之后才失效。
在PHP頁(yè)面中,無(wú)論你什么時(shí)候想要存儲(chǔ)或者重新獲取用戶數(shù)據(jù),都必須在頁(yè)面開(kāi)始處調(diào)用session_start(),因此才有權(quán)限使用$_SESSION去獲取session數(shù)據(jù)。
什么是Ajax?
Ajax代表 Asynchronous JavaScript and XML,它是一種不用重新加載整個(gè)頁(yè)面就能向服務(wù)器發(fā)送數(shù)據(jù)和從服務(wù)器接收數(shù)據(jù)的方式。
我們使用這種方式來(lái)發(fā)送數(shù)據(jù),并以較快的速度從服務(wù)器檢索數(shù)據(jù)。我們不用得到整個(gè)頁(yè)面并在瀏覽器中渲染它,因?yàn)檫@是很慢的。
因此,我們可以更新網(wǎng)頁(yè)的一部分,并且用戶是可以看見(jiàn)這種改變的,就像用戶向下滾動(dòng)Facebook的時(shí)間線頁(yè)面來(lái)看他們想看的東西,隨著新內(nèi)容添加而不用重載整個(gè)頁(yè)面。
具體問(wèn)題
開(kāi)發(fā)幾乎100%基于Ajax的Web應(yīng)用已經(jīng)不是一件新鮮事了,但是當(dāng)一個(gè)網(wǎng)頁(yè)同時(shí)發(fā)送兩個(gè)及以上的Ajax請(qǐng)求時(shí),你會(huì)注意到請(qǐng)求會(huì)花費(fèi)很長(zhǎng)時(shí)間,并且?guī)缀踉谕粫r(shí)刻完成了請(qǐng)求。
造成的原因
當(dāng)你想服務(wù)器發(fā)送一個(gè)Ajax請(qǐng)求時(shí),PHP腳本也開(kāi)啟了session_start(),它的調(diào)用會(huì)鎖定PHP的session文件。
你可能已經(jīng)知道,PHP默認(rèn)會(huì)把session數(shù)據(jù)存儲(chǔ)在服務(wù)器上的文件中。因?yàn)閮H僅只有一個(gè)PHP請(qǐng)求能改變同一個(gè)session文件,兩個(gè)同時(shí)的PHP請(qǐng)求可能會(huì)造成典型的文件鎖條件,因此,任何一個(gè)其他由PHP調(diào)用的對(duì)于同一個(gè)用戶的session_start()請(qǐng)求將不得不等到第一個(gè)請(qǐng)求結(jié)束。
現(xiàn)在,大部分PHP框架會(huì)首先在主文件中使用session_start()。因此,如果你正在使用會(huì)調(diào)用session_start()的框架或者函數(shù)庫(kù),將會(huì)造成session文件鎖,對(duì)于使用同一個(gè)瀏覽器的相同用戶,這將延遲同時(shí)發(fā)送的Ajax請(qǐng)求。
問(wèn)題的解決方法
調(diào)用session_write_close()函數(shù)會(huì)使PHP寫(xiě)入session文件并關(guān)閉它,因此釋放session文件后,另一個(gè)請(qǐng)求就有權(quán)限寫(xiě)入。
調(diào)用session_write_close()之后,當(dāng)前腳本會(huì)繼續(xù)正常運(yùn)行,但你應(yīng)該清楚在調(diào)用session_write_close()之后不允許改變?nèi)魏蝧ession變量;在同一個(gè)腳本中,其它同時(shí)發(fā)送給PHP的請(qǐng)求可以鎖定session文件并改變session變量。
為了讓你看到這種問(wèn)題,我創(chuàng)建了測(cè)試代碼并將它上傳到了github。你可以再這里找到測(cè)試腳本。在本地,你需要用一個(gè)實(shí)例來(lái)使用測(cè)試代碼,然后打開(kāi)瀏覽器控制臺(tái),查看請(qǐng)求和響應(yīng)時(shí)間。
正如我們?cè)谶@個(gè)文件中看到的示例代碼,如果我們像下面代碼這樣,創(chuàng)建多個(gè)請(qǐng)求…
同一個(gè)用戶的每個(gè)請(qǐng)求完成之前都將等到前一個(gè)請(qǐng)求完成。它將用時(shí)5s,因?yàn)橹滥_本完成之前,session文件都沒(méi)有被釋放。因此,當(dāng)?shù)谝淮握{(diào)用session_start()時(shí),新的請(qǐng)求將被阻塞。那將殺死異步請(qǐng)求的想法,也就是說(shuō),多個(gè)請(qǐng)求會(huì)在同一時(shí)間被發(fā)送和被執(zhí)行。
如果將文件中的代碼改一下:
第三行代碼將釋放session文件鎖,所以另一個(gè)并發(fā)請(qǐng)求不需要等待就能運(yùn)行,因?yàn)樗梢哉{(diào)用session_start()而不會(huì)有任何問(wèn)題。
總結(jié)
PHP有些微妙,會(huì)讓你擔(dān)心為什么奇怪的事情會(huì)發(fā)生。但是一旦你理解事情是怎么運(yùn)行的,一切將變得有意義,并且你能更好的思考去解決問(wèn)題。
譯文出處:http://www.ido321.com/1577.html
本文根據(jù)@Eslam Mahmoud的《Fix the AJAX Requests that Make PHP Take Too Long to Respond》所譯,整個(gè)譯文帶有我自己的理解與思想,如果譯得不好或有不對(duì)之處還請(qǐng)同行朋友指點(diǎn)。如需轉(zhuǎn)載此譯文,需注明英文出處:http://www.phpclasses.org/blog/post/277-Fix-the-AJAX-Requests-that-Make-PHP-Take-Too-Long-to-Respond.html
總結(jié)
以上是生活随笔為你收集整理的解决AJAX请求使PHP反应时间过长的问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 中国各省份省会地图json数据
- 下一篇: php如何设置随机数字和字母,PHP获取