Pregunta

Acabo de darme cuenta de que realmente puedo almacenar objetos en la $ _SESSION y me parece genial porque cuando salto a otra página todavía tengo mi objeto. Ahora, antes de comenzar a usar este enfoque, me gustaría saber si realmente es una buena idea o si hay peligros potenciales involucrados.

Sé que si tuviera un solo punto de entrada no tendría que hacer eso, pero aún no estoy allí, así que no tengo un solo punto de entrada y realmente me gustaría conservar mi objeto porque No pierdo mi estado así. (Ahora también he leído que debo programar sitios sin estado pero todavía no entiendo ese concepto).

Entonces en breve : ¿está bien almacenar objetos en la sesión, hay algún problema con esto?


Editar:

Resumen temporal : a estas alturas, entiendo que probablemente sea mejor recrear el objeto, incluso si se trata de volver a consultar la base de datos.

Otras respuestas podrían tal vez profundizar en ese aspecto un poco más!

¿Fue útil?

Solución

Sé que este tema es antiguo, pero este problema sigue apareciendo y no se ha solucionado satisfactoriamente:

Ya sea que guarde objetos en $ _SESSION, o los reconstruya todo el paño basándose en datos ocultos en campos de formulario ocultos, o vuelva a consultarlos desde la base de datos cada vez, está usando el estado. HTTP no tiene estado (más o menos, pero vea GET vs. PUT) pero casi todo lo que a alguien le importa hacer con una aplicación web requiere que el estado se mantenga en algún lugar. Actuar como si empujar el estado hacia los recovecos y las grietas equivalga a algún tipo de ganancia teórica es simplemente incorrecto. Estado es estado Si usas el estado, pierdes las diversas ventajas técnicas ganadas por ser apátrida. Esto no es algo para perder el sueño a menos que sepa de antemano que debería estar perdiendo el sueño por ello.

Estoy especialmente desconcertado por la bendición recibida por el "doble golpe" Argumentos presentados por Hank Gay. ¿El OP está construyendo un sistema de comercio electrónico distribuido y con carga equilibrada? Mi conjetura es no; y además postularé que serializar su clase de $ User, o lo que sea, no paralizará su servidor más allá de la reparación. Mi consejo: use técnicas que sean sensibles a su aplicación. Los objetos en $ _SESSION están bien, sujetos a precauciones de sentido común. Si su aplicación se convierte repentinamente en algo que compita con Amazon en el tráfico servido, deberá volver a adaptarse. Así es la vida.

Otros consejos

está bien siempre que para cuando se realice la llamada a session_start (), PHP ya haya encontrado la declaración / definición de la clase o un autocargador ya instalado pueda encontrarla. de lo contrario, no podría deserializar el objeto desde el almacén de la sesión.

HTTP es un protocolo sin estado por una razón. Sesiones de estado de soldadura en HTTP. Como regla general, evite utilizar el estado de sesión.

ACTUALIZACIÓN: No hay concepto de una sesión en el nivel HTTP; los servidores proporcionan esto al proporcionarle al cliente una ID única y pedirle que lo vuelva a enviar en cada solicitud. Luego, el servidor usa esa ID como una clave en una gran tabla hash de objetos de sesión. Cada vez que el servidor recibe una solicitud, busca la información de la sesión en su tabla hash de objetos de sesión basándose en la ID que el cliente envió con la solicitud. Todo este trabajo adicional es un doble golpe en la escalabilidad (una razón importante por la que HTTP es sin estado).

  • Whammy One: reduce el trabajo que puede hacer un solo servidor.
  • Whammy Two: hace que sea más difícil escalar porque ahora no puede simplemente enviar una solicitud a un servidor antiguo, no todos tienen la misma sesión. Puede anclar todas las solicitudes con un ID de sesión dado al mismo servidor. Eso no es fácil, y es un punto único de falla (no para el sistema en su conjunto, sino para grandes partes de sus usuarios). O bien, podría compartir el almacenamiento de la sesión en todos los servidores del clúster, pero ahora tiene más complejidad: memoria conectada a la red, un servidor de sesión independiente, etc.

Dado todo esto, cuanta más información coloque en la sesión, mayor será el impacto en el rendimiento (como señala Vinko). Además, como señala Vinko, si su objeto no es serializable, la sesión se comportará mal. Entonces, como regla general, evite poner más de lo absolutamente necesario en la sesión.

@Vinko Por lo general, puede evitar el estado de almacenamiento del servidor incorporando los datos que está rastreando en la respuesta que envía y que el cliente la vuelva a enviar, por ejemplo, enviando los datos en una entrada oculta. Si realmente necesita un seguimiento del estado del lado del servidor, probablemente debería estar en su almacén de datos de respaldo.

(Vinko agrega: PHP puede usar una base de datos para almacenar información de sesión, y hacer que el cliente vuelva a enviar los datos cada vez podría resolver posibles problemas de escalabilidad, pero abre una gran lata de problemas de seguridad a los que debe prestar atención ahora que el cliente está control de todo tu estado)

  • Los objetos que no pueden ser serializados (o que contienen miembros que no se pueden serializar) no saldrán de la $ _SESSION como usted esperaría
  • Las sesiones enormes suponen una carga para el servidor (serializar y deserializar megas de estado cada vez es caro)

Aparte de eso no he visto ningún problema.

En mi experiencia, generalmente no vale la pena por algo más complicado que un StdClass con algunas propiedades. El costo de la deserialización siempre ha sido más que volver a crear a partir de una base de datos dado un identificador almacenado por sesión. Parece genial, pero (como siempre), el perfil es la clave.

Sugeriría que no uses estado a menos que lo necesites absolutamente. Si puedes reconstruir el objeto sin usar sesiones, hazlo. Tener estados en su aplicación web hace que la aplicación sea más compleja de compilar, por cada solicitud que tenga que ver en qué estado se encuentra el usuario. Por supuesto, hay ocasiones en las que no puede evitar el uso de la sesión (ejemplo: el usuario debe mantenerse conectado durante su sesión en la aplicación web). Por último, sugeriría mantener el objeto de sesión lo más pequeño posible, ya que afecta el rendimiento para serializar y deserializar objetos grandes.

Tendrá que recordar que los tipos de recursos (como las conexiones de db o los punteros de archivos) no persistirán entre las cargas de página, y tendrá que volver a crearlos de forma invisible.

También considere el tamaño de la sesión, dependiendo de cómo se almacene, puede tener restricciones de tamaño o problemas de latencia.

También lo mencionaría al actualizar las bibliotecas de software: actualizamos nuestro software y la versión anterior tenía objetos en sesión con los nombres de clase del software V1, el nuevo software se estaba fallando cuando intentaba construir los objetos que estaban en la sesión. como el software V2 ya no usaba esas mismas clases, no podía encontrarlas. Tuvimos que poner un código de corrección para detectar objetos de sesión, eliminar la sesión si se encuentra, volver a cargar la página. Al principio, lo que más me molestó fue volver a crear este error cuando se informó por primera vez (muy familiar, "bueno, funciona para mí"), ya que solo afectó a las personas que ingresaron y salieron de los sistemas antiguos y nuevos recientemente. buen trabajo, lo encontramos antes del lanzamiento, ya que todos nuestros usuarios seguramente habrían tenido las antiguas variables de sesión en sus sesiones y se habrían estrellado para todos, habría sido un terrible lanzamiento :)

De todos modos, como sugiere en su enmienda, también creo que es mejor recrear el objeto. Por lo tanto, tal vez simplemente almacenar el ID y luego cada solicitud que saque el objeto de la base de datos sea mejor / más seguro.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top