Foros del Web » Programando para Internet » PHP »

Problemas con empty al evaluar respuesta de __get

Estas en el tema de Problemas con empty al evaluar respuesta de __get en el foro de PHP en Foros del Web. Me pasó algo que considero un poco extraño, lo comparto. Quizás a alguien le sirva o pueda explicar que es exactamente lo que pasó. Tengo ...
  #1 (permalink)  
Antiguo 31/08/2010, 19:52
Avatar de bng5  
Fecha de Ingreso: junio-2009
Ubicación: 127.0.0.1
Mensajes: 269
Antigüedad: 14 años, 10 meses
Puntos: 24
Problemas con empty al evaluar respuesta de __get

Me pasó algo que considero un poco extraño, lo comparto. Quizás a alguien le sirva o pueda explicar que es exactamente lo que pasó.

Tengo una clase llamada Sesion, es poco más que una envoltura para el array $_SESSION.
Implementa un patron singleton. Utilizo el método instancia que me devuelve, por supuesto, un objeto del tipo Sesion.

Parte del código de Sesion.
Código PHP:
class Sesion {

    private function 
__construct() {
        
// bla bla
    
}

    public static function 
instancia() {
        if (!isset(
self::$_instancia)) {
            
self::$_instancia = new self;
        }
        return 
self::$_instancia;
    }

    public function 
__get($clave) {
        return 
$_SESSION[$clave];
    }

Todo funciona bien con esta clase, si hago un var_dump de un atributo funciona perfecto.
Código PHP:
var_dump(Sesion::instancia()->usuario);
// Devuelve "string 'nombreDeUsuario'" 
Pero si quiero comprobar si el atributo no está vacío de la siguiente manera no funciona.

Código PHP:
    if(!empty(Sesion::instancia()->usuario)) {
        
// nunca entra en esta condición
        // como si Sesion::instancia()->usuario estuviese vacío 
        // cuando en realidad no es así
    

Esta es la solución que encontré: cargandolo en una variable.

Código PHP:

$usuarioStr 
Sesion::instancia()->usuario;
if(!empty(
$usuarioStr)) {
    
// funciona
}

$sesionObj Sesion::instancia();
if(!empty(
$sesionObj->usuario)) {
    
// NO funciona
}

if(!empty(
Sesion::instancia()->usuario)) {
    
// NO funciona
}

var_dump($usuarioStr); // devuelve string 'nombreUsuario'
var_dump($sesionObj->usuario); // devuelve string 'nombreUsuario'
var_dump(Sesion::instancia()->usuario); // devuelve string 'nombreUsuario' 
Edit: Espero se haya entendido. Cualquier duda avisen.
  #2 (permalink)  
Antiguo 31/08/2010, 22:44
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 10 meses
Puntos: 2135
Respuesta: Problemas con empty al evaluar respuesta de __get

Lo que pasa es que empty() no es una función normal, es un language construct y para que funcione tienes que sobrecargar el método __isset:
Código PHP:
Ver original
  1. class Sesion
  2. {
  3.           public function __isset($var)
  4.           {
  5.                    return isset($_SESSION[$var]);
  6.           }
  7. }
  8.  
  9. if (!empty(Sesion::instancia()->usuario)) {
  10.   // works!
  11. }

Saludos.
  #3 (permalink)  
Antiguo 01/09/2010, 13:41
Avatar de bng5  
Fecha de Ingreso: junio-2009
Ubicación: 127.0.0.1
Mensajes: 269
Antigüedad: 14 años, 10 meses
Puntos: 24
Respuesta: Problemas con empty al evaluar respuesta de __get

Tenés razón: empty llama primero a __isset y si esta devuelve true, llama luego a __get.
Muchas gracias.

También tenés razón en que empty no es una función, sino language construct. Ya estoy leyendo al respecto y experimentando con sus diferencias frente a funciones 'built-in'.
Pero no me parece que esa sea la justificación de que empty llame a __isset primero.

O sea: me resultó muy útil tu respuesta y me abriste un camino para buscar información sobre language construct, pero por lo que estoy viendo no es porque sea language construct, sino porque es su comportamiento.
  #4 (permalink)  
Antiguo 01/09/2010, 13:46
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 10 meses
Puntos: 2135
Respuesta: Problemas con empty al evaluar respuesta de __get

Si ves el Manual de PHP, indica que para poder usar los métodos mágicos dentro de language constructs como isset, empty, unset, tienes que sobrecargar los métodos __isset, __unset, etc.

Esto es para poder respetar los métodos mágicos o de lo contrario no estaría definido su comportamiento.

Saludos.
  #5 (permalink)  
Antiguo 01/09/2010, 14:23
Avatar de bng5  
Fecha de Ingreso: junio-2009
Ubicación: 127.0.0.1
Mensajes: 269
Antigüedad: 14 años, 10 meses
Puntos: 24
Respuesta: Problemas con empty al evaluar respuesta de __get

Si, yo te entiendo lo que decís.
Lo que yo digo es que: empty no llama a __isset porque sea un language construct, sino que lo hace porque es el comportamiento de este language construct.

Pero repito: me sirvió el comentario inicial sobre language construct para continuar leyendo al respecto.
  #6 (permalink)  
Antiguo 01/09/2010, 14:53
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 10 meses
Puntos: 2135
Respuesta: Problemas con empty al evaluar respuesta de __get

Cito el Manual:
Cita:
__isset() is triggered by calling isset() or empty() on inaccessible properties.
Saludos.
  #7 (permalink)  
Antiguo 01/09/2010, 15:11
Avatar de bng5  
Fecha de Ingreso: junio-2009
Ubicación: 127.0.0.1
Mensajes: 269
Antigüedad: 14 años, 10 meses
Puntos: 24
Respuesta: Problemas con empty al evaluar respuesta de __get

Si, GatorV. Parece que estuviésemos hablando de cosas diferentes.
Está clarísimo que isset() y empty() desencadenan el método mágico __isset, pero no por ser language construct. print es language construct y sólo desencadena __get.
  #8 (permalink)  
Antiguo 01/09/2010, 15:13
Avatar de pateketrueke
Modernizr
 
Fecha de Ingreso: abril-2008
Ubicación: Mexihco-Tenochtitlan
Mensajes: 26.399
Antigüedad: 16 años
Puntos: 2534
Respuesta: Problemas con empty al evaluar respuesta de __get

Cita:
Iniciado por bng5 Ver Mensaje
Si, GatorV. Parece que estuviésemos hablando de cosas diferentes.
Está clarísimo que isset() y empty() desencadenan el método mágico __isset, pero no por ser language construct. print es language construct y sólo desencadena __get.
eso es obvio...

son cosas completamente distintas, ¿pero quieres educarnos o hay que leer el manual?
__________________
Y U NO RTFM? щ(ºдºщ)

No atiendo por MP nada que no sea personal.
  #9 (permalink)  
Antiguo 01/09/2010, 15:15
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 10 meses
Puntos: 2135
Respuesta: Problemas con empty al evaluar respuesta de __get

Es obvio, print como indica imprime un valor, por ende va a __get a buscar el valor.

Saludos.
  #10 (permalink)  
Antiguo 01/09/2010, 15:25
Avatar de bng5  
Fecha de Ingreso: junio-2009
Ubicación: 127.0.0.1
Mensajes: 269
Antigüedad: 14 años, 10 meses
Puntos: 24
Respuesta: Problemas con empty al evaluar respuesta de __get

Cita:
Iniciado por pateketrueke Ver Mensaje
eso es obvio...

son cosas completamente distintas, ¿pero quieres educarnos o hay que leer el manual?
No entiendí que querés decir con tu pregunta.
Es obvio que tanto vos, como GatorV o yo conocemos el manual.
No pretendo evangelizar a nadie, pero todos los que entramos al foro en parte es porque queremos educarnos, ya sea a través de respuestas o preguntas.

Yo solo le agradecí a GatorV por la respuesta, ya que tenía razón en que:
  1. tenía que implementar el método __isset
  2. empty es un language construct y no una función

También acoté que, si bien eso era correcto, no era exactamente esa la razón y el tema se fue para largo.

Si molesta no agrego más ese tipo de comentarios.

Edit: La última oración va en serio. Soy nuevo en esto de los foros y aprendo a manejarme a través de las respuestas de los demás, así como de los karmas positivos y negativos. Mi forma de dirigirme a los demás a ido mejorando y debe mejorar más.
  #11 (permalink)  
Antiguo 01/09/2010, 15:34
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 10 meses
Puntos: 2135
Respuesta: Problemas con empty al evaluar respuesta de __get

El problema es que parece que no quieres leer bien el Manual, claramente indica que para que funcionen los language constructs debes de implementar esos métodos, el problema y que por eso se ha ido alargando es que sigues indicando que esa no es la razón (aunque como indicas con eso se arreglo).
  #12 (permalink)  
Antiguo 01/09/2010, 15:44
Avatar de bng5  
Fecha de Ingreso: junio-2009
Ubicación: 127.0.0.1
Mensajes: 269
Antigüedad: 14 años, 10 meses
Puntos: 24
Respuesta: Problemas con empty al evaluar respuesta de __get

Si, leí el manual donde dice:

Cita:
__isset() is triggered by calling isset() or empty() on inaccessible properties
Está en http://php.net/manual/es/language.oop5.overloading.php

Y no es eso lo que yo estaba diciendo, ya te la dí por buena hace rato.
Nunca te discutí eso, el que quiera leer lo que escribí que lo haga y el que quiera entender lo que se le antoje también.

Prefiero abandonar este hilo y quedarme sin saber cual era la intecionalidad de pateketrueke.

Gracias, saludos.

Última edición por bng5; 01/09/2010 a las 16:41

Etiquetas: empty, evaluar, respuesta
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 07:58.