什么是整数属性,'\ 0A \ 0A'的含义是什么?

时间:2013-01-27 12:11:06

标签: php

我是从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'“

2 个答案:

答案 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

包围的前置值

对于privateprotected属性,生成的数组键将包含不可打印的字符"\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;
    }
}