我是从PHP manual:
中读到的如果将对象转换为数组,则结果是一个数组 元素是对象的属性。键是成员变量 名称,但有一些值得注意的例外: 整数属性 不可访问 ;私有变量具有前缀的类名 变量名;受保护的变量前面有一个'*' 变量名。 这些前置值在任何一方都有空字节。 这可能会导致一些意外行为:
class A { private $A; // This will become '\0A\0A' } class B extends A { private $A; // This will become '\0B\0A' public $AA; // This will become 'AA' } var_dump((array) new B());
以上似乎有两个名为'AA'的键,但其中一个 它们实际上被命名为'\ 0A \ 0A'。
我不太明白那些字体的含义,如 this 。
什么是整数属性?
“这些前置值在两边都有空字节。”这意味着什么?这可能会导致一些意想不到的行为“?
和“是什么意思”?上面会有两个名为'AA'的键,虽然其中一个实际上名为'\ 0A \ 0A'“
答案 0 :(得分:4)
使用此代码可以深入了解新的数组键。
$x = (array)new B();
foreach ($x as $key => $value) {
echo bin2hex($key), ' = ', $value, PHP_EOL;
}
它显示了键值的十六进制表示,您可以从中更清楚地看到正在发生的事情:
00420041 =
4141 =
00410041 =
第一个属性(B::A
)的数组键编码为"\x00B\x00A"
,即chr(0) . 'B' . chr(0) . 'A'
,因为其可见性对B
是私有的。
第二个属性(B::AA
)编码为'AA'
,因为其可见性是公开的。
第三个属性(A::A
)与第一个属性非常相似,编码为"\x00A\x00A"
,因为它的可见性是A
的私有。
我不完全确定它是什么整数属性。我不担心数值属性,因为它们的使用可以忽略不计而且不鼓励(这可能就是为什么没有提到这个“特征”) “。
答案 1 :(得分:3)
这是指名称为十进制整数的字符串表示的属性。例如:
$o = new stdClass;
$o->{"123"} = 'foo'; // create a new integer property
echo $o->{"123"}, PHP_EOL; // verify it's there
$a = (array)$o; // convert to array
echo $a['123']; // OOPS! E_NOTICE: Undefined offset!
var_dump(array_keys($a)); // even though the key appears to be there!
print_r($a); // the value appears to be there too!
通常,PHP中的整数属性不应该出现在if you value your sanity附近的任何位置。
null
对于private
和protected
属性,生成的数组键将包含不可打印的字符"\0"
。这可能很有用(因为该字符对于属性名称不合法,您可以使用此信息来确定属性的可见性),但如果您不希望它存在,那么它也可能会令人讨厌。例如:
class A {
private $A; // This will become '\0A\0A'
}
class B extends A {
private $A; // This will become '\0B\0A'
public $AA; // This will become 'AA'
}
$a = (array) new B();
// The array appears to have the keys "BA", "AA" and "AA" (twice!)
print_r(array_keys($a));
// But in reality, the 1st and 3rd keys contain NULL bytes:
print_r(array_map('bin2hex', array_keys($a)));
您可以从数组键中提取可见性信息,如下所示:
$a = (array) new B();
foreach ($a as $k => $v) {
$parts = explode(chr(0), $k);
if (count($parts) == 1) {
echo 'public $'.$parts[0].PHP_EOL;
}
else if ($parts[1] == "*") {
echo 'protected $'.$parts[2].PHP_EOL;
}
else {
echo 'private '.$parts[1].'::$'.$parts[2].PHP_EOL;
}
}