2010-03-28 52 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模块确实表现得像一个容器,在这种情况下,它提供了这种程度的会话管理服务。