【问题标题】:What is a integer property and what's the meaning of '\0A\0A'?什么是整数属性,'\0A\0A' 是什么意思?
【发布时间】:2013-01-27 12:11:06
【问题描述】:

我从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'”

【问题讨论】:

    标签: php


    【解决方案1】:

    整数属性

    这是指名称是十进制整数的字符串表示形式的属性。例如:

    $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;
        }
    }
    

    【讨论】:

      【解决方案2】:

      您可以通过使用此代码对新的数组键有所了解。

      $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 是私有的。

      我不完全确定整数属性是什么。我不会担心数字属性,因为它们的使用可以忽略不计且不鼓励(这可能是为什么没有太多提及这个“功能”。

      【讨论】:

        猜你喜欢
        • 2021-09-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-13
        • 2016-04-06
        • 2016-06-07
        • 1970-01-01
        • 2019-06-12
        相关资源
        最近更新 更多