Zend抛出“Session already started”异常,但我没有开始会话,这是怎么回事?

3
Fatal error: Uncaught exception 'Zend_Session_Exception' with message 'session has already been started by session.auto-start or session_start()' in /usr/include/ZendFramework-1.11.3/library/Zend/Session.php on line 462

每次重新加载页面时都会发生这种情况。我已经做过的事情:

  • Ensured that session.autostart=0 in my php.ini
  • searched my entire application for calls to session_start(), there are none
  • placed the following session configuration information in my config.ini:

    resources.session.save_path = APPLICATION_PATH "/../data/session"
    resources.session.use_only_cookies = true
    resources.session.remember_me_seconds = 864000
    
  • removed the above from my config.ini, didn't make a difference

  • restarted apache, several times
  • finally I only use Zend_Session_Namespace(), which is initialized in my controller's init() function.

每次我都会收到这个错误。是什么原因呢?我还有哪些地方没有检查?除了Zend库之外,"session"这个词只在这个控制器中出现:

<?php

class ContributeController extends Zend_Controller_Action
{
    private $_session;

    private function getSession() {
        return $this->_session;
    }

    public function init()
    {
        $this->_session = new Zend_Session_Namespace('contribute');
    }

    public function indexAction()
    {
        // action body
    }

    public function addAction() {
        $this->getSession()->form = new Application_Form_Contribute_Add_Main();
        $this->view->form = $this->getSession()->form;
    }

    public function importAction() {}


}

?>

这是对我的php.ini文件执行grep搜索的结果,搜索关键词为^session:
session.save_handler = files
session.use_cookies = 1
session.name = PHPSESSID
session.auto_start = 0
session.cookie_lifetime = 0
session.cookie_path = /
session.cookie_domain =
session.cookie_httponly = 
session.serialize_handler = php
session.gc_divisor     = 100
session.gc_maxlifetime = 1440
session.bug_compat_42 = 1
session.bug_compat_warn = 1
session.referer_check =
session.entropy_length = 0
session.entropy_file =
session.cache_limiter = nocache
session.cache_expire = 180
session.use_trans_sid = 0
session.hash_function = 0
session.hash_bits_per_character = 4

session.auto_start,明确为关闭状态。

为什么每次都会出现这个错误?这是怎么回事?

编辑 目前看来,当我试图存储那个表单时,这可能是由于尝试存储太多内容到会话中导致的。当我重写我的代码,只存储简单的数组来概述表单的结构时,错误消失了,并且没有再出现过。如果它重新出现而我不确定它不会,我可能会再次回到这里。


请问你能解释一下“每次重新加载都会发生”吗? - Adrian World
2
@Adrian World - 我认为他的意思是“在每个请求上”,或者每次他访问一个页面。 - karim79
2
@Adrian World,karim79是正确的。 - Daniel Bingham
由于您已经在php.ini中使用了grep命令查找了“session.auto-start”(提示:检查“phpinfo()”以及源代码,它是一个“PHP_INI_ALL”设置),因此您还可以使用grep命令查找“session_start”的源代码。 - hakre
<?php 标签之前,空格或 bom 签名会怎么样? - Dmytro Zavalkin
3个回答

2

请检查您在application.ini中定义的会话数据文件夹是否存在且可写:如果不是这种情况,则会抛出相同的异常,并显示此虚假消息。


我曾经遇到过这个问题。我的配置文件中会话路径名称有一个拼写错误。在这种情况下,这确实不是一个有用的错误信息。 - Cvuorinen

1
我能想到的唯一可能被忽略的事情,就是你的应用程序(例如启动文件)中是否有这个调用:
Zend_Session::start();

我尝试过了。在引导程序中调用它会失败。在 $application 之前调用它有时可以工作,但是错误仍然会在某些刷新时弹出。即便如此,那感觉像是一个hack和一个临时措施,并没有解释更大的原因。我目前正在测试的一个理论是我的表单对于会话来说太大了,导致它在序列化时出现问题。 - Daniel Bingham

1

好的,那么在Zend_Session_Namespace构造函数中将debug_trace()转储到文件中,看看每个请求得到什么。这至少应该向您展示原因在Zend之外,或确实存在两个紧密的调用,特别是它们来自哪里。

我认为您在内部重新加载表单页面,导致init()控制器运行两次。像karim79建议的那样在引导程序中更早地启动会话应该可以解决这些问题。


为什么在Zend_Session_Namespace()上新调用两次会生成此错误呢?我不应该能够调用它以获取多个命名空间吗?当我在同一命名空间上调用它并优雅地处理时,它不应该检测到吗? - Daniel Bingham
理论上是可以的,但当Zend_Session被重置时会有一定的条件。但是我在你上面的更新中看到,这可能不是你的问题。 - Adrian World
虽然Adrian World没有提到这种情况的真实性,但我发现当Zend_Session_Namespace对象被标记为收集时,GC将会收集Zend_Session。在我的引导程序中添加Zend_Session :: start()调用后,问题得以解决。 - Ryan Bales

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接