2014-04-24 15 views
0

情況:PHP:另類的session_write_close()

我有多個頁面通過菜單訪問,登錄後的站點。 在儀表板頁面(您在登錄後看到的頁面),有一個AJAX調用從PHP控制器(zend框架)獲取數據。這個調用對2個不同的數據庫和大量的數據操作進行了大約20次查詢。加載所有內容可能需要長達5秒的時間。到現在爲止還挺好!

我的問題:

當我去到另一個網頁通過菜單,看到主頁之後,Ajax調用被取消,而新的請求被髮送到一個新的PHP-控制器。但是因爲我正在使用php-sessions(通過zend-framework),所以在session_write_close()被調用之前(在長時間的AJAX請求結束時),我無法做出新的請求。以前的通話是否有可能被取消?

一個沒有體面的解決辦法:

現在,我已經叫session_write_close()在我的AJAX請求的開始,這解決了這個問題。之後,我仍然從會話中讀取,但我已閱讀並確認這不是問題。然而,調用session_write_close()並不是最好的事情,我正在與這個項目上的幾個人合作,這個項目有很多文件和代碼路徑,並且在未來5年內不會完成。所以我不能使用session_write_close(),因爲這是不可維護的。特別是因爲當你寫入會話時,PHP不會拋出異常。數據將不會被保存。

所以我的問題是

是否有一個體面的替代session_write_close(),這讓我打斷/取消AJAX調用(PHP明智),立即去到另一個網頁,或者是有可能會改變一個設置,以便在調用session_write_close()之後嘗試寫入時PHP會拋出異常?

謝謝提前!

回答

0

一種選擇是將會話值存儲在數據庫中。所以一旦你擁有了session_id,你就可以用更新後的值讀寫數據庫。這將是這個樣子:

$session_id = session_id(); 
session_write_close(); 
$query = $dbh->prepare("select * from tbl_sessions where session_id=?"); 
$result = $query->execute(array($session_id)); 
$values = $result->fetch(); 
$session_values = json_decode($values->data); //data would be a text column with a json or serialized array 
//you could update any values then update tbl_sessions if you needed 

或者你可以在這個答案覆蓋諸如默認的會話功能:set session in database in php

或作爲另一個答案,你可以關閉和打開需要的會話: https://stackoverflow.com/a/10046611/1401720

+0

我們無法將會話保存到我們的數據庫,並被迫使用php會話。使用SessionManager可以解決問題,但是仍然不會阻止用戶在關閉後直接寫入會話,並且會對項目產生很大的影響(會話的每次讀/寫都必須更改並通過SessionManager)。 問題不在於解決方案無法正常工作,而在於不會強迫未來的開發預測這些變化。他們仍然可以忽略SessionManager .. –

+0

是的,他們可以忽略它,但這就是爲什麼你應該有編碼標準,並確保所有在項目上工作的開發人員都知道他們。 – Pitchinnate

+0

當客戶端/瀏覽器取消請求時,最好的解決方案是取消AJAX調用的PHP腳本執行。但我還沒有聽說過這樣一個概念:帶有會話的每個請求都會在PHP中排隊,直到調用「session_write_close()」。 –