Массив к объекту и объект к массиву в PHP - интересное поведение - PullRequest
18 голосов
/ 13 июня 2011

Можете ли вы объяснить следующее интересное поведение?

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"]=> string(3) "x1"
  ["testxprivate"]=> string(4) "x2"
}

ОК,xprivate свойство становится testxprivate

Давайте преобразуем этот массив в объект.

$newObj = (object)$testObj;
var_dump($newObj);

Результат:

object(stdClass)#1 (2) {
  ["xpublic"]=> string(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"]=> string(2) "x1"
  ["testxprivate"]=> string(2) "x2"
}

Ответы [ 2 ]

20 голосов
/ 13 июня 2011

Ключ массива содержит маркер, который должен быть частным свойством класса test.

Сравните вывод ваших скриптов со следующим:

$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"]=>
  string(2) "x1"
  ["testxprivate"]=>
  string(2) "x2"
  ["*xprotected"]=>
  string(2) "x3"
}

object(stdClass)#1 (3) {
  ["xpublic"]=>
  string(2) "x1"
  ["xprivate":"test":private]=>
  string(2) "x2"
  ["xprotected":protected]=>
  string(2) "x3"
}

В выводе var_dump() нулевые байты не видны.

(Обновление: добавлен защищенный член класса)

0 голосов
/ 13 июня 2011

Вероятно, механизм PHP внутренне сохраняет структуру класса и просто дает какую-то оболочку массива, и поэтому при повторном приведении он остается закрытым, хотя я не могу гарантировать это на 100%.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...