[解決済み] 参考 変数スコープとは何か、どの変数がどこからアクセス可能か、「未定義変数」エラーとは何か?
質問
<ブロッククオート注:これはPHPで変数スコープを扱うための参考問題です。このパターンに当てはまる多くの質問は、この質問と重複しているものとして閉じてください。
PHPにおけるquot;変数スコープ"とは何ですか?ある .php ファイルの変数に別の .php ファイルからアクセスできますか? なぜ時々 "未定義変数" というエラーが発生します。
解決方法を教えてください。
変数スコープとは何ですか?
変数には、限られたquot;scope"(アクセス可能な場所)があります。例えば
$foo = 'bar';
一度
どこかで
をアプリケーションで参照できるわけではありません。
$foo
から
どこでも
アプリケーション内部で他の 変数
$foo
は有効なスコープが決まっており、同じスコープのコードだけがその変数にアクセスできます。
PHPでは、スコープはどのように定義されるのですか?
非常にシンプルです。PHPは 関数スコープ . PHPに存在するスコープセパレータはこれだけです。関数内の変数は、その関数の内部でのみ使用可能です。関数の外側の変数は、関数の外側のどこでも使用できますが、 どの関数の内側でも使用できるわけではありません。つまり、PHP には特殊なスコープがひとつあります。 グローバル のスコープを使用します。どの関数の外側で宣言された変数も、このグローバルスコープに含まれます。
例
<?php
$foo = 'bar';
function myFunc() {
$baz = 42;
}
$foo
は
グローバル
のスコープを使用します。
$baz
は
ローカル
内のスコープ
myFunc
. の中のコードのみです。
myFunc
にアクセスすることができます。
$baz
. コードのみ
外
myFunc
にアクセスすることができます。
$foo
. どちらも他方にはアクセスできません。
<?php
$foo = 'bar';
function myFunc() {
$baz = 42;
echo $foo; // doesn't work
echo $baz; // works
}
echo $foo; // works
echo $baz; // doesn't work
スコープとインクルードファイル
ファイルの境界は 分離しない スコープを使用します。
a.php
<?php
$foo = 'bar';
b.php
<?php
include 'a.php';
echo $foo; // works!
にも同じルールが適用されます。
include
d のコードに適用されるのは、他のコードに適用されるのと同じです。
function
は別のスコープを持つ。スコープの目的には、コードをコピー&ペーストするようなファイルを含むと考えるとよいでしょう。
c.php
<?php
function myFunc() {
include 'a.php';
echo $foo; // works
}
myFunc();
echo $foo; // doesn't work!
上記の例では
a.php
の中に含まれていた
myFunc
の中にある変数は
a.php
はローカル関数のスコープしか持ちません。ただ、それらが
現れる
でグローバルスコープにあることを示す。
a.php
が必ずしもそうであるとは限りません。実際には、そのコードがどのコンテキストでインクルード/実行されるかに依存します。
関数やクラスの中の関数はどうなりますか?
すべての新しい
function
の宣言は新しいスコープを導入する、それだけです。
(関数の中の(匿名)関数
function foo() {
$foo = 'bar';
$bar = function () {
// no access to $foo
$baz = 'baz';
};
// no access to $baz
}
クラス
$foo = 'foo';
class Bar {
public function baz() {
// no access to $foo
$baz = 'baz';
}
}
// no access to $baz
スコープは何に適しているのか?
スコープの問題への対処は煩わしいと思われるかもしれませんが
複雑なアプリケーションを書くには、変数のスコープを限定することが重要です。
もし、あなたが宣言したすべての変数が、アプリケーション内の他のどこからでも利用できるとしたら、何がどのように変化したかを追跡する本当の方法がないまま、変数を踏み倒すことになるでしょう。変数に付けられる名前は限られているので、おそらく " という変数を使いたいでしょう。
$name
は、複数の場所で使用されています。もしこのユニークな変数名をアプリ内で一度しか使えないとしたら、変数がユニークであることを確認し、間違ったコードの部分から間違った変数を変更していないことを確認するために、非常に複雑な命名スキームに頼らなければならないでしょう。
観察してください。
function foo() {
echo $bar;
}
もしスコープがなかったら、上記の関数は何をするのでしょうか?また
$bar
はどこから来たのか?それはどんな状態なのでしょうか?初期化されているのか?いちいち確認する必要があるのか?これではメンテナンスができません。そこで...
スコープの境界を越える
正しい方法:変数の入出力を行う
function foo($bar) {
echo $bar;
return 42;
}
変数
$bar
は関数の引数としてこのスコープに明示的に入ってきています。この関数を見ただけで、この関数が扱う値がどこから来たのかがわかります。次に、この関数は明示的に
は以下を返します。
という値です。呼び出し側は、この関数がどのような変数を扱うのか、そしてその戻り値はどこから来るのかを確信することができます。
$baz = 'baz';
$blarg = foo($baz);
変数のスコープを無名関数に拡張する
$foo = 'bar';
$baz = function () use ($foo) {
echo $foo;
};
$baz();
この匿名関数は、明示的に
$foo
をその周囲のスコープから削除します。これは
グローバル
のスコープを使用します。
間違った方法
global
先に述べたように、グローバルスコープはやや特殊で、関数はそこから明示的に変数をインポートすることができます。
$foo = 'bar';
function baz() {
global $foo;
echo $foo;
$foo = 'baz';
}
この関数は、グローバル変数
$foo
.
このようなことはしないでください
<サブ
(あなたが本当に本当に本当に何をやっているのか分かっているのであれば別ですが、そうでない場合は: いけません!)
この関数の呼び出し元が見ているのは、これだけです。
baz(); // outputs "bar"
unset($foo);
baz(); // no output, WTF?!
baz(); // outputs "baz", WTF?!?!!
この関数には、何も表示されていません。 サイドエフェクト しかし、それはそうです。これは非常に簡単で、いくつかの関数が を要求し グローバルな状態です。関数は ステートレス 何度呼び出しても、入力に対してのみ動作し、定義された出力を返します。
グローバルスコープの使用はできるだけ避け、グローバルスコープからローカルスコープに変数を「プル&クオット」してはいけません。
関連
-
[解決済み】XAMPPポート80をPID 4の「Unable to open process」が使用中 [重複] XAMPPポート80をPID 4の「Unable to open process」が使用中。]
-
[解決済み】PHP 7.2 - Warning: count(): パラメータは配列かCountableを実装したオブジェクトでなければならない [解決済み]
-
[解決済み】新しいPHPMailerはPHPMailerAutoload.phpが必要?
-
[解決済み] JavaScriptの変数のスコープとは何ですか?
-
[解決済み] "お知らせ 未定義変数"、"Notice: Notice: 未定義のインデックス", "Notice:未定義のインデックス", "Notice."。PHPを使用した「未定義のオフセット
-
[解決済み] Long-Polling、Websocket、Server-Sent Events (SSE)、Cometとは何ですか?
-
[解決済み] クライアントサイドとサーバーサイドのプログラミングの違いは何ですか?
-
[解決済み】PHPパスワードのハッシュとソルトの安全性について
-
[解決済み】PHPで配列やデータをソートするにはどうすればいいですか?
-
[解決済み] リファレンス - このシンボルはPHPで何を意味するのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] 整形されていない数値が発生しました。
-
[解決済み】mysqli_result クラスのオブジェクトを文字列に変換できない
-
[解決済み】PHP 7.2 - Warning: count(): パラメータは配列かCountableを実装したオブジェクトでなければならない [解決済み]
-
[解決済み】pdo - 非オブジェクトのメンバー関数prepare()への呼び出し【重複】。
-
[解決済み】Apache + PHPで「ヘッダの前にスクリプトの出力が終了する」件
-
[解決済み】メッセージ。Trying to access array offset on value of type null [重複]配列のオフセットにアクセスしようとしています。
-
[解決済み】PHP フェイタルエラー。未定義の関数mssql_connect()をコールしています。
-
[解決済み】警告。数値でない値に遭遇しました
-
[解決済み】Wordpressの子テーマのstyle.cssが効かない。
-
[解決済み] 致命的なエラーです。mysqli_result 型のオブジェクトを使用できません [終了] 。