Como manejar objetos y sesiones de PHP cuando se usa AJAX

Publicado en Programación | 14 Comentarios

He estado trabajando en un pequeño proyecto personal ultimamente y me topé con el siguiente problema. Lo encontré muy mal documentado (al menos al momento de agregar AJAX) y ya que me costó un buen dolor de cabeza así pensé que sería buena idea publicar la solución. Ojalá este artículo ayude a alguien más a ahorrarse un par de horas y un derrame innecesario de bilis.

El problema 1.0

Este es el escenario. Estoy usando PHP orientado a objetos con el fin de poder guardar instancias en variables de sesión y asi poder pasar información constantemente entre documentos sin muchas complicaciones.

Hasta aquí nada especial pero tiene un pequeño detalle a tomar en cuenta, y es que cada que intentas hacer una operación con un objeto, PHP necesita tener a la mano la definición de la clase en la que está basado. Un ejemplo con código para explicarme mejor:

Supongan que tenemos una clase ‘usuario’ definida como:

<?php
// Archivo: usuario.php
class usuario {
    public $nombre;
    public $apellido;
    public function sayMyName() {
       echo $this->nombre . ‘ ‘ . $this->apellido;
    }
}
?>

En un segundo archivo creamos una instancia, la llenamos de datos y la asignamos a una variable de sesión para usarla más tarde:

<?php
// Archivo pag1.php
include(‘usuario.php’);
session_start();
$usuario = new usuario();
$usuario->nombre = ‘Gregory’;
$usuario->apellido = ‘House’;
$_SESSION[‘usuario’] = $usuario;
?>

Para terminar, en la siguiente página queremos desplegar el nombre de nuestro usuario:

<?php
// Archivo pag2.php
session_start();
$usuario = $_SESSION[‘usuario’];
$usuario->sayMyName();
?>

Parece lógico no? pues si, lo es hasta que lo ejecutamos y nos encontramos con un error pidiendonos la definición de la clase en pag2.php lo cual hasta cierto punto tiene sentido si entendemos como funciona PHP. Como nota, la definición debe de ir incluida antes de que llamemos a session_start(). Lo siguiente funcionaría correctamente:

<?php
// Archivo pag2.php
include(‘usuario.php’);
session_start();
$usuario = $_SESSION[‘usuario’];
$usuario->sayMyName();
//salida: “Gregory House”
?>

Simple y se resolvió con una sola linea extra de código, pero ese no era el verdadero problema, ahora viene lo interesante, que pasa cuando agregamos AJAX a la mezcla?

El problema 2.0

Cada que hacemos una llamada asíncrona a una página php tenemos que asumir que todos los archivos que incluimos están perdidos y que hay que llamarlos de nuevo si necesitamos usarlos…a excepción de la sesiones que se quedan almacenadas por su propia naturaleza.

Supongan que estamos usando el mismo código de arriba, pero ahora queremos ejecutar pag2 desde pag1 usando AJAX, entonces nos encontramos con un obstáculo extra, y es que gracias a que la sesión ya fue definida en pag1, al momento de que se llama a pag2, session_start() va a regresar un error diciendo que ya hay una sesión iniciada y que la ordén será ignorada.

Entonces solo eliminamos session_start() no? Nope por que resulta entonces que nos vamos a encontrar con otro error:

Fatal error: Unknown: The script tried to execute a method or access a
property of an incomplete object. Please ensure that the class
definition CLASE of the object you are trying to operate on was
loaded _before_ the session was started in Command line code on line #

El problema es que aunque tenemos la sesión inicializada, la definición de la clase no existe en nuestar segunda página, e incluso si tenemos el include() dentro del archivo, no le sirve a PHP por que no está antes del inicio de sesión y no hay manera de ponerla en el lugar correcto por que la sesión viene desde el primer archivo.

Después de estar intentando con todas las ideas que me encontraba en la red como modificar el valor de session_auto_start en la configuración de php y otros trucos de vudú muy poco prácticos y que no sirvieron de nada, por fin encontre una forma de hacer que funcione.

El truco es hacer lo mismo que hace session_start() con las variables de sesión pero manualmente, serializar.

Regresando al ejemplo de arriba, vamos a modificar pag1.php para serializar la instancia

<?php
// Archivo pag1.php
include(‘usuario.php’);
session_start();
$usuario = new usuario();
$usuario->nombre = ‘Gregory’;
$usuario->apellido = ‘House’;
$_SESSION[‘usuario’] = serialize($usuario);
?>

Y en pag2.php regresamos la variable a su forma original con unserialize()

<?php
// Archivo pag2.php
$usuario = unserialize($_SESSION[‘usuario’]);
$usuario->sayMyName();
//salida: “Gregory House”
?>

Noten que no incluí el archivo de definición de la clase (usuario.php).
Por alguna razón que aún no termino de entender, el include sigue sin funcionar, afortunadamente unserialize() es una de las funciones de PHP que permite declarar una función callback a la que llama como último recurso si está manejando un objeto y no encuentra la definición de la clase, se usa de la siguiente forma:

<?php
// Archivo pag2.php
ini_set('unserialize_callback_func', 'incluirClase');
function incluirClase($clase) {
    include(‘usuario.php’);
}

$usuario = unserialize($_SESSION[‘usuario’]);
$usuario->sayMyName();
//salida: “Gregory House”
?>

El parametro $clase es regresado automáticamente por PHP e incluye el nombre de la clase para la que no encontró definición.

Ahora si, eso resuleve todo y como este artículo ya se extendió mucho aquí lo termino. Si tienen alguna duda dejenla en los comentarios.

Nota: El código en el artículo no está depurado asi que no intenten ejecutarlo directamente, solo tomenlo como ejemplo.


Reporte de daños

Publicado en Proyectos | 0 Comentarios

Este Jueves todos los sitios que manejo a excepción de este blog estuvieron caidos durante gran parte del día.

El problema fue un error en la configuración de los DNS que basicamente estaba provocando que los dominios apuntaran a la nada.

Todo parece estar resuelto ya, si aún no pueden ver alguno de los sitios, denle algunas horas mientras las direcciones se expanden por los intertubos y vuelvan a intentarlo.

Disculpen las molestias.


Senado.gob.mx hackeada

Publicado en Interwebz | 0 Comentarios

A algún argentino le pareció gracioso cambiarle la cara al sitio de el senado mexicano esta madrugada de Viernes. Click en la imagen para verla completa en caso de que ya la hayan arreglado para cuando lean esto.

(vía @ugho)


Comentarios graciosos II

Publicado en Humor | 1 Comentarios

Recibido en este post.

la wapilla-warrila-mi amol… 0-o escribió
“pues vaya son unos copiotas los de Asia, claro como google tiene muxa por decirlo asi audicion por llamarlo de alguna manera, pues… joer kn ls xinos. ””’pelo no te metlas con miglo” jejejeje komo mola… podrían poner mas tiendas en vallekas (madrid, españa)…. jejejeje hay una mierda d tiendas podrian poner MISS SIXTY, CH, LACOSTE, DESIGUAL… MUXAS MAS TIENDAS SK UNA XICA KOMO YO MUY KOKETA NECESITA MAS TIENDAS Y TODO MI INSTI… ANDA PLISSS PONERNOS MAS TIENDAS QUE NOSOTR@S ASI NO AGUANTAMOS MAS… A ST PASO ME VOY A VIVIR A SOL ALLI TIENEN LA MAYORIA DE LAS TIENDAS… MUXOS BSS LA WARRY”

Alguien por favor hagale caso y pongan más tiendas cerca de su casa antes de que se nos muera de la desesperación!.


El juicio final

Publicado en Humor | 0 Comentarios

GAP

Dios: Que has hecho en tu vida?
Juzgado: No has estado leyendo mis tweets?

Visto en Geek And Poke


Quiero mis películas hoy!

Publicado en Uncategorized | 0 Comentarios

Antes de empezar vean el trailer de Forgetting Sarah Marshall a continuación (es la versión Red Band probablemente no apta para la oficina, hay una versión más ligera aquí):

Forgetting Sarah Marshall – Red Band Trailer

Kristen Bell + El tipo gracioso de How i met your mother + Mila Kunis + El tipo raro de 30 rock. Ya quiero ver esta película!.

Se estrena en los Estados Unidos este fin de semana, así que decidí revisar en imdb para ver cuando se estrenará en mx. 2 semanas? un més? ja, que tal más de 4 meses (29 de Agosto). Para ese entonces ya habré olvidado a Sarah Marshall…literalmente.

En serio, por que las distribuidoras siguen con esa ridícula idea de esperar a que las películas tengan éxito en otros lugares para poder promoverlas con frases como “la comedia que arrasó en los Estados Unidos” o “ganadora del festival de los tomates rojos en Alemania”. No va a cambiar nada!, solo traigan la maldita película y dejen que la gente se encargue de pasar la voz si vale la pena.

Hay otras razones que se me estén escapando aquí? por que yo simplemente no le veo sentido a todo esto.

En fin, esa mi fué mi queja del día. Ahora si me permiten voy a ir a ver si las buenas personas de la bahía pirata o mininova ya la tienen, ya saben, solo por curiosidad. No es que la vaya a bajar o algo así.


Fotos y relato del coca-cola zero fest

Publicado en Uncategorized | 1 Comentarios

Austin Tv

El sábado estuve en el Coca-Cola Zero Fest de la Ciudad de México. En general me divertí mucho a excepción de decepcionarme por que los Smashing Pumpkins quedaron a deber mucho.

Las fotos están en flickr y la crónica del día en dinitivo.


Sitios que me gustaron esta semana

Publicado en Diseño web | 0 Comentarios

Yahoo Shine

Yahoo shine

link: http://shine.yahoo.com/

En Yahoo están lanzando ideas como hot cakes en el desayuno para ver si alguna los salva de las garras de Microsoft. Lo que me gustó de Shine fue el pequeño tour que te dan cuando visitas el sitio por primera ocasión.

Andreas Wildman

Andreas Wildman

link: http://www.andreaswidman.com/

Bonito, limpio y con un toque de AJAX. Así me gustan mis sitios.

Piperlime

Piperlime

link: http://www.piperlime.com/browse/product.do?pid=565084002&tid=PLFR1#

Mientras miraba los zapatos de pacman más espectaculares de la historia me encontré con la pequeña funcionalidad de zoom que usan cuando pasas el cursor sobre los productos y me gustó.


Dattatec apesta!

Publicado en Interwebz | 16 Comentarios

El título lo dice todo, no tengo nada más que agregar que en este momento no se haya dicho ya en el resto de la blogosfera. Aquí la historia para los que no la hayan leido aún.


Video en flickr, ¿pudo haber sido diferente?

Publicado en Interwebz | 0 Comentarios

Flickr No al Video

Yo pensaba que solo los usuarios de digg eran los revoltosos en la web 2.0 pero los de flickr no se quedan atrás y están lanzando campañas en contra de la decisión de agregar video a su querido sitio de fotos. Esto es lo que están diciendo en los grupos que están formando para protestar:

“We joined Flickr due to it being the best photo sharing site, the members of this group want Flickr to be Photography only Give the people that pay the wages a say in what happens.”

En lo particular a mi me gustó la forma en la que flickr decidió hacer los videos. Solo 90 segundos y disponibilidad para cuentas pro únicamente, es como un twitter para video que filtrará toda la basura que entra a otros sitios de video manteniendo la limpieza que caracteriza al servicio.

Aún así, estoy de acuerdo con que el video no va con la idea de flickr, me hubiera gustado más que lo lanzaran bajo otro nombre y lo integraran como un servicio externo además de al menos ofrecer la posibilidad en los perfiles de desaparecer todos los videos para los que quieran continuar viendo solo fotografías.