2009-04-28 15 views
6

Estoy construyendo una clase con una serie de validaciones de entrada, y he decidido colocarlas dentro de un método __set (no estoy seguro de si esta es la forma correcta, ya que he limitado Experiencia OOP). Esto parece funcionar bien, arrojando los errores adecuados cuando se pasan valores no válidos desde fuera de la clase. Sin embargo, si se modifica una variable dentro de la clase, el método _ _set parece ignorarse por completo.PHP ignorando el método __set dentro de la clase

Cualquier idea sería apreciada enormemente

//RESULT::::::::::::::::::::::::::::::: 
// PASS: Testing : hello 
// PASS: Testing exception handling 
// __SET: Setting b to 123 
// PASS: Testing with valid value: 123 
// FAIL: Testing exception handling World2 



<?php 
class Test { 
     public $a; 
     private $b; 

     function __set($key, $val) { 

       switch($key) { 
         case 'b': 
           if(!is_numeric($val)) throw new Exception("Variable $b must be numeric"); 
           break; 
       } 

       echo ("__SET: Setting {$key} to {$val}<br/>"); 
       $this->$key = $val; 
     } 
     function __get($key) { return $this->$key; } 
     function bMethod() { 
       $this->b = "World2"; 
     } 

} 

$t = new Test(); 

//testing a 
try { 
     $t->a = "hello"; 
     echo "PASS: Testing $a: {$t->a}<br/>"; 
} catch(Exception $e) { 
     echo "FAIL: Testing $a"; 
} 

//testing b 
try { 
     $t->b = "world";  
     echo "FAIL: Testing $b exception handling<br/>"; 
} catch(Exception $e){ 
     echo "PASS: Testing $b exception handling<br/>"; 
} 

//testing b with valid value 
try { 
     $t->b = 123; 
     echo "PASS: Testing $b with valid value: {$t->b}<br/>"; 
} catch(Exception $e) { 
     echo "FAIL: Testing $b"; 
} 

//bypassing exception handling with method 
try { 
     $t->bMethod("world"); 
     echo "FAIL: Testing $b exception handling {$t->b}<br/>"; 
} catch(Exception $e) { 
     echo "PASS: Testing $b exception handling<br/>"; 
} 
+0

Esto me había foxed durante al menos una hora ... – Jonathan

Respuesta

10

Lee la definición de __set: "__set() se ejecuta al escribir datos a los miembros de difícil acceso." Inaccesible es clave aquí. Desde dentro de la clase, todos los miembros son accesibles y __set es pasado por alto. Overloading

+0

Desafortunadamente estoy fuera de los votos hoy, pero esto es correcto. Me encontré con este problema tratando de emular getters/setters de otros idiomas. Simplemente no funciona igual. – zombat

6

La documentación en el php documentation dice:

__get() se utiliza para leer datos de los miembros de difícil acceso.

Por lo tanto, se puede hacer algo como:

<?php 
class Test { 
    private $_params = array(); 

    function __set($key, $val) { 
     ... 
     $this->_params[$key] = $val; 
    } 

    function __get($key) { 
     if (isset($this->_params[$key])) return $this->$key; 
     throw Exception("Variable not set"); 
    } 

    ... 
} 
+0

Esto se siente como un hack, pero en realidad hace exactamente lo que yo quería hacer; Las llamadas variables dentro de los métodos de clase no pueden invocar las variables directamente, por lo que usan la función __set y __get. Gracias! – thatcanadian

Cuestiones relacionadas