我有这个:
- 持有类名(一个字符串变量
$classname
) - 一个字符串变量保存属性名称(
$propertyname
)
我想从这个类获得该财产,但问题是,属性是静态的,我不知道该怎么做。
如果属性不是一成不变的,它会一直:
$classname->$propertyname;
如果属性是一个方法,我也可以使用call_user_function
call_user_func(array($classname, $propertyname));
但对我来说,我只是失去了。 但我希望这是可能的。 随着成千上万的PHP具有的功能,他最好有东西要给这一点。 也许我失去了一些东西?
谢谢!
编辑:
- 对于那些的eval()解决方案:感谢,但它是不可能的
- 对于那些GET _class _ VARS()解决方案:谢谢,但似乎它返回“给定类的默认属性”(php.net),是的,我想这个值是多变的(即使它确实帮助我在某些情况下)
如果您使用的是PHP 5.3.0或更高版本,可以使用以下命令:
$classname::$$propertyname;
不幸的是,如果您使用的是5.3.0以下的版本,使用的是套牢eval()
get_class_vars()
不会,如果值是动态的工作)。
$value = eval($classname.'::$'.$propertyname.';');
编辑:我刚才说get_class_vars()
如果该值是动态的,是行不通的,但显然,变静态成员的“一类的默认属性”的一部分。 你可以使用以下包装:
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
不幸的是,如果你要设置的变量的值,你仍然需要使用eval()
但在一些地方的验证,它不是那么邪恶 。
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()
用这个验证应该是安全的。 如果人们开始把随机东西$className
和$property
,它会退出功能的出来,因为它不会是一个现有的类或属性。 截至$value
,这是从来没有真正解析为代码,因此无论他们摆在那里,不会影响该脚本。
我觉得这是最简单的:
$foo = new ReflectionProperty('myClassName', 'myPropertyName');
print $foo->getValue();
返回由你需要调用一个静态变量设置变量值:
$static_value = constant($classname.'::'.$propertyname);
检查出的文档:: PHP恒文档
“EVAL”看起来如此接近“恶”,我讨厌用它和/或看到它的代码。 与其他答案的一些想法,这里有一个方法来避免它,即使你的php是不是5.3或更高版本。
改变以反映基于注释的测试。
class A {
static $foo = 'bar';
}
A::$foo = 'baz';
$a = new A;
$class = get_class($a);
$vars = get_class_vars($class);
echo $vars['foo'];
输出“巴兹”。
有一两件事我注意到的是,你可以不设置这是在静态类保护的的eval()命令运行的类之外的范围变量。 要解决这个问题的唯一办法是执行一个静态方法内部/每运行于类的eval()。 该方法可被保护为call_user_func()[调用setter方法]也从类内运行。
你应该可以这样做:
eval("echo $classname::$propertyname;");
我只是做了一个快速测试,并得到这个工作对我来说。 不知道是否有更好的方法或没有,但我没能找到一个。
可能相关的:深夜静在PHP结合的讨论- 当你需要使用晚期静态绑定? 。
get_class_vars
不一样get_object_vars
。
我认为get_clas_vars
应该回到原来的属性值。
即使你说eval
是出了问题,之前PHP 5.3的最简单的方法仍然是使用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"]);
获取和不使用反射设置静态和非静态属性
使用反射的作品,但它是昂贵的
以下是我使用的这个目的,
它适用于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;
}
}