簡單地說,當開啟session_start以后,這個session會一直開啟,並且被一個用戶使用。其他用戶開啟session的話要等待第一個session用戶關閉以后才可以開啟sessio,這樣就造成了session阻塞。而session_write_close()可以解決這個session阻塞機制。
解決session阻塞問題的辦法:在session操作完成后調用session_write_close()即可避免此問題;
下面是session阻塞案例:
案例一:
使用session過程中,在開啟session后,同一瀏覽器,執行同一程序,不同頁面會被鎖。不同瀏覽器不會出現這種情況。
結合了PHP的Session機制,找到了阻塞的原因。由於PHP的Session信息是寫入文件的,1個客戶端占有1個session文件。因此,當 session_start被調用的時候,該文件是被鎖住的,而且是以讀寫模式鎖住的(因為程序中可能要修改session的值),這樣,第2次調用 session_start的時候就被阻塞了。
最簡解決方法:
查了PHP的手冊,發現一個session_write_close函數,作用是Write session data and end session,也就是寫session的數據,同時關閉這個session。因此,我們可以在用完session之后,調用這個函數關閉session 文件即可解除鎖定。一般,session是用來記錄用戶身份信息的,以便PHP進行身份認證,因此完全可以將session的讀寫放在頁面剛開始執行的時 候,在執行完以后,馬上調用session_write_close函數即可。
案例二:
上回說要改opencart其實是給opencart加一個抓取淘寶上的產品的功能,但是弄完后發現一個問題,就是當腳本在抓取的時候,因為這個過程比較慢,這個時候其他所有腳本的執行都被阻塞了,直到抓取完其他腳本才能依次執行。研究了半天沒有結果,在知乎上問了下可能是session的問題,需要調用session_write_close()來解決,那么這個session_write_close()是干嘛用的呢,手冊上這樣寫的:
session數據通常會在腳本執行結束后被保存而並不需要調用session_write_close(),但是為保護session在任何時候都只能被一個腳本執行寫操作,session的數據會被鎖住。當同時使用框架網頁和session時你會發現,框架里的網頁會因為這個個鎖定而逐個載入。你可以通過在所有的session數據修改保存結束后馬上結束session來加快載入時間。
session數據通常會在腳本執行結束后被保存而並不需要調用session_write_close(),但是為保護session在任何時候都只能被一個腳本執行寫操作,session的數據會被鎖住。當同時使用框架網頁和session時你會發現,框架里的網頁會因為這個個鎖定而逐個載入。你可以通過在所有的session數據修改保存結束后馬上結束session來加快載入時間。
這就很好的解釋了為什么我的抓取腳本會阻塞其他頁面的原因。所以,如果你有一個需要執行時間比較長並用到session的ajax請求的話,就需要在服務器端調用session_write_close(),不然你的其他頁面就都會被掛起直到請求結束!!!