注: これは、PHP の変数スコープを扱う参考質問です。このパターンに当てはまる多くの質問を、この質問と重複するものとして閉じてください。
PHP の「変数スコープ」とは何ですか?ある .php ファイル内の変数に別の .php ファイルからアクセスできますか? 「未定義の変数」 エラーが時々表示されるのはなぜですか?
関数スコープ内で定義された変数には外部からアクセスできませんが、関数の完了後にその値を使用できないわけではありません。 PHP には、オブジェクト指向 PHP で静的メソッドとプロパティを定義するために広く使用されているよく知られた static キーワードがありますが、static は関数内でも使用できることを覚えておく必要があります。静的変数を定義します。
static
静的変数は、関数スコープで定義された通常の変数とは異なり、プログラムの実行がスコープを離れても、静的変数の値は失われません。静的変数を使用した次の例を考えてみましょう:
を使用せずに $counter を定義すると、毎回エコーされる値は、関数に渡される $num パラメーターと同じになります。この単純なカウンターは、追加の回避策なしで static を使用して構築できます。
$counter
$num
これは、同じクラスのオブジェクトにのみ適用されます。静的変数は、オブジェクトが異なるクラスに属している場合 (または相互に拡張している場合)、期待どおりに動作します。
関数呼び出し間で値を保持するもう 1 つの方法は、クロージャを使用することです。クロージャは PHP 5.3 で導入されました。つまり、関数のスコープ内の特定の変数セットへのアクセスを、それらにアクセスする唯一の方法である別の匿名関数に制限することができます。クロージャ変数内にあると、構造化プログラミングの「クラス定数」(クロージャ内で値によって渡される場合) や「プライベート プロパティ」(参照によって渡される場合) などの OOP 概念を (多かれ少なかれうまく) エミュレートできます。
後者では、実際には静的変数の代わりにクロージャを使用できます。何を使用するかを決定するのは常に開発者次第ですが、静的変数は再帰を使用するときに間違いなく便利であり、開発者の注意を払う価値があることに注意してください。
変数の「範囲」または「アクセスできる場所」は制限されています。 $foo = 'bar'; をアプリケーションの どこかに一度書いたからといって、 foo >他の場所## から $ を参照できるわけではありません。 # アプリケーション内で。変数 $foo には特定のスコープがあり、そのスコープ内で有効であり、同じスコープ内のコードのみが変数にアクセスできます。 PHP でスコープを定義するにはどうすればよいですか?
どこかに一度書いたからといって、
$ を参照できるわけではありません。 # アプリケーション内で。変数
があります。これは、PHP に存在する唯一の範囲区切り文字です。関数内の変数は、その関数内でのみ使用できます。関数の外側の変数は関数の外側のどこでも使用できますが、関数の内部では使用できません。これは、PHP には特別なスコープ (global スコープ) があることを意味します。関数の外で宣言された変数はすべて、このグローバル スコープ内にあります。 ###例:### リーリー
スコープ内にあり、$baz は myFunc の local スコープ内にあります。 myFunc 内のコードのみが $baz にアクセスできます。 myFunc の外部のコードのみが $foo にアクセスできます。どちらの当事者も他方にアクセスできません: リーリー スコープと含まれるファイル ファイル境界分離されていません 範囲:
$baz
myFunc
$baz にアクセスできます。 myFunc の外部のコードのみが $foo にアクセスできます。どちらの当事者も他方にアクセスできません: リーリー スコープと含まれるファイル ファイル境界分離されていません 範囲:
$foo
リーリー
分離されていません
コードに適用されるルールは、他のコードに適用されるルールと同じです。 関数 のみに別個のスコープが適用されます。範囲を広げるために、コードをコピーして貼り付ける次のようなファイルを含めることを検討してください:
c.php リーリー 上記の例では、
c.php
は myFunc 内に含まれており、
内の変数はローカル関数スコープのみを持ちます。 が a.php 内のグローバル スコープ内にあるように見えるからといって、必ずしも実際にそうであるとは限りません。実際には、コードが含まれる/実行されるコンテキストによって異なります。 関数やクラス内の関数についてはどうすればよいでしょうか? 新しい function 宣言ごとに、新しいスコープが導入されます。これは非常に簡単です。
が
内のグローバル スコープ内にあるように見えるからといって、必ずしも実際にそうであるとは限りません。実際には、コードが含まれる/実行されるコンテキストによって異なります。
関数やクラス内の関数についてはどうすればよいでしょうか?
宣言ごとに、新しいスコープが導入されます。これは非常に簡単です。
スコープの問題に対処するのは面倒に思えるかもしれませんが、 変数のスコープを制限することは、複雑なアプリケーションを作成する上で非常に重要です。
スコープの問題に対処するのは面倒に思えるかもしれませんが、
変数$barは、この範囲を関数パラメータとして明示的に入力します。この関数を見るだけで、使用する値がどこから来たのかは明らかです。次に、明示的に 値を返します。呼び出し元は、関数がどの変数を使用するか、その戻り値がどこから来るかを知っているという自信を持っています。 リーリー 変数のスコープを匿名関数に拡張する
$bar
を明示的に組み込みます。これは global スコープとは異なることに注意してください。 間違った方法:
global
(自分が何をしているのか本当に本当に理解している場合を除き、たとえそうであったとしても、それはやめてください!) この関数の呼び出し元に表示される内容は次のとおりです: リーリー この関数に
(自分が何をしているのか本当に本当に理解している場合を除き、たとえそうであったとしても、それはやめてください!)
が、副作用はあります。一部の関数は常に
に何らかのグローバル状態を必要とするため、これは簡単に混乱を招く可能性があります。関数を ステートレスにして、何度呼び出しても、入力に対してのみ動作し、定義された出力を返すようにする必要があります。 可能であれば、いかなる方法でもグローバル スコープの使用を避けるべきです。最も確実なのは、変数をグローバル スコープからローカル スコープに「プル」しないことです。
関数スコープ内で定義された変数には外部からアクセスできませんが、関数の完了後にその値を使用できないわけではありません。 PHP には、オブジェクト指向 PHP で静的メソッドとプロパティを定義するために広く使用されているよく知られた
static
キーワードがありますが、static
は関数内でも使用できることを覚えておく必要があります。静的変数を定義します。「静的変数」とは何ですか?
静的変数は、関数スコープで定義された通常の変数とは異なり、プログラムの実行がスコープを離れても、静的変数の値は失われません。静的変数を使用した次の例を考えてみましょう:
リーリー ###結果:### リーリー staticを使用せずに
静的変数の使用例$counter
を定義すると、毎回エコーされる値は、関数に渡される$num
パラメーターと同じになります。この単純なカウンターは、追加の回避策なしでstatic
を使用して構築できます。静的変数はスカラーまたはスカラーとしてのみ定義できます 式 (PHP 5.6 以降)。必然的に他の値を割り当てます 少なくともこの記事を書いている時点では、これは失敗に終わります。 ただし、コードの次の行でこれを行うことができます: リーリー ###結果:### リーリー 静的関数はオブジェクトのメソッド間である程度「共有」されます。 クラスメート。次の例を見ると理解しやすいです:
リーリーこれは、同じクラスのオブジェクトにのみ適用されます。静的変数は、オブジェクトが異なるクラスに属している場合 (または相互に拡張している場合)、期待どおりに動作します。
静的変数は関数呼び出し間で値を保持する唯一の方法ですか?関数呼び出し間で値を保持するもう 1 つの方法は、クロージャを使用することです。クロージャは PHP 5.3 で導入されました。つまり、関数のスコープ内の特定の変数セットへのアクセスを、それらにアクセスする唯一の方法である別の匿名関数に制限することができます。クロージャ変数内にあると、構造化プログラミングの「クラス定数」(クロージャ内で値によって渡される場合) や「プライベート プロパティ」(参照によって渡される場合) などの OOP 概念を (多かれ少なかれうまく) エミュレートできます。
後者では、実際には静的変数の代わりにクロージャを使用できます。何を使用するかを決定するのは常に開発者次第ですが、静的変数は再帰を使用するときに間違いなく便利であり、開発者の注意を払う価値があることに注意してください。
「変数スコープ」とは何ですか?
変数の「範囲」または「アクセスできる場所」は制限されています。 $foo = 'bar'; をアプリケーションの
PHP でスコープを定義するにはどうすればよいですか?
どこかに一度書いたからといって、
foo >他の場所## から$ を参照できるわけではありません。 # アプリケーション内で。変数
$foo には特定のスコープがあり、そのスコープ内で有効であり、同じスコープ内のコードのみが変数にアクセスできます。非常に単純です: PHP には
関数スコープがあります。これは、PHP に存在する唯一の範囲区切り文字です。関数内の変数は、その関数内でのみ使用できます。関数の外側の変数は関数の外側のどこでも使用できますが、関数の内部では使用できません。これは、PHP には特別なスコープ (global スコープ) があることを意味します。関数の外で宣言された変数はすべて、このグローバル スコープ内にあります。 ###例:### リーリー
$fooは myFunc の
globalスコープ内にあり、
a.php$baz
は myFunc の local スコープ内にあります。myFunc
内のコードのみが$baz にアクセスできます。 myFunc
の外部のコードのみが
$foo
にアクセスできます。どちらの当事者も他方にアクセスできません:リーリー
スコープと含まれるファイル ファイル境界分離されていません
範囲:リーリー
b.phpリーリー
includeコードに適用されるルールは、他のコードに適用されるルールと同じです。 関数 のみに別個のスコープが適用されます。範囲を広げるために、コードをコピーして貼り付ける次のようなファイルを含めることを検討してください:
a.phpc.php
リーリー
上記の例では、は myFunc 内に含まれており、
a.php内の変数はローカル関数スコープのみを持ちます。
(匿名)関数内の関数が
a.php内のグローバル スコープ内にあるように見えるからといって、必ずしも実際にそうであるとは限りません。実際には、コードが含まれる/実行されるコンテキストによって異なります。
関数やクラス内の関数についてはどうすればよいでしょうか?
新しい function宣言ごとに、新しいスコープが導入されます。これは非常に簡単です。
リーリー ###コース### リーリー
スコープの用途は何ですか?スコープの問題に対処するのは面倒に思えるかもしれませんが、
変数のスコープを制限することは、複雑なアプリケーションを作成する上で非常に重要です。$name
" を複数の場所で使用することが必要な場合があります。この一意の変数名をアプリケーション内で 1 回しか使用できない場合は、変数が一意であることを確認し、間違ったコード部分から間違った変数を変更しないようにするために、非常に複雑な命名スキームを採用する必要があります。###観察する:### リーリー
スコープがない場合、上記の関数は何をするのでしょうか?$bar
それはどこから来たのですか?それはどのようなステータスを持っていますか?初期化でもされているのでしょうか?毎回確認する必要がありますか?これは保守不可能です。これにより...範囲の境界を越える
正しい方法: 変数の受け渡しと変数の受け渡し
リーリー変数
リーリー$bar
は、この範囲を関数パラメータとして明示的に入力します。この関数を見るだけで、使用する値がどこから来たのかは明らかです。次に、明示的に 値を返します。呼び出し元は、関数がどの変数を使用するか、その戻り値がどこから来るかを知っているという自信を持っています。 リーリー 変数のスコープを匿名関数に拡張する匿名関数は、周囲のスコープに
$fooを明示的に組み込みます。これは
グローバルglobal
スコープとは異なることに注意してください。 間違った方法:$foo
を使用および変更します。 ###こんなことしないで!(自分が何をしているのか本当に本当に理解している場合を除き、たとえそうであったとしても、それはやめてください!)
この関数の呼び出し元に表示される内容は次のとおりです: リーリー この関数にが、副作用はあります。一部の関数は常に
を変更し、に何らかのグローバル状態を必要とするため、これは簡単に混乱を招く可能性があります。関数を ステートレスにして、何度呼び出しても、入力に対してのみ動作し、定義された出力を返すようにする必要があります。 可能であれば、いかなる方法でもグローバル スコープの使用を避けるべきです。最も確実なのは、変数をグローバル スコープからローカル スコープに「プル」しないことです。