Zend_Session:在调用start之前清理$ _SESSION

时间:2011-10-05 08:13:55

标签: php zend-framework session

假设一个Web应用程序在php会话中存储了My_Object类的对象,名称为'myobject'。当我打开另一个不存在此类的php应用程序时,Zend_Session :: start()在尝试反序列化My_Object时抛出异常。

因此,我需要清理$ _SESSION变量以摆脱'myobject'。但是要清理$ _SESSION变量,我首先需要调用session_start(),一旦调用它,Zend_Session :: start()会抛出以下异常:

  

未捕获的异常'Zend_Session_Exception',消息'session已由session.auto-start或session_start()'

启动

即使我在调用Zend_Session :: start()之前调用session_destroy(),也会抛出此内容。

有人可以帮我吗?

先谢谢,

埃里克。

编辑:要添加说明,这是我在控制器初始化程序插件上调用的函数:

    protected function _initSession() {
        try {
            session_start();

            unset($_SESSION['myobject']);

            session_destroy();

            Zend_Session::start(); // throws an exception !!!
        }
        catch (Exception $e) {
            echo $e; exit;
        }
    }

编辑2:

为了进一步澄清,这是Zend_Session :: start()遇到未知类时抛出的异常:

  

警告:include_once(My / Object.php):无法打开流:第146行的/usr/local/zend/share/ZendFramework/library/Zend/Loader.php中没有此类文件或目录

现在我写了这篇文章,我想知道我是否应该在实施Zend自动加载器之前启动会话......

3 个答案:

答案 0 :(得分:1)

您使用的是什么版本的Zend Framework?

参考手册说明了这一点:

在对象中使用会话

如果您打算在PHP会话中保留对象,请知道它们将被»序列化以进行存储。因此,从存储中检索时,必须对PHP会话持久化的任何对象进行反序列化。 暗示开发人员必须确保在从会话存储中反序列化对象之前必须已定义持久对象的类。如果未定义未序列化对象的类,则它将成为实例stdClass的。

听起来,一种可能的解决方法是在会话中包含序列化对象的源文件,因此不会遇到该错误。但是它还指出,如果没有定义类,它就会成为stdClass的一个实例,所以既然这不是你看到的行为,那么它似乎是一个bug,或者你可能正在使用旧版本。

答案 1 :(得分:1)

好的,很抱歉回答我自己的问题,但看起来我误解了Zend_Session抛出的异常。问题实际上来自Zend_Loader而不是底层的PHP会话。事实是我在index.php中实现了Zend自动加载器,这不是一个好主意,因为从它实现的那一刻起,Zend_Loader就会尝试自动加载每个没有明确包含的类[编辑:更清楚,它会尝试使用注册的名称空间之一将每个类名称开始实例化 - 在我的代码中,我使用zend loader注册了名称空间“My_”...]

解决方案非常简单:在Zend:Session :: start()之后实现Zend_Loader。我只是在Zend_Session :: start()之后将Zend_Loader的初始化放在我的引导程序中,并且一切正常运行:Zend_Session :: start()将My_Object类反序列化为stdClass(感谢drew010指向正确的方向);这是什么例外。

感谢您的帮助,伙计们。

答案 2 :(得分:0)

通过错误的声音,它听起来不像对象是问题,但是你开始会话的方式是。

“带有消息'会话的未捕获异常'Zend_Session_Exception'已由session.auto-start或session_start()启动;”

protected function _initSession() {
    try {
        **session_start();**

        unset($_SESSION['myobject']);

        session_destroy();

        **Zend_Session::start();** // throws an exception !!!
    }
    catch (Exception $e) {
        echo $e; exit;
    }
}

在此代码中,您正在调用session_start(),然后使用Zend_Session::start()调用。

这暗示如果先前已经调用过会话,则Zend会话会抛出异常。

你可以抓住Exception并选择不做任何事情吗?

protected function _initSession() {
    try {
        session_start();

        unset($_SESSION['myobject']);

        session_destroy();

        Zend_Session::start(); // throws an exception !!!
    }
    catch (Exception $e) {
        echo $e; exit;
    }
    catch (Zend_Session_Exception $zendException)
    {
         // Do nothing, ignore exception
    }
}