Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does session_start lock in PHP?

Tags:

php

session

Originally, I just want to verify that session_start locks on session. So, I create a PHP file as below. Basically, if the pageview is even, the page sleeps for 10 seconds; if the pageview is odd, it doesn't. And, session_start is used to obtain the page view in $_SESSION.

I tried to access the page in two tabs of one browser. It is not surprising that the first tab takes 10 seconds since I explicitly let it sleep. The second tab would not sleep, but it should be blocked by sessiont_start. That works as expected.

To my surprise, the output of the second page shows that session_start takes almost no time. Actually, the whole page seems takes no time to load. But, the page does take 10 seconds to show in browser.

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

Does PHP extract session_start out of PHP page and execute it before other PHP statements?

This is the code.

<?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'];

?>
like image 560
Morgan Cheng Avatar asked Mar 28 '10 01:03

Morgan Cheng


1 Answers

That seems to be a firefox related "issue". If you request the same url in two tabs/windows the second request waits until the first request is finished (could also be an addon that blocks the second request, haven't tested that).
Take e.g.

<?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>';

I called it twice and the output was

start: 1269742677.6094

1269742677.6094
1269742682.609
4.9995958805084

and

start: 1269742682.6563

1269742682.6563
1269742687.6557
4.9994258880615

Note that there's already a 5 second gap between the start times.

When called as http://localhost/test.php and http://localhost/test.php?a=b instead of the exact same url twice this does not happen.
Both IE8 and Chrome do not show that behavior.

like image 131
VolkerK Avatar answered Oct 05 '22 02:10

VolkerK