Можете ли вы объяснить следующее интересное поведение?
class test { //Class *test* has two properties, public and private. public $xpublic = 'x1'; private $xprivate = 'x2'; } $testObj = new test();
Давайте преобразуем $testObj в массив.
settype($testObj, 'array'); var_dump($testObj);
Результат:
array (2) {
["xpublic"] => строка (3) "x1"
["testxprivate"] => строка (4) "x2"
}
OK, свойство testxprivate становится testxprivate
Давайте преобразуем этот массив в объект.
$newObj = (object)$testObj; var_dump($newObj);
Результат:
object (stdClass) # 1 (2) {
["xpublic"] => строка (3) "xxx"
["xprivate": "test": private] => string (4) "xxx3"
}
$newObj – объект stdClass .
И вопрос:
Почему testxprivate становится частным свойством xprivate (а не testxprivate ) нового объекта? Как PHP знает, что $testObj массив является объектом?
Если я определяю равный массив:
$testArray = array('xpublic'=>'x1', 'testxprivate'=>'x2');
а затем преобразовать его в объект:
var_dump((object)$testArray);
Я получу объект с двумя общедоступными свойствами xpublic и testxprivate как и ожидалось:
object (stdClass) # 2 (2) {
["xpublic"] => строка (2) "x1"
["testxprivate"] => строка (2) "x2"
}
Ключ массива содержит маркер, который должен быть частным свойством теста класса.
Сравните выходные данные скриптов со следующим:
$array = array( "xpublic" => "x1", # this will become a private member: "\x00test\x00xprivate" => "x2", # this will become a protected member: "\x00*\x00xprotected" => "x3" ); var_dump($array); $obj = (object) $array; var_dump($obj);
При сериализации одна и та же строка используется для описания частных членов.
Вывод:
array (3) {
[ "Xpublic"] =>
строка (2) "x1"
[ "Testxprivate"] =>
строка (2) "x2"
[ "* Xprotected"] =>
строка (2) "x3"
}
object (stdClass) # 1 (3) {
[ "Xpublic"] =>
строка (2) "x1"
[ "Xprivate": "тест": частная] =>
строка (2) "x2"
[ "Xprotected": защита] =>
строка (2) "x3"
}
В выводе var_dump() нулевые байты не видны.
(Обновление: добавлен защищенный член класса)
Вероятно, PHP-движок сохраняет структуру класса внутри себя и просто дает какую-то оболочку массива, и, таким образом, при повторном запуске он остается закрытым, хотя я не могу гарантировать это на 100%.