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

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

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

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

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

Есть идеи?

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

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

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

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

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

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

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

 $obj = new Object(); $_SESSION['obj'] = serialize($obj); $obj = unserialize($_SESSION['obj']); 

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

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

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

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

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

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

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

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

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

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

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

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

[РЕДАКТИРОВАТЬ]

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

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

Страница 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; ?> 

Страница 2

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

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