Foros del Web » Programando para Internet » PHP » Frameworks y PHP orientado a objetos »

$this->false (php4) a unset($this) (php5)

Estas en el tema de $this->false (php4) a unset($this) (php5) en el foro de Frameworks y PHP orientado a objetos en Foros del Web. Hola a todos!! Tengo que pasar una aplicación ya hecha en php4 a php5 y me encuentro con un problema que no se resolver. Creo ...
  #1 (permalink)  
Antiguo 19/06/2008, 03:45
Avatar de SUSMO  
Fecha de Ingreso: abril-2008
Ubicación: Barcelona
Mensajes: 188
Antigüedad: 16 años
Puntos: 0
$this->false (php4) a unset($this) (php5)

Hola a todos!!

Tengo que pasar una aplicación ya hecha en php4 a php5 y me encuentro con un problema que no se resolver.

Creo un objeto y dentro del constructor (como sería en php4 con el mismo nombre que la clase) hago ciertas comprobaciones y si no se cumplen destruyo el objeto y devuelvo falso.

En php4 no me da ningún tipo de problema:
Código PHP:
$this false; return false
Al adaptarlo al php5 lo he sustituido por lo siguiente:
Código PHP:
unset($this); return false
El caso es que dentro del constructor después de hacer el unset hago un var_dump($this) y me devuelve null pero cuando vuelvo a la página inicial en donde creo el objeto si hago un var_dump($nombre_objeto) me devuelve el objeto con todas sus propiedades. ¿Porque el unset no me ha borrado el objeto en la página donde se hace la llamada? ¿Alguien sabe como solventarlo? ¿Como puedo hacer para que el objeto sea false en la página desde donde lo creo?

Gracias por la atención.
  #2 (permalink)  
Antiguo 19/06/2008, 08:22
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años
Puntos: 2135
Respuesta: $this->false (php4) a unset($this) (php5)

Mmm no veo el caso en si, ya que lo mejor seria que lanzaras una excepción en caso de que no se pudiera construir, por ejemplo:
Código PHP:
try {
       
$obj = new Algo();
} catch( 
Exception $e ) {
       echo 
$e->getMessage();

Pero si lo quieres destruir podrías tratar de igualar $this a null.

Saludos.
  #3 (permalink)  
Antiguo 19/06/2008, 09:20
Avatar de SUSMO  
Fecha de Ingreso: abril-2008
Ubicación: Barcelona
Mensajes: 188
Antigüedad: 16 años
Puntos: 0
De acuerdo Respuesta: $this->false (php4) a unset($this) (php5)

Hola GatorV

Volviendo a leer mi post he visto que no me he explicado todo lo bien que debería, sorry.
Lo que quiero es que al crear el objeto si no se cumplen unas condiciones él mismo me devuelva false ya que lo necesito para comparar.
Te pongo código para que se me entienda mejor.

Fichero donde creo el objeto:
Código PHP:
....
$obj = new Login($post_usuario$post_clave);

var_dump($obj); //En php4 devuelve false, en php5 el objeto con sus propiedades

if ($obj !== false
{
      
session_start();
      
$_SESSION['USUARIO'] = $post_usuario;
      
$_SESSION['CLAVE'] = $post_clave;
 }
.... 
La clase Login me comprueba que exista el usuario en la base de datos, si no existe no inicia la sesión.

Constructor de la clase Login:
Código PHP:
.....
$res $this->coneccion->consulta("SELECT * FROM clientes WHERE usuario='$usuario' AND clave='$clave'");

if (!
$res)
   die(
$this->coneccion->ultimoError());

if (
$this->coneccion->numeroResultados() == 0)
{
    
//$this = false; (en php4 funcionaba con esta línea)

        
unset($this); //(Cambio para PHP5)
        
var_dump($this); //Dentro del constructor en php5 devuelve null  y en php4 false
    
return false;
}
... 
El caso es que en php4 si el usuario no estaba en la bdd después de crear el objeto hacía un var_dump($obj) y me daba false y por tanto no iniciaba sesión.
Sustituyendo $this = false por unset($this) para que me funcionara en php5 al hacer el var_dump($obj) me devuelve el objeto con todas sus propiedades, es decir, no me lo elimina. Ahora ya he solventado mi problema poniendo un atributo que me diga si el login se ha efectuado con éxito o no y así en lugar de comparar el objeto en sí comparo el valor de ese atributo pero me quedo con la duda de pq se comportan diferente. ¿Me lo sabrías responder?

Gracias por tu tiempo.
  #4 (permalink)  
Antiguo 19/06/2008, 09:34
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años
Puntos: 2135
Respuesta: $this->false (php4) a unset($this) (php5)

Hola SUSMO,

En PHP4, el soporte a objetos es muy "virtual", ya que esta muy limitado, en PHP5, se reestructuro completamente el soporte, yo creo por ahi viene el problema en sí.

Pero como te comento, lo ideal para ese caso es que uses excepciones para mostrar si inicio o no sesión:
Código PHP:
try {
      
$obj = new Login$post_usuario$post_clave );
      
session_start();
      
$_SESSION['USUARIO'] = $post_usuario;
      
$_SESSION['CLAVE'] = $post_clave
} catch( 
IncorrectLoginException $ile ) {
      switch( 
$ile->getCode() ) {
            case 
IncorrectLoginException::USER_NOT_FOUND:
                    echo 
"El usuario no existe";
                    break;
            case 
IncorrectLoginException::PASSWORD_NO_MATCH:
                    echo 
"La contraseña es incorrecta";
                    break;
             case 
IncorrectLoginException::LOGIN_TOOMANY_TRIES:
                    echo 
"Ha tratado de entrar muchas veces, por favor espere 5 minutos e intente de nuevo";
                    break;
             default:
                    echo 
"Error al iniciar sesion, favor de volver a intentarlo";
                    break;
      }

Saludos.
  #5 (permalink)  
Antiguo 19/06/2008, 10:04
Avatar de SUSMO  
Fecha de Ingreso: abril-2008
Ubicación: Barcelona
Mensajes: 188
Antigüedad: 16 años
Puntos: 0
Respuesta: $this->false (php4) a unset($this) (php5)

Hola GatorV

No se me había ocurrido utilizar excepciones, mi opción era más a la antigua usanza, variable que te diga si ha pasado el login o no jeje
Esta vez, no lo modificaré pq ya lo he implementado pero lo tendré en cuenta para futuras ocasiones.

Muchas gracias por la ayuda!!
  #6 (permalink)  
Antiguo 19/06/2008, 10:28
Avatar de enriqueplace  
Fecha de Ingreso: mayo-2005
Ubicación: Uruguay / Argentina
Mensajes: 1.102
Antigüedad: 19 años
Puntos: 32
Respuesta: $this->false (php4) a unset($this) (php5)

Podrías poner un poco más de código para entender el contexto en que necesitas una solución de este tipo?

De curioso nomás
__________________
Blog phpsenior.com Cursos a Distancia surforce.com
  #7 (permalink)  
Antiguo 20/06/2008, 02:29
Avatar de SUSMO  
Fecha de Ingreso: abril-2008
Ubicación: Barcelona
Mensajes: 188
Antigüedad: 16 años
Puntos: 0
Respuesta: $this->false (php4) a unset($this) (php5)

Hola enriqueplace,

El contexto, es una validación de usuario, en la página de login con un formulario de usuario y password que envía los datos a la misma página. Si el usuario se valida correctamente no se carga la de login y se redirecciona a la pagina principal de la administración.

Aquí te pongo más código tal y como me has pedido y aprovecho para poner como he implementado la solución por si a alguien le puede servir.

Página de login:

Código PHP:
....
if (!empty(
$_POST['usuario']) && !empty($_POST['clave']))

    
$post_usuario strtolower($_POST['usuario']); //Guardo en BDD usuario y password en minúsculas
    
$post_clave strtolower($_POST['clave']);
    
$obj = new Login($post_usuario$post_clave);

    
//Solución, he creado un atributo en la clase que me indica 
    //si el usuario está registrado o no
    
if ($obj->registrado  !== false)  
   {
      
session_start();
      
$_SESSION['USUARIO'] = $post_usuario;
      
$_SESSION['CLAVE'] = $post_clave;
      
header("location: area.php");
      exit();
   }
}
//Empieza el código html de la página de login
.... 
Implementación del constructor de la clase login:

Código PHP:
.....
function 
Login($usuario ""$clave "")

{
    
$this->coneccion = new Coneccion(MYSQL_URL,MYSQL_USER,MYSQL_PASS,MYSQL_SCHEMA);

    
$res $this->coneccion->conecta();

    if (!
$res)

    die(
$this->coneccion->ultimoError());

    
$res $this->coneccion->consulta("SELECT * FROM clientes WHERE usuario='$usuario' AND clave='$clave'");

    if (!
$res)
       die(
$this->coneccion->ultimoError());

    if (
$this->coneccion->numeroResultados() == 0)
   {
        unset(
$this); 
       
$this->registrado false;
        return 
false;
    }
    
$this->registrado true;
    return 
true;
}
... 
Saludos!!!
  #8 (permalink)  
Antiguo 20/06/2008, 07:50
Avatar de enriqueplace  
Fecha de Ingreso: mayo-2005
Ubicación: Uruguay / Argentina
Mensajes: 1.102
Antigüedad: 19 años
Puntos: 32
Respuesta: $this->false (php4) a unset($this) (php5)

Bueno, rápidamente te puedo decir que tu constructor está "muy gordo", hace demasiadas cosas.

Algunas sugerencias:
  1. Cambia el constructor por __construct
  2. No pongas en minúsculas la clave, ya que si alguien pone claves combinadas no funcionarán luego.
  3. Separa las operaciones de persistencia en métodos aparte y no lo hagas en el mismo constructor.
  4. Es medio redundante retornar false y además retornar un objeto del mismo tipo con un atributo en false
  5. Cierra siempre con llaves, no deje el if sin llaves.
  6. Cambia "coneccion" por "conexión".
  7. Usa nombres coherentes para las instancias (no "obj")
  8. Trata de ver un mecanismo que no tengas siempre en la sesión la clave del usuario.

Voy a hacer un ejemplo rápido para que se entienda mejor (puede tener detalles y/o errores):

Código PHP:
class Login
{
   private 
$_usuario null;
   private 
$_clave null;
   private 
$_resultado null;
   
   public function 
__construct($usuario ""$clave "")
   {
      
$this->_usuario $usuario;
      
$this->_clave $clave;
   }
   public function 
esValido()
   {
          
$this->load();
          
       if (
$this->conexion->numeroResultados() == 0){
               
$this->registrado false;
        }else{
            
$this->registrado true;
        }
           return 
$this->registrado;
   }
   public function 
load()
   {
      
$this->conexion = new Coneccion(MYSQL_URL,MYSQL_USER,MYSQL_PASS,MYSQL_SCHEMA);

       
$res $this->conexion->conecta();
       if (!
$res){
               die(
$this->conexion->ultimoError());
       }
       
$this->_resultado $this->conexion->consulta("SELECT * FROM clientes WHERE usuario='$usuario' AND clave='$clave'");

       if (!
$res){
          die(
$this->coneccion->ultimoError());
       }    
   }   


/* Uso */

if (!empty($_POST['usuario']) && !empty($_POST['clave']))

    
$post_usuario strtolower($_POST['usuario']);
    
$post_clave $_POST['clave'];
    
    
$Login = new Login($post_usuario$post_clave);
    
    if (
$Login->esValido() ){
      
session_start();
      
$_SESSION['USUARIO'] = $post_usuario;
      
$_SESSION['CLAVE'] = $post_clave;
      
header("location: area.php");
      exit();
   }


De todas formas puedes ver de cambiar la estrategia por un método de clase que haga algo por el estilo:

Código PHP:
 if( Login::esValido($usuario$clave) ){
     
/* etc */
 


De todas formas, sugiero que (bueno, las buenas practicas lo dicen) que mantengas el foco en una acción simple en cada método y
no hagas métodos kilométricos.

Toma este criterio: "si tu método supera la visual de tu pantalla, algo está mal"
__________________
Blog phpsenior.com Cursos a Distancia surforce.com

Última edición por enriqueplace; 20/06/2008 a las 08:02
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 00:01.