36h6qa
Last Updated: May 15, 2019
·
13.83K
· Ocramius

Converting PHP Objects to Arrays to read private members

Since long time ago, PHP supports the very interesting yet feature of object to array conversion through simple casting via (array):

<?php

class Foo {
    public $bar = 'barValue';
}

var_dump((array) new Foo());

You can see a running example at http://3v4l.org/FC3WT

This allows us to apply fast conversions when serializing data in JSON or XML for example.

Weirdly, it allows us to also retrieve private and protected properties:

<?php

class Foo {
    public $bar = 'barValue';
    protected $baz = 'bazValue';
    private $tab = 'tabValue';
}

var_dump((array) new Foo());

A live example is at http://3v4l.org/sGnfO

The keys for private and protected values are quite strange though:

  • For protected values, the key is "\0*\0$propertyName"
  • For private values, the key is "\0$classFQCN\0$propertyName"

You can see a quick demonstration at http://3v4l.org/6o7Ac

While this may not make sense to many people, this is how actually PHP represents objects internally, and it is thought this way to avoid any collisions in object serialization.

Use with caution - clearly violates OOP principles

I wrote more extensively on the topic at http://ocramius.github.io/blog/fast-php-object-to-array-conversion/

3 Responses
Add your response

8615

The other way around, the null characters allow you to have a standard class (stdClass) instance with private/protected members.

<?php

class Foo {
    public $bar = 'barValue';
    protected $baz = 'bazValue';
    private $tab = 'tabValue';
}

print_r((object) (array) new Foo);
stdClass Object
(
    [bar] => barValue
    [baz:protected] => bazValue
    [tab:Foo:private] => tabValue
)
over 1 year ago ·
8616

Nice trick! Though stdClass is basically useless :(

over 1 year ago ·
28898

Nice idea, but you can solve this problem with fully readable array index names (from property names) by using getobjectvars() from within the class. Just add an export method to the class that returns return get_object_vars($this);. That gives you everything you need. No weird index names or anything like that.

over 1 year ago ·