2011-05-20 129 views
14

我正在使用Apache上的PHP的Web應用程序。 $ _SESSION變量對於必須在頁面間持續存在的信息有相當大的用處。PHP每用戶多個併發會話

我們需要每個用戶都能夠打開多個併發會話,無論是作爲新的選項卡還是新的窗口,具體取決於他們選擇的瀏覽器。現在,當用戶打開添加選項卡或窗口並轉到該網站時,將採用現有會話。我該如何防止這種情況發生,以便用戶必須(或可能)登錄並啓動新會話,而不會干擾他們已經打開的任何現有會話?

我們的臨時解決方法是使用多個瀏覽器(IE和FF),但這顯然不是一種非常好的做事方式。

+0

不可能你需要編寫自己的會話處理腳本,並通如果通過附加到每個URL – 2011-05-20 03:23:53

+2

'通過如果通過附加到每個URL'什麼可能出錯? – 2013-06-07 15:12:49

回答

8

您描述的行爲與瀏覽器會話的概念相反。爲什麼用戶需要多個會話?是否需要執行用戶訪問控制?如果是這樣,請將用戶分配給邏輯組並將權限授予特定組。用戶是否需要代表其他用戶執行某些操作?如果是這樣,圍繞該概念設計網站,而不是試圖爲單個用戶創建多個會話。

如果你真的要做到這一點,你可以做沿查詢參數可怕的事情像通(很有安全感!)的頁面作爲會話ID之間,繞過實際$ _SESSION乾脆管理自己的概念的會議。再次,這是不正常的,將來只會導致頭痛/安全問題。

+1

我們有這個需求的原因是由於應用程序的使用方式。例如銷售人員可能需要在任何給定時間打開多個訂單輸入屏幕。這可能是因爲一個客戶因各種原因需要臨時交給另一個工作人員。然後,銷售人員需要能夠爲隊列中的下一個人啓動新的訂單,而不會干擾已經打開的訂單,這將在原始客戶交還時完成。在舊系統中,這是通過打開應用程序的多個副本(而不是基於Web的)完成的。 – 2011-05-20 03:53:31

+10

啊,我現在明白了。 :)你可以改變你的網站的工作方式,以保持銷售人員在會話中的當前訂單。相反,您可以使用更多REST風格的方法[http://www.xml.com/pub/a/2004/08/11/rest.html],其中銷售人員更新訂單的ID是網絡的一部分頁面的URL。這樣,他們可以打開兩個標籤頁/窗口並修改兩個訂單,並且該會話將完全脫離圖片。 – Dave 2011-05-20 04:11:16

+1

接受上述評論的答案,而不是答案本身。 – 2011-05-23 11:10:56

1

如果可能的話,這將是非常困難的。

會議不應該擔心他們是在哪個選項卡。

另外,如果在標籤1會話1打開一個新窗口會發生什麼?這是一個新的會議?

+0

這是我可以找到關於此事的最好的寫法:http://www.php.net/manual/en/ ref.session.php#74557 – 2011-05-20 03:09:53

+0

@onteria_這似乎已被濫用:所以,每一個鏈接,表單,header()和Javascript代碼都會將SESSION_NAME的值轉發給下一個腳本,它會知道它必須使用哪個會話。' – 2013-06-07 14:45:21

2

非原子併發會話管理的訪問可以使用下面的僞編碼邏輯模擬:

function main(){ 
    $locker = new SessionLocking(); 
    /** read elements the $_SESSION "cached" copy. **/ 
    $var1 = $_SESSION['var1']; 
    $var2 = $_SESSION['var2']; 
    /** Pseudo Atomic Read **/ 
    $locker->lock(); //session is locked against concurrent access. 
    $var3 = $_SESSION['var3']; 
    $locker->unlock(); //session is committed to disk (or other) and can be accessed by another script. 
    /** Psuedo Atomic Write **/ 
    $locker->lock(); //session is locked against concurrent access. 
    $_SESSION['var4'] = "Some new value"; 
    $locker->unlock(); //session is committed to disk (or other) and can be accessed by another script 
} 

CLASS SessionLocking { 

private static $lockCounter=0; 
private static $isLoaded=false; 

function __constructor(){ 
    if (!self::$isLoaded) load(); 
} 

private function load(){ 
$this->lock(); 
$this->unlock(); 
} 

private function lock(){ 
    if ($lockCounter<1) try {session_start();} Catch(){} 
    $lockCounter++; 
} 

private function unlock(){ 
    if ($lockCount<1) return; 
    $lockCounter--; 
    if ($lockCounter<1) try {session_write_close();} Catch(){} 
} 
} 
-2

這裏是一個辦法做到這一點:在php.ini

- 首先禁用會話cookie與:

session.use_cookies = 0 

這可以確保cookie不被用於傳遞會話ID。

- 那麼請確保您生成所有URL與包括會話ID(你得到它通過函數的session_id(),例如:

print "<a href= \"http://www.example.com/".session_id()."&showlist=1\">show list</a>";