2009-03-23 20 views
25

Estoy intentando acceder a una variable estática dentro de una clase mediante el uso de un nombre de clase variable. Soy consciente de que con el fin de acceder a una funcióndentro de la clase, se utiliza call_user_func():

class foo { 
    function bar() { echo 'hi'; } 
} 
$class = 'foo'; 
call_user_func(array($class, 'bar')); // prints hi 

Sin embargo, esto no funciona cuando se trata de acceder a una variable de estática dentro de la clase:

class foo { 
    public static $bar = 'hi'; 
} 
$class = "foo"; 
call_user_func(array($class, 'bar')); // nothing 
echo $foo::$bar; // invalid 

¿Cómo puedo obtener esta variable? ¿Es posible? Tengo un mal presentimiento de que solo está disponible en PHP 5.3 en el futuro y estoy ejecutando PHP 5.2.6.

+0

@Krinkle, por favor no se acostumbre a agregar texto en negrita, no ayuda tanto como a mucha gente. ¡Gracias! – sarnold

Respuesta

24

Usted puede utilizar reflection para hacer esto. Cree un objeto ReflectionClass dado el nombre de clase, y luego use el método getStaticPropertyValue para obtener el valor de la variable estática.

class Demo 
{ 
    public static $foo = 42; 
} 

$class = new ReflectionClass('Demo'); 
$value=$class->getStaticPropertyValue('foo'); 
var_dump($value); 
+0

Me he dado cuenta de que getStaticPropertyValue ($ prop) no parece funcionar si $ prop es cualquier cosa menos "pública estática". Se borrará si $ prop es declarado "estático privado" o "estático protegido" en la clase. Aunque no estoy exactamente seguro de por qué. – brianjcohen

+10

Esto tiene sentido, ya que si NO es público, no debería tener acceso desde fuera de la clase. – adudley

21

Para los miembros estáticos de llamadas que usted puede utilizar un código como el siguiente:

call_user_func("MyClass::my_static_method"); 
// or 
call_user_func(array("MyClass", "my_static_method")); 

Por desgracia, la única manera de conseguir que los miembros estáticos de un objeto parece ser get_class_vars():

$vars = get_class_vars("MyClass"); 
$vars['my_static_attribute']; 
24

Creo que hay una manera mucho mejor (más elegante) de crear la instancia de ReflectionClass. También edité este código (y mi respuesta) después de algunos comentarios. Agregué un ejemplo para las variables protegidas (por supuesto, no se puede acceder desde fuera de la clase, así que hice un getter estático y lo llamé usando un patrón variable también). Se puede utilizar en varias formas diferentes:

class Demo 
{ 
    public static $foo = 42; 
    protected static $boo = 43; 
    public static function getProtected($name) { 
     return self::$$name; 
    } 
} 

$var1 = 'foo'; 
$var2 = 'boo'; 
$class = 'Demo'; 
$func = 'getProtected'; 
var_dump(Demo::$$var1); 
var_dump($class::$foo); 
var_dump($class::$$var1); 
//var_dump(Demo::$$var2); // Fatal error: Cannot access protected property Demo::$boo 
var_dump(Demo::getProtected($var2)); 
var_dump($class::getProtected($var2)); 
var_dump($class::$func($var2)); 

La documentación está aquí:

http://php.net/manual/en/language.variables.variable.php

+1

No pensé que esto funcionaría si 'Demo' era una variable ... pero lo hace:' $ class :: $$ field' – mpen

+0

Sí, lo hace. Me olvidé de escribirlo, ¡gracias! – Karol

+1

'$ class :: $$ field' solo funciona si está usando PHP 5.3 o superior, parece. – jamietelin

2

¿Ha probar esto?

class foo { 
    static public $bar = "Hi"; 

    static public function bar() { 
     echo "Hi"; 
    } 
} 

echo foo::$bar; // Output: Hi 
foo::bar(); // Output: Hi 

$class = "foo"; 
echo $class::$bar; // Output: Hi 
$class::bar(); // Output: Hi 
call_user_func($class, 'bar'); // Output: Hi 
+2

La pregunta tiene 4 años y se refiere explícitamente a una versión antigua de PHP donde '$ class: : $ bar' no fue posible todavía. –

Cuestiones relacionadas