6

PHPマニュアルからこれを読みました:

オブジェクトが配列に変換される場合、結果は要素がオブジェクトのプロパティである配列になります。キーはメンバー変数名ですが、いくつかの注目すべき例外があります。整数プロパティにはアクセスできません。プライベート変数には、変数名の前にクラス名が追加されています。保護された変数には、変数名の先頭に「*」が付加されます。これらの先頭に追加された値には、両側に null バイトがあります。 これにより、予期しない動作が発生する可能性があります。

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」という名前の 2 つのキーがあるように見えますが、そのうちの 1 つ は実際には「\0A\0A」という名前です。

このような書体の部分の意味がよくわかりません。

整数プロパティとは

「これらの先頭に追加された値の両側に null バイトがあります。これにより、予期しない動作が発生する可能性があります」の意味は何ですか?

そして、「?上には、'AA' という名前の 2 つのキーがあるように見えますが、そのうちの 1 つは実際には '\0A\0A' という名前です」

4

2 に答える 2

4

このコードを使用すると、新しい配列キーについての洞察を得ることができます。

$x = (array)new B();

foreach ($x as $key => $value) {
    echo bin2hex($key), ' = ', $value, PHP_EOL;
}

キー値の16進表現が表示され、そこから何が起こっているかをより明確に確認できます。

00420041 = 
4141 = 
00410041 = 

最初のプロパティ()の配列キーは、の可視性が。にプライベートであるため、としてB::Aエンコードされます。"\x00B\x00A"chr(0) . 'B' . chr(0) . 'A'B

2番目のプロパティ( )は、可視性が公開されているため、B::AA単純にエンコードされます。'AA'

3番目のプロパティ(A::A)は、最初のプロパティと同様に、"\x00A\x00A"その可視性が。にプライベートであるため、としてエンコードされAます。

ただし、整数プロパティが何であるかは完全にはわかりません。数値プロパティの使用はごくわずかであり、推奨されていないため、数値プロパティについて心配する必要はありません(これが、この「機能」についてあまり言及されていない理由です。

于 2013-01-27T12:21:01.533 に答える
4

整数プロパティ

これは、名前が 10 進整数の文字列表現であるプロパティを指します。例えば:

$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 の整数プロパティは、近くに置くべきものではありません。

で囲まれた先頭の値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;
    }
}
于 2013-01-27T12:44:53.607 に答える