0

Referring to this question ...

How do I access this object property with a hyphenated name?

... I have an additional one:

I want to access a json property that is saved in a variable ... something like ...

$var = '$obj->my-prop';

IF it would just be

$var = 'my-prop'

... I could solve the problem with the hyphenated name by calling it via

$obj->{$var}

which would lead to

$obj->{'my-prop'}

... like it is said in the preceding question.

BUT: My variable also contains the preceding object value ('$obj'). As calling it via {$var} leads to {'$obj->my-prop'}, which is invalid, the only way to solve it seams to be to explode('->',$var) and then concatenate it, which is a mess.

Does someone know the 'solution idéale'? :-)


EDIT: so the solution idéale of one has to solve the question whether to keep this literal object syntax by saving the variable as string that just looks(!) like an object. therefore the unpackPath function of h2ooooooo would be a proper one. In contrast to that to save that variable in a chain as array (as ToBe said) would open a more system appropriate way of processing data. To json_decode a string like 'a->b' is not possible though.

Community
  • 1
  • 1
sasha
  • 769
  • 10
  • 20
  • 1
    Mechanics like these tend to do more harm than good. Are you sure you have to use dynamic variable/property names like this? Can't you just json_decode it and use it as a normal array? – ToBe Oct 17 '14 at 09:32
  • ya, this is right. would be a way to save the variable in a more appropriate or to say a less complicative way of processing this data. on the other way: as my beginning object should not be saved - ... or even in the case that I would save all variables in this array, I would have to use a concatenation-function to create the call/request of the reffered data. – sasha Oct 18 '14 at 09:02

1 Answers1

2

You have to make your own parser (using eg. explode() like you mentioned).

Setup:

<?php

class Foo {
    public $bar;

    public function __construct() {
        $this->bar = new Bar();
    }
}

class Bar {
    public $oof;

    public function __construct() {
        $this->oof = new Oof();
    }
}

class Oof {
    public $id = 123;
}

function unpackPath($object, $path) {
    if (is_string($path)) {
        $path = explode('->', $path);
    }

    $value = $object->{$path[0]};

    if (count($path) == 1) {
        return $value;
    } else {
        return unpackPath($value, array_slice($path, 1));
    }
}

Usage:

$foo = new Foo();
var_dump( unpackPath($foo, 'bar->oof->id') ); // int(123)

DEMO.

Please note that you have to define your start object ($foo) in order to not use global variables.

h2ooooooo
  • 37,963
  • 8
  • 65
  • 101
  • first of all @ h2ooooooo and @ToBe: thanx for your both help- & useful answers! got 2 go on my weekend-starting-trip yesterday, so wasnt able to answer more prompt :-) so this answer is exactly the one my imagination was of. already had coded it in my brain, which seemed (like I said) to complicative. nonetheless: hadn't coded it in this way of not to say OOP but in way of a recursive function, which reduces that complexity in an imho very clean way. thx! – sasha Oct 18 '14 at 08:49
  • 1
    This was extremely helpful for my team on a project where we were unable to parse a complex chain of objects that contained illegitimate sub-object names. The data we are parsing comes through an API that is out of our control, and this gave us a very simple way to pull a selection of parameters with very little code. – bwright Nov 21 '20 at 01:33