Я только что понял, что на самом деле могу хранить объекты в $ _SESSION, и я нахожу это довольно круто, потому что при переходе на другую страницу у меня все еще есть мой объект. Теперь, прежде чем я начну использовать этот подход, я хотел бы выяснить, действительно ли это хорошая идея или есть потенциальные подводные камни .
Я знаю, что если бы у меня была единственная точка входа, мне не нужно было бы этого делать, но я еще не там, поэтому у меня нет единой точки входа, и я действительно хотел бы сохранить свой объект, потому что я не не могу так потерять свое состояние. (Теперь я также прочитал, что я должен программировать сайты без сохранения состояния, но я пока не понимаю этой концепции.)
Итак, вкратце : нормально ли хранить объекты в сеансе, есть ли проблемы с этим?
Редактировать:
Временное резюме : к настоящему времени я понимаю, что, вероятно, лучше воссоздать объект, даже если он требует повторного запроса к базе данных.
Дальнейшие ответы могли бы развить этот аспект немного подробнее!
Ответы:
Я знаю, что эта тема старая, но эта проблема продолжает появляться и не была обращена к моему удовлетворению:
Сохраняете ли вы объекты в $ _SESSION, или восстанавливаете их целиком на основе данных, хранящихся в скрытых полях формы, или повторно запрашиваете их из БД каждый раз, вы используете состояние. HTTP не имеет состояния (более или менее; но смотрите GET vs. PUT), но почти все, что кто-либо заботится о веб-приложении, требует сохранения состояния где-то. Действовать так, будто толкать государство в укромные уголки равносильно некоторой теоретической победе, просто неправильно. Государство есть государство. Если вы используете состояние, вы теряете различные технические преимущества, получаемые при отсутствии состояния. Это не то, чтобы потерять сон, если вы заранее не знаете, что вам следует потерять сон из-за этого.
Я особенно озадачен благословением, полученным "двойным ударом" аргументов, выдвинутых Хэнком Гаем. Создает ли ОП распределенную систему электронной коммерции с балансировкой нагрузки? Мое предположение нет; и я буду далее утверждать, что сериализация его класса $ User, или что-то еще, не повредит его серверу без возможности восстановления. Мой совет: используйте методы, которые подходят для вашего приложения. С объектами в $ _SESSION все в порядке, с учетом здравого смысла. Если ваше приложение вдруг превратится во что-то конкурирующее с Amazon по трафику, вам нужно будет заново адаптировать его. Такова жизнь.
источник
все в порядке, пока к моменту вызова session_start () объявление / определение класса уже встречено PHP или может быть найдено уже установленным автозагрузчиком. в противном случае он не сможет десериализовать объект из хранилища сеансов.
источник
__autoload()
функция.HTTP является протоколом без сохранения состояния по причине. Сеансы сваривают состояние по HTTP. Как правило, избегайте использования состояния сеанса.
ОБНОВЛЕНИЕ: нет концепции сеанса на уровне HTTP; серверы предоставляют это, предоставляя клиенту уникальный идентификатор и сообщая ему о необходимости повторной отправки при каждом запросе. Затем сервер использует этот идентификатор в качестве ключа в большой хэш-таблице объектов Session. Всякий раз, когда сервер получает запрос, он ищет информацию о сеансе в своей хэш-таблице объектов сеанса на основе идентификатора, предоставленного клиентом вместе с запросом. Вся эта дополнительная работа - двойной удар по масштабируемости (большая причина, по которой HTTP не сохраняет состояния).
Учитывая все это, чем больше информации вы добавляете в сеанс, тем больше влияние на производительность (как указывает Винко). Также, как указывает Винко, если ваш объект не сериализуем, сеанс будет вести себя неправильно. Поэтому, как правило, избегайте внесения в сессию большего, чем необходимо.
@Vinko Обычно вы можете обойти состояние хранилища сервера, внедрив данные, которые вы отслеживаете, в ответ, который вы отправляете обратно, и попросив клиента отправить его повторно, например, отправив данные в скрытый вход. Если вам действительно нужно отслеживание состояния на стороне сервера, оно, вероятно, должно быть в вашем резервном хранилище данных.
(Винко добавляет: PHP может использовать базу данных для хранения информации о сеансе, и если клиент повторно отправляет данные каждый раз, это может решить потенциальные проблемы с масштабируемостью, но открывает большой круг вопросов безопасности, на которые нужно обратить внимание, поскольку клиент контролирует все ваше состояние)
источник
O(1)
сказать вам что - нибудь? @ whammy два: просто не случайным образом перенаправить все запросы на случайные серверы? выполните циклический перебор и продолжайте маршрутизацию на один и тот же сервер от одного и того же пользователя. Это вау, супер очевидно. Вы должны вернуться к своим книгам вместе со всеми более 30 голосами противКроме этого я не видел проблем.
источник
По моему опыту, это, как правило, не стоит ничего более сложного, чем StdClass с некоторыми свойствами. Стоимость десериализации всегда была больше, чем воссоздание из базы данных с сохраненным в сеансе идентификатором. Это кажется классным, но (как всегда), профилирование - это ключ.
источник
Я бы предложил не использовать состояние, если оно вам абсолютно не нужно. Если вы можете перестроить объект без использования сессий, сделайте это. Наличие состояний в вашем веб-приложении делает приложение более сложным для построения, для каждого запроса вы должны видеть, в каком состоянии находится пользователь. Конечно, бывают случаи, когда вы не можете избежать использования сеанса (пример: пользователь должен сохранять логин во время своего сеанса на веб-приложение). В заключение я хотел бы предложить, чтобы ваш объект сеанса был как можно меньшим, так как это влияет на производительность для сериализации и десериализации больших объектов.
источник
Вы должны помнить, что типы ресурсов (например, соединения БД или файловые указатели) не сохраняются между загрузками страниц, и вам нужно будет их невидимо воссоздать.
Также учитывайте размер сеанса, в зависимости от того, как он хранится, у вас могут быть ограничения по размеру или проблемы с задержкой.
источник
Я также упоминал бы об обновлении библиотек программного обеспечения - мы обновили наше программное обеспечение, и у старой версии были объекты в сеансе с именами классов программного обеспечения V1, новое программное обеспечение терпело крах, когда оно пыталось построить объекты, которые были в сеансе - как V2 Программное обеспечение больше не использовало те же классы, оно не могло их найти. Нам пришлось вставить некоторый код исправления, чтобы обнаружить объекты сеанса, удалить сеанс, если он найден, перезагрузить страницу. Изначально самой большой болью было то, что вы воссоздали эту ошибку, когда о ней впервые сообщили (слишком знакомо, «ну, это работает для меня» :), поскольку она затрагивала только людей, которые недавно использовали старые и новые системы - однако, хорошо работу, которую мы нашли перед запуском, так как все наши пользователи наверняка имели бы старые переменные сеанса в своих сеансах и могли бы потерпеть крах для всех,
В любом случае, как вы предлагаете в своей поправке, я также думаю, что лучше воссоздать объект. Так что, может быть, просто сохранить идентификатор и затем при каждом запросе извлекать объект из базы данных лучше / безопаснее.
источник