在 PHP 中,多次运行 session_start() 有什么坏处吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2580322/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 07:00:01  来源:igfitidea点击:

In PHP, is there any harm in running session_start() multiple times?

phpsession

提问by sprugman

Presumably there's some tiny performance hit, but beyond that?

大概有一些微小的性能损失,但除此之外?

采纳答案by Chad Birch

From the docs:

文档

As of PHP 4.3.3, calling session_start() after the session was previously started will result in an error of level E_NOTICE. Also, the second session start will simply be ignored.

从 PHP 4.3.3 开始,在会话之前启动后调用 session_start() 将导致级别为 E_NOTICE 的错误。此外,第二个会话开始将被简单地忽略。

So no, it won't "cause harm", but it'll throw an error. And the fact that it's happening is probably an indicator that you're doing something incorrectly, and might need to re-think how your code is laid out.

所以不,它不会“造成伤害”,但会引发错误。它发生的事实可能表明您做错了某些事情,可能需要重新考虑您的代码是如何布局的。

回答by rkulla

As of PHP 4.3.3, calling session_start() while the session has already been started will result in an E_NOTICE warning. The second call to session_start() will simply be ignored.You could check if the session has been started first or not with:

从 PHP 4.3.3 开始,在会话已经启动时调用 session_start() 将导致 E_NOTICE 警告。对 session_start() 的第二次调用将被忽略。您可以使用以下命令检查会话是否已首先启动:

if (session_id() == "")
  session_start();

回答by Sander Visser

Calling session_start(); can harm the performance of your application.

调用 session_start(); 可能会损害应用程序的性能。

The following code will trigger an E_NOTICE, but won't harm that much performance wise

以下代码将触发 E_NOTICE,但不会对性能造成太大影响

<?php
session_start();
session_start();
?>

But calling the following will harm the performance! But it's still useful. If you have a script that takes like 3 minutes to run and is called with XHR (js). In this case it's useful to use the session_write_close. otherwise the request to the server is blocked until the sessions are released. It could happen that you want to use the sessions at the start of the script and at the end of the script.

但是调用以下会损害性能!但它仍然有用。如果您有一个脚本需要大约 3 分钟才能运行并使用 XHR (js) 调用。在这种情况下,使用 session_write_close 很有用。否则对服务器的请求将被阻塞,直到会话被释放。您可能希望在脚本开始和结束时使用会话。

<?php
session_start();
session_write_close();
session_start();
?>

But, when you call the session_start(); all information is deserialized, and when you call session_write_closed() it's serialized. So if you have a lot of data it can be really slow!

但是,当你调用 session_start(); 所有信息都被反序列化,当你调用 session_write_closed() 时,它被序列化。所以如果你有很多数据,它可能真的很慢!

The following test shows how much impact it has.

下面的测试显示了它有多大的影响。

1.0130980014801 sesion_start + close with empty session

1.0130980014801 session_start + 以空会话结束

1.0028710365295 normal loop without session

1.0028710365295 没有会话的正常循环

12.808688879013 a lot data in the session with start + close

12.808688879013 会话中有大量数据,开始 + 关闭

1.0081849098206 normal loop again (useless kinda)

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);
}
?>

回答by vicvicvic

Reading the docs for session_start, all I can see is:

阅读 session_start 的文档,我只能看到:

As of PHP 4.3.3, calling session_start()after the session was previously started will result in an error of level E_NOTICE. Also, the second session start will simply be ignored.

从 PHP 4.3.3 开始,session_start()在会话之前启动之后调用将导致 level 错误E_NOTICE。此外,第二个会话开始将被简单地忽略。

So, you'll get an E_NOTICEand be ignored.

所以,你会得到一个E_NOTICE并被忽略。

回答by Super Cat

If it produces an error, odds are that the developers didn't intend for that particular action to occur. So yes, despite what you're shown by W3Schools, it's technically a 'bad' thing to do.

如果它产生错误,很可能是开发人员不打算发生该特定操作。所以是的,尽管 W3Schools 向您展示了什么,但从技术上讲,这是一件“坏事”。

So, rather than play it safe and try to set the session on each page, why not firstcheck to see if the session exists before you move forward?

因此,与其安全地尝试在每个页面上设置会话,不如在继续之前检查会话是否存在?

  if ( !isset($_SESSION) ) session_start();

Personally, I'd check for the existence of the session's cookie first.

就个人而言,我会首先检查会话的 cookie 是否存在。

回答by dkinzer

I usually put a session start statement in an include file that I require_once. But I don't think there should be an issue with multiple calls.

我通常将会话开始语句放在我 require_once 的包含文件中。但我认为多次调用不应该有问题。

回答by Syntax Error

If the session is already open, then it will return an error notice, and the new session will be ignored. So no harm is done, but you will have a pesky error.

如果会话已经打开,则返回错误通知,新会话将被忽略。所以不会造成任何伤害,但你会遇到一个讨厌的错误。

But... if you are finding the need to do this then it could be a symptom that your code is not organized well. It would probably be in your benefit to see how you can keep yourself from repeating redundant tasks like starting a session.

但是...如果您发现需要这样做,则可能是您的代码组织得不好的症状。了解如何避免重复诸如开始会话之类的冗余任务可能对您有利。