我尝试在__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
}
}
答案 0 :(得分:4)
Symfony会话正在使用自定义会话处理程序。 (通过session_set_save_handler
)
自定义会话处理程序使PHP注册一个关闭函数(即register_shutdown_function
),调用session_register_shutdown
,这会添加另一个关闭处理程序(因此它将在最后执行),调用session_write_close
,然后有效地关闭你的会话。
调用该函数后,将不再存储进一步的写入操作。 [因为会话处理程序之后不再被调用。]
由于析构函数(尚未清理的对象)仅在之后运行,因此调用了关闭函数,此会话写入将失败。
避免这种情况的唯一解决方案是要么不使用自定义会话处理程序(我猜不是你的选项),手动重启会话(只要破坏顺序不会先破坏类),或明确地破坏所有在关机处理程序中或之前对此对象的引用。