How can I access a deep object property named as a variable (dot notation) in php?

前端 未结 5 1478
醉梦人生
醉梦人生 2020-11-27 08:05

There are many questions similar to this, however this is slightly different since it\'s about deep object property access, not just one level of depth.

Let\'s say I

相关标签:
5条回答
  • 2020-11-27 08:30

    There is no easy way to do it.

    Fortunately though, lots of people want to do this, so there's libraries that support it, like Symfony's PropertyAccessor:

    http://symfony.com/doc/current/components/property_access.html

    0 讨论(0)
  • 2020-11-27 08:35

    It is very easy to reduce the object path using variable property notation ($o->$p):

    $path = 'foo.bar';
    echo array_reduce(explode('.', $path), function ($o, $p) { return $o->$p; }, $user);
    

    This could easily be turned into a small helper function.

    0 讨论(0)
  • 2020-11-27 08:35

    I am posting this as a compliment to an answer (How to write getter/setter to access multi-level array by key names?) that does the same for arrays.

    Create the $path array via explode() (or add to the function), then use references.

    $path = explode('.', $variable);
    

    Getter

    function get($path, $object) {
        $temp = &$object;
    
        foreach($path as $var) {
            $temp =& $temp->$var;
        }
        return $temp;
    }
    
    $value = get($path, $user);
    

    And of course the evil eval(), not recommended:

    $value = str_replace('.', '->', $variable);
    eval("echo \$user->$value;");
    
    0 讨论(0)
  • 2020-11-27 08:43

    You can use my JSON package using Composer:

    composer require machitgarha/json
    

    For example:

    $userJson = new MAChitgarha\Component\JSON(new User());
    
    $userJson->set("foo", new Foo());
    $userJson->set("foo.bar", "Hello World");
    
    $userJson->get("foo.bar"); // Hello World 
    
    0 讨论(0)
  • 2020-11-27 08:48

    A little improvement added to @deceze post.

    This allow handling cases where you need to go through arrays also.

    $path = 'foo.bar.songs.0.title';
    echo array_reduce(explode('.', $path), function ($o, $p) { return is_numeric($p) ? $o[$p] : $o->$p; }, $user);
    

    Edit:

    And if you have PHP 7+, then the following will safely return null if a property's name is mistyped or if it doesn't exist.

    $path = 'foo.bar.songs.0FOOBAR.title';
    echo array_reduce(explode('.', $path), function ($o, $p) { return is_numeric($p) ? ($o[$p] ?? null) : ($o->$p ?? null); }, $user);
    
    0 讨论(0)
提交回复
热议问题