从PHP中使用动态类名获取静态属性

时间:2009-08-14 17:23:45

标签: php oop dynamic static properties

我有这个:

  • 一个包含类名($classname
  • 的字符串变量
  • 一个字符串变量,包含属性名称($propertyname

我想从该类获取该属性,问题是,该属性是静态的,我不知道该怎么做。

如果属性不是静态的,那就是:

$classname->$propertyname;

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

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

但就我而言,我只是输了。但我希望这是可能的。有了PHP拥有的数千个函数,他最好也有这方面的东西。也许我错过了什么?

谢谢!

编辑:

  • 对于那些有eval()解决方案的人:谢谢,但这是不可能的
  • 对于那些有get _class _vars()解决方案的人:谢谢,但似乎它返回“给定类的默认属性”(php.net),是的,我想要那个值可以改变(即使它在某些情况下对我有帮助)

11 个答案:

答案 0 :(得分:74)

如果您使用的是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开始,它实际上从未被解析为代码,因此无论它们放在哪里都不会影响脚本。

答案 1 :(得分:15)

我认为这是最简单的:

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

答案 2 :(得分:12)

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

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

查看文档:: PHP Constant Documentation

答案 3 :(得分:1)

您应该可以执行以下操作:

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

我刚做了一个快速测试,并让它为我工作。不确定是否有更好的方法,但我找不到。

答案 4 :(得分:1)

'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'];

输出'baz'。

答案 5 :(得分:1)

我注意到的一件事是你不能设置在静态类中受保护的变量,因为eval()命令在类外的作用域中运行。解决这个问题的唯一方法是在每个运行eval()的类中实现一个静态方法。这个方法可以受到保护,因为call_user_func()[调用setter方法]也从类内部运行。

答案 6 :(得分:0)

潜在相关:讨论PHP中的后期静态绑定 - When would you need to use late static binding?

答案 7 :(得分:0)

get_class_varsget_object_vars不同。

我认为get_clas_vars应返回原始属性值。

答案 8 :(得分:0)

即使你说eval是不可能的,在PHP 5.3之前,最简单的解决方案仍然是使用eval

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

答案 9 :(得分:0)

您可以使用ReflectionClass:

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

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

答案 10 :(得分:-1)

在不使用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;
    }
}