Подтвердить что ты не робот

Хранение объектов в сеансе PHP

В документации по PHP говорится: "Вы не можете использовать ссылки в переменных сеанса, поскольку нет возможности восстановить ссылку на другую переменную".

Означает ли это, что я не могу иметь такие вещи, как:

session_start();
$user = new User;
$user->name = 'blah';
$_SESSION['user'] = $user;

Я попытался сохранить простую строку и объект User в сеансе, строка всегда сохраняется между страницами на страницы или после обновления страницы. Однако пользовательская переменная теряется в $_SESSION (становится пустой).

любая идея?

Изменить: Я подтвердил, что session_id одинаково во всех этих страницах/подстраницах, до и после обновления страницы.

Изменить: Как ни странно, после того, как я попытался выполнить сериализацию и неэтериализованный подход ниже, сериализованный пользовательский объект (или строка) в сеансе все еще исчезает!

Изменить: наконец, я понял, что это за ошибка, выглядит как-то $_SESSION ['user'], переписывается какой-то таинственной силой, если я использую любую переменную, отличную от "пользователя", тогда все прекрасно. PHP (по крайней мере, 5.3, который является используемой версией) выполняет сериализацию и несериализацию автоматически, когда вы помещаете объект в $_SESSION.

session_start();
$user = new User();
$user->name = 'blah'
$_SESSION['myuser'] = $user; 
4b9b3361

Ответ 1

Для объектов PHP 5 необходимо использовать методы магии __sleep и __wakeup.

Например, в следующем блоке кода:

$obj = new Object();

$_SESSION['obj'] = serialize($obj);

$obj = unserialize($_SESSION['obj']);

__ sleep вызывается serialize(). Метод sleep возвращает массив значений из объекта, который вы хотите сохранить.

__ wakeup вызывается unserialize(). Метод пробуждения должен принимать неэтериализованные значения и инициализировать их в них в объекте.

Ответ 2

В вашем примере кода не используются ссылки, на которые ссылалась документация. Это то, что php означает по ссылкам:

$var =& $GLOBALS["var"];

Что касается помещения объектов в сеанс, PHP может хранить объекты в $_SESSION. См. http://example.preinheimer.com/sessobj.php.

Что вы видите, это ошибка в порядке вызовов __sleep и __destruct (__destruct) до __sleep), а модуль сеанса не может сериализовать объект при выключении. Эта ошибка была открыта 1 сентября 2009 года.

Ответ 3

Вы правильно сказали, что не можете хранить ссылки в переменных сеансов назначение объекта в PHP 5 и выше делает именно это назначение ссылки не obj

Вот почему вам понадобится сериализовать объект (реализующий также __sleep в классе) и присвоение строки переменной сеанса

и десериализуем его позже (также реализуя __wake в классе) из переменной сеанса позже.

Ответ 4

Это ожидаемое поведение. Хранение ссылки на объект будет работать только в том случае, если местоположение памяти для объекта не изменилось. В протоколе без учета состояния, таком как HTTP, состояние приложения не сохраняется между запросами. Следующий запрос может обрабатываться другим потоком, процессом или другим сервером.

Учитывая присущий апатриду характер веб-приложения, удерживание указателя на ячейку памяти бесполезно. Следовательно, состояние объекта должно быть разбито на формат хранения, сохранено или передано, а затем восстановлено, когда это необходимо. Этот процесс известен как Serialization.

Вы можете сериализовать весь объект в сеансе (что может быть опасно в зависимости от глубины вашего графа объектов, поскольку ваш объект может содержать ссылки на другие объекты, и они также должны быть сериализованы), или если объект могут быть восстановлены путем запроса базы данных по следующему запросу, вы можете просто занести идентификатор в сеанс.

[EDIT]

JPot указал, что объекты автоматически сериализуются в $_SESSION, поэтому явная сериализация не требуется. Я оставлю ответ для потомков, но, очевидно, это не поможет вашей проблеме.

Ответ 5

Для безопасной сериализации и несериализации кодируются и декодируются с base64_encode() и base64_decode() соответственно. Ниже я передаю сериализованный объект в сеанс и неэтериализую его на другой странице, чтобы вернуть переменную в состояние объекта.

Page 1

<?php

require  $_SERVER['DOCUMENT_ROOT'] .'/classes/RegistrationClass.php';
$registrationData= new RegistrationClass();
$registrationData->setUserRegData();
$reg_serlizer = base64_encode(serialize($registrationData));   //serilize the object to create a string representation
$_SESSION['regSession'] = $reg_serlizer;
?>

Page 2

<?php
session_start();
require  $_SERVER['DOCUMENT_ROOT'] .'/classes/RegistrationClass.php';
$reg_unserilizeObj = 
unserialize((base64_decode($_SESSION['regSession'])));
$reg_unserilizeObj->firstName;
?>

В этой статье описываются проблемы, с которыми может столкнуться, не делая этого. isuses с сериализацией /unserialization php