2009-08-14 20 views
43

tengo esto:obtener la propiedad estática de una clase con nombre de clase dinámica en PHP

  • variable de una cadena que contiene el nombre de la clase ($classname)
  • una variable de cadena con ostenta el nombre de la propiedad ($propertyname)

Quiero obtener esa propiedad de esa clase, el problema es que la propiedad es estática y no sé cómo hacer eso.

Si la propiedad no fuera estática, que habría sido:

$classname->$propertyname; 

si la propiedad fueron un método, que podría haber utilizado call_user_function

call_user_func(array($classname, $propertyname)); 

Pero en mi caso, soy yo acaba de perder. Sin embargo, espero que sea posible. Con las miles de funciones que PHP tiene, es mejor que tenga algo para esto también. Tal vez me estoy perdiendo algo?

Gracias!

Editar:

  • para aquellos con eval() soluciones: gracias, pero está fuera de la cuestión
  • para aquellos con get _class _vars() soluciones: gracias, pero parece que vuelve "las propiedades predeterminadas de la clase dada" (php.net), y sí, me gustaría que el valor de ser cambiable (a pesar de que me ayuda en algunos de los casos)

Respuesta

66

Si está usando PHP 5.3.0 o superior, se puede usar la siguiente:

$classname::$$propertyname; 

Por desgracia, si está utilizando una versión inferior a la 5.3.0, está atrapado usando eval() ( get_class_vars() no funcionará si el valor es dinámico).

$value = eval($classname.'::$'.$propertyname.';'); 


EDIT: que acabo de decir get_class_vars() no funcionaría si el valor es dinámico, pero al parecer, los miembros estáticos variables son parte de "las propiedades predeterminadas de una clase ".Se podría utilizar el siguiente contenedor:

function get_user_prop($className, $property) { 
    if(!class_exists($className)) return null; 
    if(!property_exists($className, $property)) return null; 

    $vars = get_class_vars($className); 
    return $vars[$property]; 
} 

class Foo { static $bar = 'Fizz'; } 

echo get_user_prop('Foo', 'bar'); // echoes Fizz 
Foo::$bar = 'Buzz'; 
echo get_user_prop('Foo', 'bar'); // echoes Buzz 

Por desgracia, si desea establecer el valor de la variable, todavía se tendrá que utilizar eval(), pero con algo de validación en su lugar, es no tan mal.

function set_user_prop($className, $property,$value) { 
    if(!class_exists($className)) return false; 
    if(!property_exists($className, $property)) return false; 

    /* Since I cannot trust the value of $value 
    * I am putting it in single quotes (I don't 
    * want its value to be evaled. Now it will 
    * just be parsed as a variable reference). 
    */ 
    eval($className.'::$'.$property.'=$value;'); 
    return true; 
} 

class Foo { static $bar = 'Fizz'; } 

echo get_user_prop('Foo', 'bar'); // echoes Fizz 
set_user_prop('Foo', 'bar', 'Buzz'); 
echo get_user_prop('Foo', 'bar'); // echoes Buzz 

set_user_prop() con esta validación debe ser seguro. Si la gente comienza a poner elementos aleatorios como $className y $property, saldrá de la función ya que no será una clase o propiedad existente. A partir del $value, en realidad nunca se analiza como código, así que lo que sea que pongan allí no afectará al script.

+0

+1 para la función de envoltura. – nilamo

+0

Oh, Dios mío, estaba a punto de preguntar "pero ¿qué tal establecer ...". Amigo, ¡eres totalmente rockero! – treznik

+1

En PHP 5 en adelante (estoy en 5.2), puedes usar la reflexión para esto, como acabo de aprender. Ver mi respuesta aquí: http://stackoverflow.com/questions/3354628/from-the-string-name-of-a-class-can-i-get-a-static-variable/3364090#3364090 –

0

usted debería ser capaz de hacer somethi ng gusta:

eval("echo $classname::$propertyname;"); 

Hice una prueba rápida y conseguí que esto funcionara para mí. No estoy seguro de si hay una manera mejor o no, pero no pude encontrar ninguna.

+1

eval es :) mal nunca usarlo. siempre hay mejores alternativas –

0

'eval' parece tan cerca de 'evil', y odio usarlo y/o verlo en código. Con algunas ideas de otras respuestas, esta es una forma de evitarlo, incluso si su php no es 5.3 o superior.

Se ha modificado para reflejar las pruebas basadas en un comentario.

class A { 
    static $foo = 'bar'; 
} 

A::$foo = 'baz'; 
$a = new A; 

$class = get_class($a); 
$vars = get_class_vars($class); 

echo $vars['foo']; 

Salidas 'baz'.

+2

'get_class_vars()' solo devuelve el valor inicial de '$ foo'. Si '$ foo' cambia, el valor que obtendrá de' get_class_vars() 'no cambiará. –

+0

En realidad, por definición no se supone que funcione, pero aparentemente sí. –

+0

Estoy de acuerdo con su segundo comentario. Pensé que era un poco raro, así que lo probé y actualicé mi respuesta. ¿Eso coincide con lo que encontraste? – nilamo

0

get_class_vars no es lo mismo que get_object_vars.

Creo que get_clas_vars debe devolver los valores de las propiedades originales.

1

Una cosa que noté es que no puede establecer variables que están protegidas en clases estáticas ya que el comando eval() se ejecuta en un ámbito fuera de la clase. Lo único que se puede evitar es implementar un método estático dentro de/cada clase que ejecuta el eval(). Este método podría estar protegido ya que call_user_func() [para llamar al método setter] también se ejecuta desde el interior de la clase.

13

creo que este es el más simple:

$foo = new ReflectionProperty('myClassName', 'myPropertyName'); 
print $foo->getValue(); 
10

para devolver un valor variable que se establece por una variable estática es necesario llamar a:

$static_value = constant($classname.'::'.$propertyname); 

Mira la documentación :: PHP Constant Documentation

+0

+1 para la sugerencia. Pero creo que funciona solo para constantes de clase y no para variables estáticas de clase. –

+0

Probé, funciona SOLAMENTE con constantes de clase, pero NO con variables estáticas de clase. –

0

Incluso si dijiste que eval está fuera de discusión, antes de PHP 5.3 la solución más fácil aún es mediante el uso de eval:

eval("\$propertyval = $classname::\$propertyname;"); 
echo $propertyval; 
-1

Obtención y definición de las propiedades estáticas estáticas y no sin utilizar Reflexión

Usando Reflexión obras, sino que es costoso

Esto es lo que utilizar para este propósito,

Funciona para PHP 5 >= 5.1.0 porque estoy usando property_exist

function getObjectProperty($object, $property) 
{ 
    if (property_exists(get_class($object), $property)) { 
     return array_key_exists($property, get_object_vars($object)) 
      ? $object->{$property} 
      : $object::$$property; 
    } 
} 

function setObjectProperty($object, $property, $value) 
{ 
    if (property_exists(get_class($object), $property)) { 
     array_key_exists($property, get_object_vars($object)) 
      ? $object->{$property} = $value 
      : $object::$$property = $value; 
    } 
} 
+0

No funcionará con PHP <5.3 porque '$ object :: $$ property' no es una sintaxis válida para él. –

0

Puede utilizar ReflectionClass:

class foo 
{ 
    private static $bar = "something"; 
} 

$class = "foo"; 
$reflector = new ReflectionClass($class); 
$static_vars = $reflector->getStaticProperties(); 
var_dump($static_vars["bar"]); 
Cuestiones relacionadas