PHP言語におけるグローバルと$GLOBALS[]の解析 [転送]
当初、global と $GLOBALS は記述方法が異なるだけで同じだと思っていましたが、実際のアプリケーションでは、この 2 つの違いは依然として非常に大きいことがわかりました。
まず次の例を見てください。
PHP コード
<?php
// 例子1
function test_global() {
global $var1, $var2;
$var2 =& $var1;
}
function test_globals() {
$GLOBALS['var3'] =& $GLOBALS['var1'];
}
$var1 = 5;
$var2 = $var3 = 0;
test_global();
print $var2 ."\n";
test_globals();
print $var3 ."\n";
?>
実行結果は次のとおりです:
0
5
どうしてこれは 2 つの 5 ではないでしょうか? 1 0 と 1 があります。5 はどうでしょうか?
それでは、上記の質問はそのままにして、$GLOBALS とグローバルの原理を詳しく分析してみましょう!
変数が実際にはコード内の対応する物理メモリの「コード名」 上で宣言した 3 つの変数によって割り当てられるメモリが次の図に示されているとします:
PHP マニュアルの $GLOBALS の説明を引用します:
グローバル変数: $GLOBALS
注: PHP 3.0 の $GLOBALS .0 以降のバージョンで適用されます。
定義されたすべてのグローバル変数で構成される配列。変数名は配列のインデックスです。
これは「スーパーグローバル」、または自動グローバル変数として説明できます。
つまり、上記のコードの $var1 と $GLOBALS['var1'] は、2 つの異なる変数ではなく、同じ変数を参照します。
グローバルが何をしたか分析してみましょう?
PHP の関数によって生成される変数は関数のプライベート変数であることは誰もが知っているので、グローバル キーワードによって生成される変数はこの規則を回避できないのはなぜでしょうか。次のコードを見てください。
PHP コード
<?php
// 例子2
function test() {
global $a;
unset($a);
}
$a = 1;
test();
print $a;
?>
コードをコピーします
実行結果は次のとおりです:
1
なぜ 1 が出力されるのですか? $aの設定が解除されていませんか?設定解除に失敗しましたか? PHPのバグ?
いいえ、実際には unset は機能します。test 関数の後に
print $a;
Copy code
を追加できます。つまり、global はテスト関数の外側の $a に対してエイリアス変数 "$a" を生成します。これを --test->$a に変更しました。このような名前も付けられており、次の画像を表示できます:
[画像はありません、ありがとう、騙されました]
次に、上記の例 1 に戻って、これを見てください。 test_global "$var2 =& $var1;" のコード、上記は参照代入操作です。つまり、$var2 は var1 が指す物理メモリ アドレスを指すことになるため、例 1 の test_global 関数を実行した後、次のように変更されます。変数は以下の図で見ることができます:
[画像はありません、ありがとう、騙されました]
test_globals が実行された後、変数の変化を見てください:
この時点で、この図を見ると、例 1 の実行後に $var2 が 0、$var3 が 5 になる理由がわかります。
したがって、関数内の global と $GLOBALS[] の違いは次のとおりであるという結論に達します。
global は、関数の外部変数を指す関数内でエイリアス変数を生成します。 、実際の関数ではありません 外部変数の場合、エイリアス変数のポインティング アドレスが変更されると、例 1 のようないくつかの予期せぬ状況が発生します。
$GLOBALS[] は確かに外部変数と呼ばれ、関数の内部と外部では常に一貫性が保たれます。