wake-up-neo.com

Abrufen einer statischen Eigenschaft von einer Klasse mit dynamischem Klassennamen in PHP

Ich habe das:

  • eine String-Variable, die den Klassennamen enthält ($classname)
  • eine String-Variable mit dem Eigenschaftennamen ($propertyname)

Ich möchte diese Eigenschaft von dieser Klasse erhalten, das Problem ist, die Eigenschaft ist statisch und ich weiß nicht, wie ich das machen soll.

Wenn die Eigenschaft nicht statisch wäre, hätte es Folgendes gegeben:

$classname->$propertyname;

wenn die Eigenschaft eine Methode wäre, hätte ich call_user_function verwenden können

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

Aber in meinem Fall bin ich einfach verloren. Ich hoffe jedoch, dass es möglich ist. Mit den Tausenden von Funktionen, die PHP hat, sollte er auch etwas dafür haben. Vielleicht fehlt mir etwas?

Vielen Dank!

Bearbeiten:

  • für die mit eval () solutions: danke, aber das steht außer Frage
  • für die mit get _class _vars () solutions: Danke, aber es scheint, dass "die Standardeigenschaften der angegebenen Klasse" (php.net) zurückgegeben wird veränderbar (auch wenn es mir in manchen Fällen hilft)
47
treznik

Wenn Sie PHP 5.3.0 oder höher verwenden, können Sie Folgendes verwenden:

$classname::$$propertyname;

Wenn Sie eine niedrigere Version als 5.3.0 verwenden, können Sie leider nicht mehr mit eval() ( get_class_vars() arbeiten, wenn der Wert dynamisch ist).

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

EDIT: Ich habe gerade gesagt, get_class_vars() würde nicht funktionieren, wenn der Wert dynamisch ist, aber anscheinend variable statische Elemente Teil von "den Standardeigenschaften einer Klasse" . Sie können den folgenden Wrapper verwenden:

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

Wenn Sie den Wert der Variablen festlegen möchten, müssen Sie leider immer noch eval() verwenden, aber mit einer gewissen Validierung ist es nicht so schlimm .

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() mit dieser Validierung sollte sicher sein. Wenn Leute anfangen, zufällige Dinge als $className und $property zu schreiben, wird die Funktion beendet, da es sich nicht um eine vorhandene Klasse oder Eigenschaft handelt. Ab $value wird es nie wirklich als Code analysiert, sodass das Skript nicht beeinflusst wird, was auch immer sie dort einfügen.

74
Andrew Moore

Ich denke das ist das einfachste:

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

Um einen Variablenwert zurückzugeben, der von einer statischen Variablen festgelegt wurde, müssen Sie Folgendes aufrufen:

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

Schauen Sie sich die Dokumentation an :: PHP Konstante Dokumentation

10
frodosghost

'eval' sieht so nah an 'böse' und ich hasse es, es zu benutzen und/oder es im Code zu sehen. Mit einigen Ideen aus anderen Antworten können Sie dies vermeiden, auch wenn Ihr PHP-Wert nicht 5.3 oder höher ist. 

Geändert, um Tests basierend auf einem Kommentar widerzuspiegeln.

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

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

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

echo $vars['foo'];

Ausgänge 'baz'.

1
nilamo

Mir ist aufgefallen, dass Sie keine Variablen festlegen können, die in statischen Klassen geschützt sind, da der Befehl eval () in einem Bereich außerhalb der Klasse ausgeführt wird. Um dies zu umgehen, müssen Sie nur eine statische Methode in der/jeder Klasse implementieren, die eval () ausführt. Diese Methode kann geschützt werden, da call_user_func () [zum Aufrufen der Setter-Methode] auch innerhalb der Klasse ausgeführt wird.

1
mbirth

get_class_vars stimmt nicht mit get_object_vars überein.

Ich denke, get_clas_vars sollte die ursprünglichen Eigenschaftswerte zurückgeben.

0
firzen

Selbst wenn für Sie gesagt wurde, dass eval nicht in Frage kommt, ist die einfachste Lösung vor PHP 5.3 die Verwendung von eval:

eval("\$propertyval = $classname::\$propertyname;");
echo $propertyval;
0
Marco Demaio

Möglicherweise relevant: Diskussion der späten statischen Bindung in PHP - Wann müssten Sie die späte statische Bindung verwenden?

0
Alex Weinstein

Sie können ReflectionClass verwenden:

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

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

Sie sollten in der Lage sein, Folgendes zu tun:

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

Ich habe gerade einen kurzen Test gemacht und das für mich funktionieren lassen. Nicht sicher, ob es einen besseren Weg gibt oder nicht, aber ich konnte keinen finden.

0
Steven Surowiec