Я пытаюсь установить сеанс var в методе __destruct ().
Метод __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
}
}
Сессии Symfony используют пользовательские обработчики сессий. (с помощью session_set_save_handler
)
Настраиваемые обработчики сеансов заставляют PHP регистрировать функцию выключения (т.е. register_shutdown_function
), ссылаясь session_register_shutdown
, который добавляет еще один обработчик выключения (чтобы он выполнялся последним), вызывая session_write_close
, эффективно закрывая вашу сессию.
После вызова этой функции дальнейшие записи не будут сохранены. [поскольку обработчик сеанса больше не будет вызываться впоследствии.]
А так как работают только деструкторы (еще не очищенные объекты) после функции выключения были вызваны, эта запись сеанса не удастся.
Единственное решение, позволяющее избежать этого, — это либо не использовать пользовательский обработчик сеанса (я полагаю, это не вариант), либо перезапускать сеанс вручную (если порядок уничтожения не уничтожает класс в первую очередь), либо явное уничтожение всех ссылок на этот объект в обработчиках завершения работы или перед.
Других решений пока нет …