PHP: доступ к приватным свойствам
Кинули ссылку на один из способов получения доступа к приватным свойствам в ПХП, тут создаётся функция, которая вызывается в контексте объекта с закрытым свойством:
function inspect_closure(object $o, string $p)
{
return (function () use ($p) {
return $this->$p;
})->call($o);
}
Я решил вспомнить сколько таких способов вообще существует в ПХП.
Сначала, очевидно, на ум должен прийти рефлекшн, ведь он для этого и предназначен:
function inspect_reflection(object $o, string $p)
{
$refClass = new \ReflectionClass(get_class($o));
$refProp = $refClass->getProperty($p);
$refProp->setAccessible(true);
return $refProp->getValue($o);
}
Теперь экзотика. Например, мне вспоминается доступ через преобразование в массив, я о нём уже однажды писал. При преобразовании объекта в массив его приватные и защищённые свойства видны по специальным именам в полном соответствии с документацией:
function inspect_array(object $o, string $p)
{
return ((array) $o)[
sprintf("\0%s\0%s", get_class($o), $p)
];
}
Последний способ самый спорный. Не работает с анонимными классами и объектами, в свойствах которого лежат анонимные функции. А ещё от него легко защититься, если закрыть магический метод, отвечающий за сериализацию.
По сути — родственник предыдущего метода. При сериализации все закрытые свойства в объекте сохраняются под теми же специальными именами, что в предыдущем способе:
function inspect_serialize(object $o, string $p)
{
$class = get_class($o);
$serialized = serialize($o);
if (preg_match("/s:\d+:\"\\0{$class}\\0{$p}\";([^;]+;)/s", $serialized, $m)) {
return unserialize($m[1]);
}
throw new \UnexpectedValueException('Something went wrong.');
}
Конечно такую регулярку очень легко обмануть, более корректно было бы написать парсер, но для иллюстрации принципа, думаю, вполне годится.