【问题标题】:In PHP, is there any harm in running session_start() multiple times?在 PHP 中,多次运行 session_start() 有什么害处吗?
【发布时间】:2011-02-04 12:54:10
【问题描述】:

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

【问题讨论】:

    标签: php session


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      来自the docs

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

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

      【讨论】:

        【解决方案3】:

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

        【讨论】:

          【解决方案4】:

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

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

          因此,您将收到 E_NOTICE 并被忽略。

          【讨论】:

            【解决方案5】:

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

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

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

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

            【讨论】:

            • 最好不要查。在一个干净的架构中,在正确的位置只有一个session_start(),开发人员应该注意到任何进一步的调用,但不能忽略。使用@ 错误抑制的相同原因是code smell
            【解决方案6】:

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

            【讨论】:

              【解决方案7】:

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

              但是...如果您发现需要这样做,那么这可能是您的代码组织得不好的症状。看看如何让自己避免重复多余的任务,比如开始一个会话,这可能对你有好处。

              【讨论】:

                猜你喜欢
                • 2016-05-04
                • 1970-01-01
                • 2011-06-18
                • 2011-12-19
                • 2011-01-07
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2019-09-06
                相关资源
                最近更新 更多