Можете ли вы объяснить следующее интересное поведение?
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%.