2009-08-14 10 views
51
public static function __get($value) 

no funciona, e incluso si lo hiciera, se da la circunstancia de que ya necesito la magia __get captador de propiedades de la instancia de la misma clase.magia __get captador de propiedades estáticas en PHP

Esto probablemente es una pregunta de sí o no, entonces, ¿es posible?

Respuesta

54

No, no es posible.

Citando al manual page of __get: Miembro

sobrecarga sólo funciona en contexto del objeto. Estos métodos mágicos no se activarán en contexto estático . Por lo tanto, estos métodos pueden no declararse estáticos .


En PHP 5.3, __callStatic ha sido añadido; pero todavía no hay __getStatic ni __setStatic; incluso si la idea de tener/codificarlos a menudo vuelve a aparecer en php internals @ mailling-list.

hay incluso una Request for Comments: Static classes for PHP
Pero, aún así, no se han aplicado (¿todavía?)

+13

Esto es por lo que no podemos tener Niza cosas ... – cvsguimaraes

+9

@cvsguimaraes las cosas estáticas no son cosas bonitas ... –

+2

@webarto estuvo de acuerdo, pero considerando que estamos en tierra PHP, son características OOP de primera categoría jaja – cvsguimaraes

16

Tal vez alguien todavía necesita esto:

static public function __callStatic($method, $args) { 

    if (preg_match('/^([gs]et)([A-Z])(.*)$/', $method, $match)) { 
    $reflector = new \ReflectionClass(__CLASS__); 
    $property = strtolower($match[2]). $match[3]; 
    if ($reflector->hasProperty($property)) { 
     $property = $reflector->getProperty($property); 
     switch($match[1]) { 
     case 'get': return $property->getValue(); 
     case 'set': return $property->setValue($args[0]); 
     }  
    } else throw new InvalidArgumentException("Property {$property} doesn't exist"); 
    } 
} 
+4

¿Qué hace esto? – starbeamrainbowlabs

4

muy agradables mbrzuchalski. Pero parece que solo funciona en variables públicas. Sólo cambia el interruptor a esta para que pueda acceder a los privados/protegidas:

switch($match[1]) { 
    case 'get': return self::${$property->name}; 
    case 'set': return self::${$property->name} = $args[0]; 
} 

Y usted probablemente querrá cambiar la declaración if para limitar las variables que son accesibles, o de lo contrario sería contrario al propósito de haciéndolos ser privados o protegidos.

if ($reflector->hasProperty($property) && in_array($property, array("allowedBVariable1", "allowedVariable2"))) {...) 

Así, por ejemplo, tengo una clase diseñada para tirar de varios datos para sacarme de un servidor remoto a través de un módulo ssh pera, y lo quiero hacer ciertas suposiciones sobre el directorio de destino en función de qué servidor es se le pide que mire. Una versión ajustada del método de mbrzuchalski es perfecta para eso.

static public function __callStatic($method, $args) { 
    if (preg_match('/^([gs]et)([A-Z])(.*)$/', $method, $match)) { 
     $reflector = new \ReflectionClass(__CLASS__); 
     $property = strtolower($match[2]). $match[3]; 
     if ($reflector->hasProperty($property)) { 
      if ($property == "server") { 
       $property = $reflector->getProperty($property); 
       switch($match[1]) { 
        case 'set': 
         self::${$property->name} = $args[0]; 
         if ($args[0] == "server1") self::$targetDir = "/mnt/source/"; 
         elseif($args[0] == "server2") self::$targetDir = "/source/"; 
         else self::$targetDir = "/"; 
        case 'get': return self::${$property->name}; 
       } 
      } else throw new InvalidArgumentException("Property {$property} is not publicly accessible."); 
     } else throw new InvalidArgumentException("Property {$property} doesn't exist."); 
    } 
} 
0

Además, puede obtener acceso a las propiedades estáticas ellos como propiedades de miembro, utilizando __get():

class ClassName { 

static $data = 'smth'; 

function __get($field){ 
     if (isset($this->$field)){ 
      return $this->$field; 
     } 
     if(isset(self::$$field)){ 
      return self::$$field; // here you can get value of static property 
     } 
     return NULL; 
     } 
} 

$obj = new ClassName(); 
echo $obj->data; // "smth" 
+3

excepto que ahora es público, por lo que ni siquiera necesita '__get' –

0

intente esto:

class nameClass{ 
    private static $_sData = []; 
    private static $object = null; 
    private $_oData = []; 

    public function __construct($data=[]){ 
     $this->_oData = $data; 
    } 

    public static function setData($data=[]){ 
     self::$_sData = $data; 
    } 

    public static function Data(){ 
     if(empty(self::$object)){ 
      self::$object = new self(self::$_sData); 
     } 
     return self::$object; 
    } 

    public function __get($key) { 
     if(isset($this->_oData[$key]){ 
      return $this->_oData[$key]; 
     } 
    } 

    public function __set($key, $value) { 
     $this->_oData[$key] = $value; 
    } 
} 

nameClass::setData([ 
    'data1'=>'val1', 
    'data2'=>'val2', 
    'data3'=>'val3', 
    'datan'=>'valn' 
]); 

nameClass::Data()->data1 = 'newValue'; 
echo(nameClass::Data()->data1); 
echo(nameClass::Data()->data2); 
Cuestiones relacionadas