Nima Ghaedsharafi
Nima Ghaedsharafi

Reputation: 135

dynamically retrieve object method

I try to dynamically retrieve a method of a class but php throws an exception which says Undefined property: stdClass ...

and How i try to get the values

private function getExactValue($row, $name)
{
    $tempRow = clone $row;
    foreach( explode('->', $name) as $key => $value)
    {
        $temp = $tempRow->{$value};
        unset($tempRow);
        $tempRow = $temp;
    }
    return $tempRow;
}

$row is an instance of an Object (not Std one)

$name is what i need in the Object to traverse , for example when i need $row->student->gifts->totalPoint() just pass the student->gifts->totalPoint() to the method for $name parameter

can you tell me what my mistake is?

Upvotes: 1

Views: 73

Answers (1)

Mike Brant
Mike Brant

Reputation: 71384

I see what you are trying to do here. My first word of advice is that you are going about what you are trying to achieve in a very hackish way. If you wanted a better way to be able to execute arbitrary methods on an unknown object, I would suggest you look into PHP's reflection capabilities.

That being said, the problem with your code would appear to be that you are trying to execute a method via string, where what you need to do is utilize the method's name. What I would suggest is that within your loop where you explode the string on ->, you try to detect if it is a method or not, and then act accordingly. That could look like this:

foreach( explode('->', $name) as $value)
{
    $value_trimmed = rtrim($value, '()');
    if ($value === $value_trimmed) {
        // this is a property
        $tempRow = $tempRow->{$value};
    } else {
        // this is a method
        $tempRow = $tempRow->{$value_trimmed}();
    } 
}

You should probably also do some validation on the input as well to make sure you have valid property/method names for each segment, as well as add validation that the entire string is indeed properly formed (i.e. you don't have things like foo->->bar(())). Of course this make no mention of how to handle array like foo[0]->bar() which you might also need to accommodate.

Upvotes: 2

Related Questions