【发布时间】:2011-02-04 12:54:10
【问题描述】:
大概有一些微小的性能影响,但除此之外?
【问题讨论】:
大概有一些微小的性能影响,但除此之外?
【问题讨论】:
从 PHP 4.3.3 开始,在会话已经启动时调用 session_start() 将导致 E_NOTICE 警告。对 session_start() 的第二次调用将被忽略。您可以检查会话是否首先启动:
if (session_id() == "")
session_start();
【讨论】:
来自the docs:
从 PHP 4.3.3 开始,在会话之前启动之后调用 session_start() 将导致 E_NOTICE 级别的错误。此外,第二个会话开始将被忽略。
所以不,它不会“造成伤害”,但会引发错误。而且它正在发生的事实可能表明你做错了,可能需要重新考虑你的代码是如何布局的。
【讨论】:
调用 session_start();可能会损害您的应用程序的性能。
以下代码将触发 E_NOTICE,但不会对性能造成太大影响
<?php
session_start();
session_start();
?>
但是调用以下会损害性能! 但它仍然有用。如果您有一个脚本需要 3 分钟才能运行并使用 XHR (js) 调用。 在这种情况下,使用 session_write_close 很有用。否则,对服务器的请求将被阻止,直到会话被释放。您可能希望在脚本的开头和结尾使用会话。
<?php
session_start();
session_write_close();
session_start();
?>
但是,当你调用 session_start();所有信息都被反序列化,当你调用 session_write_closed() 它被序列化。 所以如果你有很多数据,它可能真的很慢!
以下测试显示了它有多大的影响。
1.0130980014801 session_start + 以空会话关闭
1.0028710365295 没有会话的正常循环
12.808688879013 会话中有很多数据,开始+关闭
1.0081849098206 再次正常循环(有点没用)
<?php
//start and clear first session
session_start();
session_destroy();
session_write_close();
//test one
if(true) {
//test loop one
$start = microtime(true);
for($i = 0; $i < 1000; $i++) {
session_start();
usleep(100);
session_write_close();
}
$end = microtime(true);
echo($end - $start);
//test loop 2
echo('<br />');
$start = microtime(true);
for($i = 0; $i < 1000; $i++) {
usleep(100);
}
$end = microtime(true);
echo($end - $start);
}
//fill the array with information so serialization is needed
session_start();
$_SESSION['test'] = array();
for($i = 0; $i < 10000; $i++) {
$_SESSION['test'][$i] = chr($i);
}
session_write_close();
echo('<br />');
//test two
if(true) {
//test loop one
$start = microtime(true);
for($i = 0; $i < 1000; $i++) {
session_start();
usleep(100);
session_write_close();
}
$end = microtime(true);
echo($end - $start);
//test loop 2
echo('<br />');
$start = microtime(true);
for($i = 0; $i < 1000; $i++) {
usleep(100);
}
$end = microtime(true);
echo($end - $start);
}
?>
【讨论】:
阅读 session_start 的文档,我只能看到:
从 PHP 4.3.3 开始,在会话之前启动后调用
session_start()将导致级别为E_NOTICE的错误。此外,第二个会话开始将被忽略。
因此,您将收到 E_NOTICE 并被忽略。
【讨论】:
如果它产生错误,很可能是开发人员不打算发生该特定操作。所以是的,尽管 W3Schools 向您展示了这些内容,但从技术上讲,这是一件“坏事”。
因此,与其安全起见并尝试在每个页面上设置会话,不如首先在继续之前检查会话是否存在?
if ( !isset($_SESSION) ) session_start();
就我个人而言,我会先检查会话的 cookie 是否存在。
【讨论】:
session_start(),开发人员应该注意到任何进一步的调用,但不能忽略。使用@ 错误抑制的相同原因是code smell。
我通常将会话开始语句放在我需要一次的包含文件中。但我认为多次调用应该没有问题。
【讨论】:
如果会话已经打开,那么它将返回错误通知,并且新会话将被忽略。所以不会造成任何伤害,但你会遇到一个讨厌的错误。
但是...如果您发现需要这样做,那么这可能是您的代码组织得不好的症状。看看如何让自己避免重复多余的任务,比如开始一个会话,这可能对你有好处。
【讨论】: