これがどのように機能するかは、draw010 の回答よりも少し複雑です。これは誤解を招くので、これを明確にする必要があると感じました。次のテスト ケースを検討してください。
main.php
<?php
require('/tmp/functions.php');
echo "exists=",function_exists('a1'),"\n";
a();
echo "exists=",function_exists('a1'),"\n";
a1();
?>
関数.php
<?php
function a(){
require('a1.php');
}
a1.php
これにより、次の出力が生成されます。
exists=
exists=1
Hello World
つまり、 が呼び出されるa1()
まで存在しませんがa()
、グローバルに使用できるようになります。別の例を考えてみましょう:
<?php
$a=false;
if( $a ){
function x() {return 1;}
} else {
function x() {return 2;}
}
echo x();
これも完全に有効で、 が表示されます2
。true$a
に設定されていた場合、答えは になります。このコードの VLD を実行すると、その理由がわかります。2 つの関数は、期待どおりのオペコード シーケンスを発行しますが、スクリプト ファイルのパスに基づいて呼び出し不可能な名前が付けられます (私の場合はと)。呼び出しコードは、1
%00x%2Ftmp%2Fy.php0x7fb364a1a03
%00x%2Ftmp%2Fy.php0x7fb364a1a06
ZEND_DECLARE_FUNCTION '%00x%2Ftmp%2Fy.php0x7fb364a1a033', 'x'
最初の宣言が行われるパスポイントで。これにより、関数が as として使用可能にx()
なり、同様のZEND_DECLARE_FUNCTIONによって、2 番目の関数x()
が別のパスで as として使用可能になります。
クラスでもまったく同じメカニズムが機能しますが、この場合、ZEND_DECLARE_CLASSが呼び出されて、内部クラス名がパブリック エイリアスにバインドされます。