49 votes

Obtenir une propriété statique d'une classe avec un nom de classe dynamique en PHP

J'ai ceci:

  • une variable de chaîne qui détient le nom de la classe ($classname)
  • une variable de chaîne avec des cales le nom de la propriété ($propertyname)

Je veux obtenir la propriété de cette classe, le problème est que la propriété est statique et je ne sais pas comment faire.

Si la propriété n'était pas statique, il aurait été:

$classname->$propertyname;

si la propriété était une méthode, je pourrais avoir utilisé call_user_function

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

Mais dans mon cas, je suis juste perdu. Je suis cependant en espérant que c'est possible. Avec les milliers de fonctions pour PHP, il est préférable d'en avoir quelque chose pour cela. Peut-être que je suis absent quelque chose?

Merci!

Edit:

  • pour ceux avec la fonction eval() solutions: merci, mais il est hors de question
  • pour ceux avec qui _class _vars() solutions: merci, mais il semble qu'il renvoie "les propriétés par défaut de la classe donnée" (php.net), et oui, je voudrais que la valeur changable (même si elle ne m'aider dans certains cas)

75voto

Andrew Moore Points 49765

Si vous utilisez PHP 5.3.0 ou plus, vous pouvez utiliser les éléments suivants:

$classname::$$propertyname;

Malheureusement, si vous utilisez une version inférieure à la 5.3.0, vous êtes coincé à l'aide de eval() (get_class_vars() ne fonctionnera pas si la valeur est dynamique).

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


EDIT: je viens de le dire get_class_vars() ne fonctionnent pas si la valeur est dynamique, mais apparemment, la variable statique membres font partie de "la valeur par défaut des propriétés d'une classe". Vous pouvez utiliser le wrapper suivant:

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

Malheureusement, si vous souhaitez définir la valeur de la variable, vous devez utiliser eval(), mais avec de la validation en place, c'est pas si 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() avec cette validation doit être sécurisé. Si les gens commencer à mettre des choses au hasard que comme $className et $property, il va quitter la fonction en tant que ce ne sera pas une classe existante ou des biens. Comme d' $value, il n'est jamais réellement analysée comme code de façon à ce qu'il met en il n'y en aura pas d'incidence sur le script.

16voto

Bahadır Points 61

Je pense que c'est le plus simple:

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

13voto

frodosghost Points 315

Pour renvoyer une valeur de variable définie par une variable statique, vous devez appeler:

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

Consultez la documentation :: Documentation constante de PHP

1voto

mbirth Points 11

Une chose que j'ai remarquée est que vous ne pouvez pas définir de variables protégées dans des classes statiques car la commande eval () s'exécute dans une étendue en dehors de la classe. La seule chose à faire serait de mettre en œuvre une méthode statique dans la classe / every qui exécute eval (). Cette méthode peut être protégée car call_user_func () [pour appeler la méthode setter] s'exécute également depuis l'intérieur de la classe.

1voto

Steven Surowiec Points 3833

Vous devriez pouvoir faire quelque chose comme:

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

Je viens de faire un test rapide et cela a fonctionné pour moi. Je ne sais pas s'il existe un meilleur moyen ou non, mais je n'ai pas réussi à en trouver un.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X