Can PHP dissect its own syntax? For example, I’d like to write a function that takes in an input like $object->attribute and says to itself:
OK, he’s giving me
$foo->bar, which means he must think that$foois an object that has a property calledbar. Before I try accessingbarand potentially get a ‘Trying to get property of non-object’ error, let me check whether$foois even an object.
The end goal is to echo a value if it is set, and fail silently if not.
I want to avoid repetition like this:
<input value="<? if(is_object($foo) && is_set($foo->bar)){ echo $foo->bar; }?> "/>
…and to avoid writing a function that does the above, but has to have the object and attribute passed in separately, like this:
<input value="<? echoAttribute($foo,'bar') ?>" />
…but to instead write something which:
- preserves the object->attribute syntax
- is flexible: can also handle array keys or regular variables
Like this:
<input value="<? echoIfSet($foo->bar); ?> />
<input value="<? echoIfSet($baz['buzz']); ?> />
<input value="<? echoIfSet($moo); ?> />
But this all depends on PHP being able to tell me "what kind of thing am I asking for when I say $object->attribute or $array[$key]", so that my function can handle each according to its own type.
Is this possible?
Update
I got some good answers here and did some experimenting. Wanted to summarize.
- The answer to my original question appears to be "no," but we did find a way to accomplish was I was trying to do. Techpriester pointed out that I could pass the string ‘$foo->bar’ to a function and have it parse that and
eval()it. Not the approach I want to take, but deserves a mention. - Peter Bailey pointed out that something like
$foo->bargets evaluated before getting passed to a function. I should have thought of this, but for some reason didn’t. Thanks, Peter! - Will Vousden showed that passing
$foo->$barby reference allows the function to evaluate it, rather than having it evaluated beforehand. His function shows thatisset($foo->bar)will not complain if$foois not an object, which I didn’t know.
More interestingly, his example seems to imply that PHP waits to evaluate a variable until it absolutely has to.
If you’re passing something by value, then of course PHP has to determine the value right then. Like this:
$foo->bar = 'hi';
somefunction($foo->bar); // same as somefunction('hi');
But if you’re passing by reference, it can wait to determine the value when it actually needs to.
Like this (following the order in which things happen):
echo ifSet($foo->bar); // PHP has not yet evaluated $foo->bar...
function ifSet(&$somevar){ // ...because we're passing by reference (&$somevar)
// Now we're inside the function, but it still hasn't evaluated $foo->bar; it
// just made its local variable, $somevar, point to the same thing as $foo->bar
if(isset($somevar)){ // Right HERE is where it's evaluated - when we need it
return $bar;
}
}
Thanks to everyone who responded! If I’ve misstated something, please let me know.
You can pass it by reference:
Note that this won’t work if you try to access an object as an array or vice versa.
You shouldn’t try to rely on something like this too much, though.