get_mangled_object_vars
Returns all of an object's properties using the engine's internal mangled key names.
get_mangled_object_vars(object $object): array- Added in PHP 7.4
Parameters
| Parameter | Type | Description |
|---|---|---|
$object | object | An object instance. |
Return value
arrayReturns an array whose elements are the object's properties, keyed by the mangled member variable names.
Errors
Throws a TypeError if object is not an object.
get_mangled_object_vars() returns every property of an object regardless of visibility, keyed the way the engine stores them internally. Public names are unchanged; a protected property becomes \0*\0name; a private one becomes \0ClassName\0name, where \0 is a literal NUL byte. This is exactly the array you get from (array) $object, but obtained by a function call you can pass around.
When to reach for it
Serialization and hydration. __serialize(), var_export() replacements, custom encoders and anything reconstructing an object from a raw property array all need the mangled form, because that is what (object) $array and the unserializer expect. It is also the reliable way to snapshot an entire object for a deep-equality check in a test, since it ignores scope.
Things that trip people up
- NUL bytes are invisible in terminal output and in HTML. A
print_r()of the result looks like it has odd blank gaps, andjson_encode()will produce keys with
Example
When to use it
- Build the array returned by a custom __serialize() implementation
- Snapshot every property of an object, including private ones, for a test assertion
- Write an encoder that must round-trip through (object) $array without losing private state
Frequently asked questions
What is the difference between get_mangled_object_vars and get_object_vars?
get_mangled_object_vars() returns every property with engine-mangled keys and ignores the calling scope, while get_object_vars() returns only the properties visible from where you called it, with clean names.
Why do the array keys look broken when I print them?
Private and protected keys contain NUL bytes, which terminals and browsers do not render. Replace "\\0" with something visible before printing, or use var_dump(), which shows the byte length.
Is get_mangled_object_vars the same as casting an object to an array?
Not always. For a plain object the two match, but the cast is not reliable: a class that overrides the conversion hands back something else, so casting an ArrayObject built from ['x' => 'y'] gives that stored array while get_mangled_object_vars() still returns the object's real properties (see the ArrayObject example on the manual page). That reliability, not the syntax, is why the function exists.
More examples
Same result as an array cast
The function and the array cast produce an identical array. The last check succeeds only because the key is built in double quotes so \0 is a real NUL byte — the same literal in single quotes would return false.
<?php
class Point {
public int $x = 1;
protected int $y = 2;
private int $z = 3;
}
$p = new Point();
$mangled = get_mangled_object_vars($p);
$cast = (array) $p;
var_dump($mangled === $cast);
echo count($mangled), " properties, ", count(get_object_vars($p)), " visible outside\n";
var_dump(array_key_exists("\0*\0y", $mangled));Round-tripping an object through its properties
The private property's key is "\0Token\0secret" — a NUL byte, the declaring class, another NUL, then the name. That mangling is why the private value survives: get_mangled_object_vars() returns two entries where get_object_vars(), called from outside the class, returns only the public one.
<?php
class Token {
public function __construct(
public string $name = 'api',
private string $secret = 'shh',
) {}
}
$mangled = get_mangled_object_vars(new Token('web', 'top'));
$plain = get_object_vars(new Token('web', 'top'));
foreach (array_keys($mangled) as $k) {
echo str_replace("\0", '\\0', $k), "\n";
}
echo 'mangled keys: ', count($mangled), "\n";
echo 'plain keys: ', count($plain), "\n";
var_dump(array_values($mangled));
Discussion