1

我尝试在 __destruct() 方法中设置会话变量。方法 __destruct() 正在运行,但未设置会话变量。同时,__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
    }

}
4

1 回答 1

4

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

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

调用该函数后,将不再存储任何写入。[因为会话处理程序将不再被调用。]

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

避免这种情况的唯一解决方案是不使用自定义会话处理程序(我猜这不是您的选择),手动重新启动会话(只要破坏顺序不首先破坏类),或者显式破坏对此对象在关闭处理程序或之前。

于 2016-08-26T14:55:21.307 回答