PHP中的数组到Object和Object to Array - 有趣的行为

时间:2011-06-12 23:36:30

标签: php arrays object casting

你能解释下一个有趣的行为吗?

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

让我们将这个数组转换为object。

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

结果:

object(stdClass)#1 (2) {
  ["xpublic"]=> string(3) "xxx"
  ["xprivate":"test":private]=> string(4) "xxx3"
}

$newObjstdClass个对象。

问题是:

为什么testxprivate成为新对象的私有属性xprivate(不是testxprivate)? PHP如何知道$testObj数组是一个对象?

如果我定义相等的数组:

$testArray = array('xpublic'=>'x1', 'testxprivate'=>'x2');

然后将其转换为对象:

var_dump((object)$testArray);

我会按预期获得包含两个公共属性xpublictestxprivate的对象:

object(stdClass)#2 (2) {
  ["xpublic"]=> string(2) "x1"
  ["testxprivate"]=> string(2) "x2"
}

2 个答案:

答案 0 :(得分:20)

数组键包含一个标记,该标记应该是类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()的输出中,空字节不可见。

(更新:添加受保护的类成员)

答案 1 :(得分:0)

可能PHP引擎内部保留了类结构,只是简单地给出了一种数组包装器,因此当你再次强制它时,它仍然是私有的,但我无法保证100%。