57

I have this:

  • one string variable which holds the class name ($classname)
  • one string variable with holds the property name ($propertyname)

I want to get that property from that class, the problem is, the property is static and I don't know how to do that.

If the property weren't static, it would have been:

$classname->$propertyname;

if the property were a method, I could have used call_user_function

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

But in my case, am I just lost. I am however hoping that it is possible. With the thousands of functions that PHP has, he'd better have something for this as well. Maybe I'm missing something?

Thanks!

Edit:

  • for those with eval() solutions: thanks, but it is out of the question
  • for those with get _class _vars() solutions: thanks, but it seems it returns "the default properties of the given class" (php.net), and yes, I would like that value to be changable (even though it does help me in some of the cases)

11 Answers 11

87

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.

Sign up to request clarification or add additional context in comments.

5 Comments

Oh my god, I was just about to ask "but how about setting...". Dude, you totally rock!
In PHP 5 and up (I'm on 5.2), you can use reflection for this, as I just learned. See my answer here: stackoverflow.com/questions/3354628/…
Shouldn't it be more like classname::$propertyname; in your first example, instead of $classname::$$propertyname;? Maybe this is just a typical version-thingy.
get_user_prop works for me. I wish the PHP Manual included it.
$classname::${$propertyname}; also works and reads less like a typo I might accidentally "correct".
17

I think this is the simplest:

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

Comments

14

To return a variable value that is set by a Static Variable you need to call:

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

Check out the documentation :: PHP Constant Documentation

3 Comments

+1 for the hint. But i think it works only for class constants and not class static variables.
I tested, it does work ONLY with class constants, but NOT with class static variables.
exactly what i was looking for. 10 points
1

You should be able to do something like:

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

I just did a quick test and got this to work for me. Not sure if there's a better way or not, but I wasn't able to find one.

2 Comments

eval is evil :) never use it. there is always better alternatives
"Eval is evil" should be continued with "if you'r unsure of what you are doing" - obviously it can be useful as a last resort or it wouldn't be part of the language.
1

'eval' looks so close to 'evil', and I hate using it and/or seeing it in code. With a few ideas from other answers, here's a way to avoid it even if your php isn't 5.3 or higher.

Changed to reflect testing based on a comment.

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

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

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

echo $vars['foo'];

Outputs 'baz'.

5 Comments

get_class_vars() only returns the initial value of $foo. If $foo changes, the value you will get from get_class_vars() will not change.
Actually, by definition it's not supposed to work, but apparently does.
I agree with your second comment. I thought that was a little weird, so I tested it and updated my answer. Does that match what you found?
Actually, get_class_vars('A') just works fine. You don't need to create an instance.
Sweet. *<|:^) <-- meeting minimum char limit with Santa.
1

One thing I noticed is that you can't set variables which are protected in static classes as the eval() command runs in a scope outside the class. The only thing to get around this would be to implement a static method inside the/every class which runs the eval(). This method could be protected as the call_user_func() [to call the setter method] also runs from inside the class.

Comments

0

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

Comments

0

get_class_vars is not same as get_object_vars.

I think get_clas_vars should return the original property values.

Comments

0

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;

Comments

0

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;
    }
}

1 Comment

It won't work with PHP<5.3 because $object::$$property is not valid syntax for it.
0

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"]);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.