从PHP中使用dynamic类名获得静态属性

我有这个:

  • 一个保存类名的stringvariables( $classname
  • 一个stringvariables与持有属性名称( $propertyname

我想从那个类中获得这个属性,问题是,属性是静态的,我不知道该怎么做。

如果财产不是静态的,那将是:

 $classname->$propertyname; 

如果该属性是一种方法,我可以使用call_user_function

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

但就我而言,我刚刚输了。 然而,我希望这是可能的。 有了PHP的数以千计的function,他最好也有这个function。 也许我错过了什么?

谢谢!

编辑:

  • 对于那些与eval()解决scheme:谢谢,但它是不可能的
  • 对于那些获得_class _vars()解决scheme:谢谢,但它似乎返回“给定类的默认属性” (php.net),是的,我希望这个值是可变的(即使它帮助我在某些情况下)

如果您使用PHP 5.3.0或更高版本,则可以使用以下内容:

 $classname::$$propertyname; 

不幸的是,如果您使用的是低于5.3.0的版本,那么您将使用eval() (如果值是dynamic的, get_class_vars()将不起作用)。

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

编辑:我只是说,如果该值是dynamic的get_class_vars()将无法正常工作,但显然,variables静态成员是“类的默认属性”的一部分 。 你可以使用下面的包装器:

 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 

不幸的是,如果你想设置variables的值,你仍然需要使用eval() ,但是通过一些validation,这并不是那么邪恶

 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 

这个validation的set_user_prop() 应该是安全的。 如果人们开始把随机的东西当作$className$property ,它将退出函数,因为它不会是现有的类或属性。 从$value ,它永远不会被parsing为代码,因此不pipe它们放在哪里都不会影响脚本。

我认为这是最简单的:

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

要返回由静态variables设置的variables值,您需要调用:

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

查阅文档:: PHP常量文档

我注意到的一件事是,你不能设置在静态类中被保护的variables,因为eval()命令在类的范围外运行。 解决这个问题的唯一方法是在运行eval()的每个类中实现一个静态方法。 这个方法可以被保护,因为调用setter方法的call_user_func()也是从类里面运行的。

你应该能够做到这样的事情:

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

我只是做了一个快速testing,并得到这个为我工作。 不知道有没有更好的方法,但我没有find一个。

“eval”看起来如此接近“邪恶”,我讨厌使用它和/或在代码中看到它。 从其他答案的一些想法,这是一个避免它,即使你的PHP不是5.3或更高的方法。

更改为反映基于评论的testing。

 class A { static $foo = 'bar'; } A::$foo = 'baz'; $a = new A; $class = get_class($a); $vars = get_class_vars($class); echo $vars['foo']; 

输出'baz'。

潜在的相关:在PHP中后期静态绑定的讨论 – 你什么时候需要使用迟静态绑定? 。

get_class_varsget_object_vars

我认为get_clas_vars应该返回原来的属性值。

即使对于你说的evaleval的,以前的PHP 5.3最简单的解决scheme仍然是使用eval

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

您可以使用ReflectionClass:

 class foo { private static $bar = "something"; } $class = "foo"; $reflector = new ReflectionClass($class); $static_vars = $reflector->getStaticProperties(); var_dump($static_vars["bar"]); 

在不使用reflection的情况下获取和设置静态和非静态属性

使用reflection的作品,但它是昂贵的

这是我用于这个目的,

它适用于PHP 5 >= 5.1.0因为我使用的是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; } }