What is an integer property and what is the value of '\ 0A \ 0A'?

I read this from the PHP manual :

If the object is converted to an array, the result is an array. Elements are properties of the object. The keys are member variable names with a few notable exceptions: integer properties are not available ; private variables have a class name appended to the variable name; protected variables have "*", the name of the variable. These preliminary values ​​have zero bytes on both sides. This may lead to unexpected behavior:

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()); 

The above will have two keys named "AA", although one of them is actually called '\ 0A \ 0A'.

, this.

?

" . "?

"?" , "AA", "\ 0A\0A"

+5
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.

, . , (, , ".

+4

, . :

$o = new stdClass;
$o->{"123"} = 'foo';        // create a new integer property

echo $o->{"123"}, PHP_EOL;  // verify it 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 -, .

, 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;
    }
}
+3

All Articles