問題の原因
2 日前にグループで new と stdClass について質問した人がいます。具体的なパフォーマンスは次のとおりです:
<?php $a = new stdClass; $b = new $a; var_dump($a, $b);
このコードは正しく実行でき、$a と $b は 2 つの異なるオブジェクトです。 。新しい $a の前に属性が追加され、値が $a に割り当てられた場合でも、 $b は常に空のオブジェクトです。
それでは、なぜ空のオブジェクトが new の後に続くことができるのでしょうか? stdClass には何か特別なものがあるのでしょうか?
実際のパフォーマンス
実際、これは stdClass とはまったく関係なく、たとえば psysh で簡単なテストを実行してください。
>>> $a = new Reflection; => Reflection {#174} >>> $b = new $a; => Reflection {#177}私はここが初めてです。 Reflection クラスのインスタンスは、stdClass と何ら変わりません。もちろん、クラスをカスタマイズすることもできます:
>>> class Test { public $foo = 1; } => null >>> $a = new Test => Test {#178 +foo: 1, } >>> $a->foo = 2; => 2 >>> $b = new $a; => Test {#180 +foo: 1, }この例から、$a の属性を変更しても $b には影響がないことが明確にわかります (ここで PHP のキーワード clone について考えることもできます)。 パフォーマンスがわかったので、次の結論も導き出すことができます。 new クラスのオブジェクトを通じて新しいオブジェクトを作成することは、元のオブジェクトのクラスを new することと同等です。 原因それでは、どのような種類の PHP 実装がこの動作を引き起こすのでしょうか?この問題を分析するためにソース コードから始めましょう。 実際、ソース コードから zend_vm_def.h に直接アクセスすると、オペコード ZEND_FETCH_CLASS の説明で次のことがわかります:
ZEND_VM_HANDLER(109, ZEND_FETCH_CLASS, ANY, CONST|TMPVAR|UNUSED|CV) { ... if (OP2_TYPE == IS_CONST) { ... } else if (Z_TYPE_P(class_name) == IS_OBJECT) { Z_CE_P(EX_VAR(opline->result.var)) = Z_OBJCE_P(class_name); } ... ... }いくつかの干渉するコンテキストを削除すると、上記の内容が表示されます。明確に示されています。説明は次のとおりです。取得した class_name がオブジェクトの場合は、Z_OBJCE_P マクロを通じてそのクラスを見つけます。したがって、上記のパフォーマンスは簡単に説明できます。 これ自体はとてもシンプルな質問なので、難しく考える必要はありません。 new の特定の実装を知りたい場合は、zend_compile.c ファイルに移動して zend_compile_new の実装を表示できます。