为什么我不能在__destruct()方法中设置session var?

时间:2016-08-26 14:39:48

标签: php symfony session session-set-save-handler

我尝试在__destruct()方法中设置session var。 方法__destruct()正在运行,但会话var未设置。 而__contruct()中的会话或其他方法(例如test())按预期工作。

public function test()
{
    $_SESSION['MyVarTest'] = rand(200,300); ← working correctly
}

public function __destruct()
{
    echo 'called';
    $_SESSION['MyVar'] = rand(1,100); ← not working
}

更新版本。现在我尝试本机PHP Session和Symfony组件,两者都不能在__destruct()方法中工作。

<?php

namespace Project\Modules\Cart\Storage;

use Illuminate\Support\Collection;

class Session
{

    /**
     * @var \Symfony\Component\HttpFoundation\Session\Session
     */
    protected $session;

    protected $cart;

    public function __construct()
    {
        $this->cart  = new Collection();

        $this->session = app('session');
        print_r($_SESSION);

    }

    public function test()
    {
        $this->session->set('json', rand(1,100));  ← working correctly
        $_SESSION['json'] = rand(1,100);  ← working correctly
        return $this->cart->toJson();
    }

    public function __destruct()
    {
        echo 'called';
         $_SESSION['MyVar'] = rand(1,100); ← not working

        $this->session->set('cart', serialize($this->cart->toArray()));  ← not working
    }

}

1 个答案:

答案 0 :(得分:4)

Symfony会话正在使用自定义会话处理程序。 (通过session_set_save_handler

自定义会话处理程序使PHP注册一个关闭函数(即register_shutdown_function),调用session_register_shutdown,这会添加另一个关闭处理程序(因此它将在最后执行),调用session_write_close,然后有效地关闭你的会话。

调用该函数后,将不再存储进一步的写入操作。 [因为会话处理程序之后不再被调用。]

由于析构函数(尚未清理的对象)仅在之后运行,因此调用了关闭函数,此会话写入将失败。

避免这种情况的唯一解决方案是要么不使用自定义会话处理程序(我猜不是你的选项),手动重启会话(只要破坏顺序不会先破坏类),或明确地破坏所有在关机处理程序中或之前对此对象的引用。