session_start如何在PHP中锁定?

时间:2010-03-28 01:26:02

标签: php session

最初,我只想验证 session_start 锁定会话。所以,我创建了一个PHP文件,如下所示。基本上,如果网页浏览是偶数,页面会休眠10秒;如果网页浏览是奇数,则不是。并且, session_start 用于获取 $ _ SESSION 中的网页视图。

我尝试在一个浏览器的两个标签页中访问该页面。因为我明确地让它睡了所以第一个标签需要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是否从PHP页面中提取 session_start 并在其他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'];

?>

3 个答案:

答案 0 :(得分: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而不是两次完全相同的网址时,这不会发生。
IE8和Chrome都没有显示出这种行为。

答案 1 :(得分: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

答案 2 :(得分:0)

因为php没有容器。如何对同一会话的两个调用进行序列化?谁这样做?这两个过程如何对话? PHP模块是否始终处于活动状态,并且仅在进行会话检查后生成线程?在这种情况下,PHP模块的行为确实像一个容器,在这种情况下,就是在这种程度上提供会话管理服务。