注:これは、PHPで変数スコープを処理するための参照用の質問です。このパターンの複製として、このパターンに当てはまる多くの質問のいずれかを閉じてください。
PHPの「可変スコープ」とは何ですか?ある.phpファイルの変数は別の.phpファイルからアクセスできますか?「未定義の変数」エラーが発生することがあるのはなぜですか?
変数の「スコープ」または「アクセス可能な場所」は限られています。アプリケーションのどこかに$foo = 'bar';
一度書いたからといって、アプリケーション内の他のどこ$foo
からでも参照できるわけではありません。変数に$foo
は、それが有効である特定のスコープがあり、同じスコープ内のコードのみが変数にアクセスできます。
非常に単純です:PHPには関数スコープがあります。これは、PHPに存在する唯一の種類のスコープセパレーターです。関数内の変数は、その関数内でのみ使用できます。関数外の変数は、関数外のどこでも使用できますが、関数内では使用できません。これは、PHPにはグローバルスコープという1つの特別なスコープがあることを意味します。関数の外部で宣言された変数は、このグローバルスコープ内にあります。
<?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
意味のある名前は非常に多いので、変数「」を複数の場所で使用することをお勧めします。この一意の変数名をアプリで1回しか使用できない場合は、非常に複雑な命名スキームを使用して、変数が一意であり、間違ったコードから間違った変数を変更していないことを確認する必要があります。
観察する:
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?!?!!
この機能に副作用があるという兆候はありませんが、副作用はあります。一部の関数は変更を続け、グローバルな状態を必要とするため、これは非常に簡単に混乱します。関数をステートレスにし、入力のみに作用し、定義された出力を返すようにしますが、何度も呼び出します。
可能な限り、グローバルスコープの使用は避けてください。確かに、変数をグローバルスコープからローカルスコープに「プル」するべきではありません。
関数のスコープ内で定義された変数に外部からアクセスすることはできませんが、その関数の完了後にそれらの値を使用できないことを意味するわけではありません。PHPには、static
静的メソッドとプロパティを定義するためにオブジェクト指向PHPで広く使用されているよく知られたキーワードがありますが、static
静的変数を定義するために関数内でも使用できることに注意してください。
静的変数は、プログラムの実行がこのスコープを離れたときに値が失われない場合、関数のスコープで定義された通常の変数とは異なります。静的変数を使用する次の例を考えてみましょう。
function countSheep($num) {
static $counter = 0;
$counter += $num;
echo "$counter sheep jumped over fence";
}
countSheep(1);
countSheep(2);
countSheep(3);
結果:
1 sheep jumped over fence
3 sheep jumped over fence
6 sheep jumped over fence
それ$counter
なしで定義した場合static
、毎回エコーされる値は$num
、関数に渡されるパラメーターと同じになります。を使用static
すると、追加の回避策なしでこの単純なカウンターを構築できます。
静的変数は、ローカル関数スコープにのみ存在します。定義されている関数の外部からアクセスすることはできません。したがって、その関数を次に呼び出すまで、値を変更しないでおくことができます。
静的変数は、スカラーまたはスカラー式としてのみ定義できます(PHP 5.6以降)。それに他の値を割り当てると、少なくともこの記事が書かれた時点では必然的に失敗につながります。それでも、コードの次の行でこれを行うことができます。
function countSheep($num) {
static $counter = 0;
$counter += sqrt($num);//imagine we need to take root of our sheep each time
echo "$counter sheep jumped over fence";
}
結果:
2 sheep jumped over fence
5 sheep jumped over fence
9 sheep jumped over fence
静的関数は、同じクラスのオブジェクトのメソッド間で「共有」されています。次の例を見ると簡単に理解できます。
class SomeClass {
public function foo() {
static $x = 0;
echo ++$x;
}
}
$object1 = new SomeClass;
$object2 = new SomeClass;
$object1->foo(); // 1
$object2->foo(); // 2 oops, $object2 uses the same static $x as $object1
$object1->foo(); // 3 now $object1 increments $x
$object2->foo(); // 4 and now his twin brother
これは、同じクラスのオブジェクトでのみ機能します。オブジェクトが異なるクラスからのものである場合(互いに拡張している場合でも)、静的変数の動作は期待どおりになります。
関数呼び出し間で値を保持する別の方法は、クロージャを使用することです。クロージャーはPHP5.3で導入されました。つまり、関数スコープ内の変数のセットへのアクセスを、それらにアクセスする唯一の方法となる別の無名関数に制限することができます。クロージャ変数に含まれていると、構造化プログラミングの「クラス定数」(値によってクロージャに渡された場合)や「プライベートプロパティ」(参照によって渡された場合)などのOOP概念を(多かれ少なかれうまく)模倣できます。
後者では、実際には静的変数の代わりにクロージャを使用できます。何を使用するかは常に開発者が決定しますが、静的変数は再帰を処理するときに間違いなく役立ち、開発者が気付くに値することに注意してください。
既存のものとPHPマニュアルはこれのほとんどを説明するのに素晴らしい仕事をしているので、私は質問に対する完全な答えを投稿しません。
しかし逃した一人の被験者は、であったスーパーグローバルなど、一般に使用される$_POST
、$_GET
、$_SESSION
、等が挙げられる。これらの変数はせずに、任意の範囲で、常に利用可能である配列でglobal
宣言。
たとえば、この関数は、PHPスクリプトを実行しているユーザーの名前を出力します。変数は問題なく関数で使用できます。
<?php
function test() {
echo $_ENV["user"];
}
「グローバルは悪い」という一般的なルールは、誤用しない限り、通常、PHPでは「グローバルは悪いがスーパーグローバルは大丈夫」に修正されています。(これらの変数はすべて書き込み可能であるため、本当にひどい場合は、依存性の注入を回避するために使用できます。)
これらの変数が存在することは保証されていません。管理者は、使用してそれらの一部またはすべてを無効にすることができvariables_order
ディレクティブではphp.ini
、これは一般的な動作ではありません。
現在のスーパーグローバルのリスト:
$GLOBALS
-現在のスクリプトのすべてのグローバル変数$_SERVER
-サーバーと実行環境に関する情報$_GET
-リクエストに使用されたHTTPメソッドに関係なく、URLのクエリ文字列で渡される値$_POST
-application/x-www-form-urlencoded
またはmultipart/form-data
MIMEタイプを使用してHTTPPOSTリクエストで渡される値$_FILES
multipart/form-data
-MIMEタイプのHTTPPOSTリクエストで渡されたファイル$_COOKIE
-現在のリクエストで渡されたCookie$_SESSION
-PHPによって内部的に保存されたセッション変数$_REQUEST
-の典型的組み合わせ$_GET
と$_POST
、時には$_COOKIES
。内容は、のrequest_order
ディレクティブによって決定されphp.ini
ます。$_ENV
-現在のスクリプトの環境変数特徴的なスターのコリン・エッグレスフィールドは、RomaDrama Liveでのスリル満点のファンとの出会いについて料理しました!加えて、大会での彼のINSPIREプログラム。
ノーザンエクスポージャーが90年代の最も人気のある番組の1つになった理由を確認するには、Blu-rayまたはDVDプレーヤーをほこりで払う必要があります。
ドミニカのボイリング湖は、世界で2番目に大きいボイリング湖です。そこにたどり着くまでのトレッキングは大変で長いですが、努力する価値は十分にあります。
サンディエゴコミックコンは今週開幕し、オタクのアナウンス、ポスター、予告編、お気に入りの番組や映画のからかいでいっぱいになります。SDCCは、コンベンションフロア全体の多くのパネルで行われているため、すべてに対応するのは難しい場合があります。
小さなアプリ開発者は金曜日に発表された法的な和解でグーグルから9千万ドルをこじ開けた。アップルとの同様の合意に続いて熱くなった。金曜日のブログ投稿で、Googleは、Androidメーカーが市場での優位性を悪用してPlayストア経由でのアプリ内購入に対して30%の料金を不当に請求したと主張するアプリ開発者との訴訟を解決するために、9千万ドルを支払うことに合意したと述べました。
今週、RadioShackのTwitterアカウントは、奇妙なものから完全にひどいものになりました。短い順序で、会社のフィード全体が、バイブレーター、「ビッグティット」(スペルミス)、有名人やその他の企業アカウントを荒らしているツイートなど、NSFW素材の真の山になりました。
大型ハドロン衝突型加速器のトンネル内にあるコンパクトミュオンソレノイド(CMS)検出器。2012年7月4日、CERNの科学者たちは、1960年代に最初に提案された素粒子であるヒッグス粒子の観測を確認しました。
Zendaya shared a sweet photo in honor of boyfriend Tom Holland's 26th birthday Wednesday
シーレン「Ms.JuicyBaby」ピアソンは、先月脳卒中で入院した後、「もう一度たくさんのことをする方法を学ばなければならない」ため、言語療法を受けていることを明らかにしました。
オスカー受賞者の世紀半ばの家には、3つのベッドルーム、2つのバス、オーシャンフロントの景色があります。
1.ドラマを見た後、起業する考えはありますか?あなたのビジネスはボトルネックに遭遇しましたか?方向性がなくてわからない場合は、ドラマを追いかけて行くことを心からお勧めします。(?)ブラフではなく、最も完璧なビジネス例を隠すドラマがあります。2.ブレイキング・バッドとその弁護士ドラマ「ブレイキング・バッド」を見た友人たちは、演劇の中で、穏やかな表情で、弁護士のソウル・グッドマンに深く感銘を受けなければなりません。口を開けて、感覚の弱い傭兵の性格を持っています。道徳の面で、サル・グッドマンは無意識のうちに劇に欠かせない役割を果たし、彼自身のシリーズ「絶望的な弁護士」(ベター・コール・ソール)を生み出しました。ウェントウのテキストとビデオは、劇中のソウル・グッドマンのテレビコマーシャルです。製品(サービス)、競争戦略、市場ポジショニング、ブランド名、ターゲット顧客グループ、コミュニケーション軸から広告まで、サル・グッドマンの役割のビジネス設定は、「最低」と見なすことができる超超超超超超完全です。ブランドコミュニケーションのコスト」「変化」のモデル。なぜ?私の分析をご覧ください。3.ソウル・グッドマンの「事業戦略」1.基本情報ブランド名:Saul Goodman製品:法律相談サービス対象顧客:麻薬中毒、飲酒運転、事故など。法律知識の欠如は、一般的に公立弁護士にしか余裕がなく、真面目な弁護士も「特別な法律を持つ消費者」を避けます。恐れてはいけない「ニーズ」。コミュニケーションの主軸:この国のすべての男性、女性、子供は有罪判決を受けるまで無実だと思います。地域:アルバカーキ市スローガン:Thrallに電話したほうがいいです!(ベター・コール・ソール)広告:2つの可能性のある犯罪状況をシミュレートします+サウルの主張+サウルのスローガン2をより適切に呼び出します。