ホームページ >バックエンド開発 >PHPチュートリアル >PHP変数のスコープ
変数のスコープは、変数が定義されているコンテキスト (つまり、その有効スコープ) です。ほとんどの PHP 変数にはスコープが 1 つだけあります。この単一スコープ スパンには、 include および require によって導入されたファイルも含まれます。例:
<?php $a = 1; include 'b.inc'; ?>
この変数 $a は、インクルード ファイル b.inc で有効になります。ただし、ユーザー定義関数では、ローカル関数スコープが導入されます。関数内で使用される変数は、デフォルトではローカル関数のスコープに制限されます。例:
<?php $a = 1; /* global scope */ function Test() { echo $a; /* reference to local scope variable */ } Test(); ?>
echo ステートメントは変数 $a のローカル バージョンを参照しており、このスコープ内の値が割り当てられていないため、このスクリプトは出力を生成しません。 PHP のグローバル変数は C 言語とは少し異なることに気づくかもしれません。C 言語では、ローカル変数によってオーバーライドされない限り、グローバル変数は関数内で自動的に有効になります。これにより問題が発生する可能性があり、誰かが誤ってグローバル変数を変更してしまう可能性があります。 PHP のグローバル変数を関数で使用する場合は、グローバル変数を宣言する必要があります。
グローバルキーワード
まず、グローバルの使用例:
例 #1 グローバルの使用
<?php $a = 1; $b = 2; function Sum() { global $a, $b; $b = $a + $b; } Sum(); echo $b; ?>
上記のスクリプトの出力は「3」になります。グローバル変数 $a および $b が関数内で宣言されると、いずれかの変数へのすべての参照がそのグローバル バージョンを指します。 PHP では、関数が宣言できるグローバル変数の最大数に制限はありません。
グローバル スコープ内の変数にアクセスする 2 番目の方法は、特別な PHP カスタム $GLOBALS 配列を使用することです。前の例は次のように記述できます:
例 #2 global の代わりに $GLOBALS を使用します
<?php $a = 1; $b = 2; function Sum() { $GLOBALS['b'] = $GLOBALS['a'] + $GLOBALS['b']; } Sum(); echo $b; ?>
$GLOBALS は連想配列であり、各変数は要素であり、キー名は変数名に対応し、値は変数の内容。 $GLOBALS はスーパーグローバル変数であるため、$GLOBALS はグローバル スコープ内に存在します。次の例は、スーパーグローバル変数の有用性を示しています。
例 #3 スーパーグローバル変数とスコープを示す例
<?php function test_global() { // 大多数的预定义变量并不 "super",它们需要用 'global' 关键字来使它们在函数的本地区域中有效。 global $HTTP_POST_VARS; echo $HTTP_POST_VARS['name']; // Superglobals 在任何范围内都有效,它们并不需要 'global' 声明。Superglobals 是在 PHP 4.1.0 引入的。 echo $_POST['name']; } ?>
静的変数の使用
変数スコープのもう 1 つの重要な機能は、静的変数です。静的変数はローカル関数スコープ内にのみ存在しますが、プログラムの実行がこのスコープを離れても、その値は失われません。次の例を見てください:
例 #4 静的変数を必要とする例を示します
<?php function Test() { $a = 0; echo $a; $a++; } ?>
この関数は、呼び出されるたびに $a の値を 0 に設定し、0 を出力するため、あまり役に立ちません。変数を 1 つインクリメントする $a++ は、この関数が終了すると変数 $a が存在しなくなるため、効果がありません。現在のカウント値を失わないカウント関数を作成するには、変数 $a を静的として定義します:
例 #5 静的変数の使用例
<?php function test() { static $a = 0; echo $a; $a++; } ?>
これで、変数 $a は test( が呼び出された場合にのみ使用されます)初めて ) 関数が初期化され、それ以降 test() 関数が呼び出されるたびに $a の値が出力され、1 ずつ増加します。
静的変数は、再帰関数を処理する方法も提供します。再帰関数は、それ自体を呼び出す関数です。再帰関数を作成するときは、無限に再帰する可能性があるので注意してください。再帰を終了する適切な方法があることを確認する必要があります。次の単純な関数は、静的変数 $count を使用して再帰的に 10 までカウントし、いつ停止するかを決定します:
例 #6 静的変数と再帰関数
<?php function test() { static $count = 0; $count++; echo $count; if ($count < 10) { test(); } $count--; } ?>
静的変数は、上の例のように宣言できます。これを宣言内の式の結果に代入すると、解析エラーが発生します。
例 #7 静的変数の宣言
<?php function foo(){ static $int = 0; // correct static $int = 1+2; // wrong (as it is an expression) static $int = sqrt(121); // wrong (as it is an expression too) $int++; echo $int; } ?>
静的宣言はコンパイル時に解決されます。
関数の外で global キーワードを使用することに問題はありません。関数内にファイルを含める場合に使用できます。
グローバル変数と静的変数への参照
PHP4 を駆動する Zend エンジン 1 世代では、変数の静的定義とグローバル定義は参照の形式で実装されます。たとえば、関数スコープ内の global ステートメントを使用してインポートされた真のグローバル変数は、実際にグローバル変数への参照を確立します。これは、次の例に示すように、予期しない動作を引き起こす可能性があります:
<?php function test_global_ref() { global $obj; $obj = &new stdclass; } function test_global_noref() { global $obj; $obj = new stdclass; } test_global_ref(); var_dump($obj); test_global_noref(); var_dump($obj); ?>
上記のルーチンは出力します:
NULL
object(stdClass)(0) {}
同様の動作は、静的ステートメントにも適用されます。参照は静的に保存されません:
<?php function &get_instance_ref() { static $obj; echo 'Static object: '; var_dump($obj); if (!isset($obj)) { // 将一个引用赋值给静态变量 $obj = &new stdclass; } $obj->property++; return $obj; } function &get_instance_noref() { static $obj; echo 'Static object: '; var_dump($obj); if (!isset($obj)) { // 将一个对象赋值给静态变量 $obj = new stdclass; } $obj->property++; return $obj; } $obj1 = get_instance_ref(); $still_obj1 = get_instance_ref(); echo "\n"; $obj2 = get_instance_noref(); $still_obj2 = get_instance_noref(); ?>
上記のルーチンは次のように出力します:
Static object: NULL Static object: NULL Static object: NULL Static object: object(stdClass)(1) { ["property"]=>int(1) }
上記の例は、参照が静的変数に割り当てられるとき、&get_instance_ref() 関数が 2 回目にライブで呼び出されるとき、その値は記憶されないことを示しています。 。