Getting static property from a class with dynamic class name in PHP

后端 未结 11 481
情歌与酒
情歌与酒 2020-11-30 01:44

I have this:

  • one string variable which holds the class name ($classname)
  • one string variable with holds the property name ($propert
相关标签:
11条回答
  • 2020-11-30 02:02

    I think this is the simplest:

    $foo = new ReflectionProperty('myClassName', 'myPropertyName'); 
    print $foo->getValue();
    
    0 讨论(0)
  • 2020-11-30 02:04

    Even if for you said eval is out of the question, prior PHP 5.3 the easiest solution is still by using eval:

    eval("\$propertyval = $classname::\$propertyname;");
    echo $propertyval;
    
    0 讨论(0)
  • 2020-11-30 02:05

    Potentially relevant: discussion on late static binding in PHP - When would you need to use late static binding?.

    0 讨论(0)
  • 2020-11-30 02:06

    If you are using PHP 5.3.0 or greater, you can use the following:

    $classname::$$propertyname;
    

    Unfortunately, if you are using a version lower than 5.3.0, you are stuck using eval() (get_class_vars() will not work if the value is dynamic).

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


    EDIT: I've just said get_class_vars() wouldn't work if the value is dynamic, but apparently, variable static members are part of "the default properties of a class". You could use the following wrapper:

    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
    

    Unfortunately, if you want to set the value of the variable, you will still need to use eval(), but with some validation in place, it's not so evil.

    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() with this validation should be secure. If people start putting random things as $className and $property, it will exit out of the function as it won't be an existing class or property. As of $value, it is never actually parsed as code so whatever they put in there won't affect the script.

    0 讨论(0)
  • 2020-11-30 02:06

    Getting and setting both static and non static properties without using Reflection

    Using Reflection works but it is costly

    Here is what I use for this purpose,

    It works for PHP 5 >= 5.1.0 because I'm using 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;
        }
    }
    
    0 讨论(0)
  • 2020-11-30 02:07

    You can use ReflectionClass:

    class foo
    {
        private static $bar = "something";
    }
    
    $class = "foo";
    $reflector = new ReflectionClass($class);
    $static_vars = $reflector->getStaticProperties();
    var_dump($static_vars["bar"]);
    
    0 讨论(0)
提交回复
热议问题