1

I was googling and reading the manual, but couldn't find an answer.

Ie, have an array of strings like this:

$a = ['book->name', 'book->id'];

Now I need to get those values from shelf object. Normaly I would just ask:

$bookName = $shelf->book->name;
$bookId = $shelf->book->id;

But how do I read with the 2nd part beeing a string?

If I try $shelf->{$a[0]} I get Undefined property: stdClass::$book->name in....

What is the way to solve this?

PS: I know I can try eval, but would really like not to.

2
  • No, you can't do this. Also, your objects are leaking encapsulation. Commented Dec 28, 2017 at 13:43
  • have you tried $shelf->$a[0] maybe this will work Commented Dec 28, 2017 at 13:51

1 Answer 1

1

You can do this by splitting the string:

$a = ['book->name', 'book->id'];

$parts = explode('->', $a[0]);
$bookName = $shelf->{$parts[0]}->{$parts[1]};

$parts = explode('->', $a[1]);
$bookId = $shelf->{$parts[0]}->{$parts[1]};

This assumes you know how deeply nested your properties are going to be. I'd probably wrap this in a function to be able to handle an unknown number of properties:

function getPropertyByString($object, $properties) {
    $parts = explode('->', $properties);
    $value = $object;

    foreach ($parts as $part) {
        if (!property_exists($value, $part)) {
            throw new OutOfBoundsException('Object does not contain a property called "' . $part . '"');
        }

        $value = $value->$part;
    }

    return $value;
}

$bookName = getPropertyByString($shelf, $a[0]);
$bookId = getPropertyByString($shelf, $a[1]);
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, this was my second option after eval, that I also ended up doing. Thought there might be a oneliner.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.