2010-03-28 54 views
7

最初,我只想驗證session_start鎖定會話。所以,我創建一個PHP文件如下。基本上,如果瀏覽量是均勻的,頁面會睡10秒;如果綜合瀏覽量很奇怪,則不會。並且,session_start用於獲取中的頁面視圖$ _SESSIONPHP中session_start如何鎖定?

我試圖訪問一個瀏覽器的兩個選項卡中的頁面。第一個標籤在我明確讓它入睡之後需要10秒鐘就不足爲奇了。第二個標籤不會睡覺,但應該被sessiont_start阻止。這按預期工作。

令我驚訝的是,第二頁的輸出顯示session_start幾乎沒有時間。實際上,整個頁面似乎沒有時間加載。但是,該頁面在瀏覽器中顯示需要10秒鐘。

obtained lock 
Cost time: 0.00016689300537109 
Start 1269739162.1997 
End 1269739162.1998 
allover time elpased : 0.00032305717468262 
The page views: 101 

PHP是否提取在session_start了PHP頁面之前其他PHP語句執行呢?

這是代碼。

<?php 

function float_time() 
{ 
    list($usec, $sec) = explode(' ', microtime()); 
    return (float)$sec + (float)$usec; 
} 

$allover_start_time = float_time(); 

$start_time = float_time(); 

session_start(); 

echo "obtained lock<br/>"; 
$end_time = float_time(); 

$elapsed_time = $end_time - $start_time; 
echo "Cost time: $elapsed_time <br>"; 
echo "Start $start_time<br/>"; 
echo "End $end_time<br/>"; 
ob_flush(); 
flush(); 


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

if ($_SESSION['views'] % 2 == 0) 
{ 
    echo "sleep 10 seconds<br/>"; 
    sleep(10); 
} 

$allover_end_time = float_time(); 
echo "allover time elpased : " . ($allover_end_time - $allover_start_time) . "<br/>"; 

echo "The page views: " . $_SESSION['views']; 

?> 
+1

注意microtime(1)有用的參數,使float_time函數過時。 – 2010-03-28 01:36:43

+0

比較兩個「開始」值。第二個例子在第一個例子10秒後「開始」嗎? – VolkerK 2010-03-28 01:39:52

+0

我無法確認你的結果。通過在兩個選項卡中重新加載以獲得更多請求,我首先按預期運行10秒和其他8秒。瀏覽器Chrome,PHP5.2.5,Win – 2010-03-28 01:44:09

回答

4

這似乎是一個Firefox相關的「問題」。如果您在兩個選項卡/窗口中請求相同的URL,則第二個請求會一直等到第一個請求完成(也可能是一個阻止第二個請求的插件,但沒有測試過)。

<?php // test.php 
$start = microtime(true); 
echo "<pre>start: $start</pre>"; 
sleep(5); 
$end = microtime(true); 

echo '<pre>', $start, "\n", $end, "\n", $end-$start, '</pre>'; 

我把它叫做兩次輸出功率爲

start: 1269742677.6094 

1269742677.6094 
1269742682.609 
4.9995958805084 

start: 1269742682.6563 

1269742682.6563 
1269742687.6557 
4.9994258880615 

注意,有已經開始時間之間有5秒鐘的間隔。

當被調用爲http://localhost/test.phphttp://localhost/test.php?a=b而不是兩次完全相同的URL時,這種情況不會發生。
IE8和Chrome都不顯示該行爲。

+0

哇!你是對的!你怎麼知道? 我從來沒有想過這可能是由於瀏覽器「問題」。 – 2010-03-28 07:10:22

+0

這或多或少是偶然的;-) – VolkerK 2010-03-28 11:14:35

+1

在示例session_start()中缺少,原來的問題在那裏。你有嘗試過嗎?除非使用session_write_close()釋放鎖,否則session_start()將阻止來自同一會話的其他請求。 http://www.php.net/manual/en/function.session-start.php#101452 – Murukesh 2011-04-19 15:26:14

1

是的,這可能是因爲在session_start()的阻塞在同一個會話的其他請求(基於文件)。我能夠使用默認會話處理程序(文件)在Windows XP/PHP 5.2中的Firefox(4.x)和Chrome(10.x)中驗證問題。我不確定這個問題對於非文件會話處理程序是否可重現。

obtained lock 
**Cost time: 9.90100598335** 
Start 1303227658.67 
End 1303227668.57 
sleep 10 seconds 
allover time elpased : 19.9027831554 
The page views: 4 

這是一個非常有趣的問題,並在上​​面的回答中描述的Firefox標籤鎖定會黯然失色被檢測這一項。

http://www.php.net/manual/en/function.session-start.php#101452

0

由於php沒有容器。兩個對同一會話的調用如何被序列化?這是誰?這兩個過程如何交談? PHP模塊是否始終處於活動狀態,並且僅在進行會話檢查後才產生線程?在這種情況下,PHP模塊確實表現得像一個容器,在這種情況下,它提供了這種程度的會話管理服務。