ホームページ  >  に質問  >  本文

参考:変数スコープとは何ですか、どこからどの変数にアクセスできるのか、「未定義変数」エラーとは何ですか?


注: これは、PHP の変数スコープを扱う参考質問です。このパターンに当てはまる多くの質問を、この質問と重複するものとして閉じてください。

PHP の「変数スコープ」とは何ですか?ある .php ファイル内の変数に別の .php ファイルからアクセスできますか? 「未定義の変数」 エラーが時々表示されるのはなぜですか?

P粉023650014P粉023650014389日前599

全員に返信(2)返信します

  • P粉311563823

    P粉3115638232023-10-20 10:03:09

    関数スコープ内で定義された変数には外部からアクセスできませんが、関数の完了後にその値を使用できないわけではありません。 PHP には、オブジェクト指向 PHP で静的メソッドとプロパティを定義するために広く使用されているよく知られた static キーワードがありますが、static は関数内でも使用できることを覚えておく必要があります。静的変数を定義します。

    「静的変数」とは何ですか?

    静的変数は、関数スコープで定義された通常の変数とは異なり、プログラムの実行がスコープを離れても、静的変数の値は失われません。静的変数を使用した次の例を考えてみましょう:

    リーリー ###結果:### リーリー

    static

    を使用せずに $counter を定義すると、毎回エコーされる値は、関数に渡される $num パラメーターと同じになります。この単純なカウンターは、追加の回避策なしで static を使用して構築できます。

    静的変数の使用例

    後続の関数呼び出しの間に値を保存します。
    1. 方法がない場合(または方法がない場合)、再帰呼び出しの間に値を保存する 目的) それらをパラメータとして渡します。
    2. キャッシュは通常、値を 1 回取得することによって実行するのが最適です。のために たとえば、サーバー上の不変ファイルを読み取った結果などです。
    3. ######スキル######
    4. 静的変数はローカル関数スコープ内にのみ存在します。それはありえない 定義されている関数の外部でアクセスされます。だからあなたはできる 次の呼び出しまでその値が保持されることを確認してください この機能。

    静的変数はスカラーまたはスカラーとしてのみ定義できます 式 (PHP 5.6 以降)。必然的に他の値を割り当てます 少なくともこの記事を書いている時点では、これは失敗に終わります。 ただし、コードの次の行でこれを行うことができます: リーリー ###結果:### リーリー 静的関数はオブジェクトのメソッド間である程度「共有」されます。 クラスメート。次の例を見ると理解しやすいです:

    リーリー

    これは、同じクラスのオブジェクトにのみ適用されます。静的変数は、オブジェクトが異なるクラスに属している場合 (または相互に拡張している場合)、期待どおりに動作します。

    静的変数は関数呼び出し間で値を保持する唯一の方法ですか?

    関数呼び出し間で値を保持するもう 1 つの方法は、クロージャを使用することです。クロージャは PHP 5.3 で導入されました。つまり、関数のスコープ内の特定の変数セットへのアクセスを、それらにアクセスする唯一の方法である別の匿名関数に制限することができます。クロージャ変数内にあると、構造化プログラミングの「クラス定数」(クロージャ内で値によって渡される場合) や「プライベート プロパティ」(参照によって渡される場合) などの OOP 概念を (多かれ少なかれうまく) エミュレートできます。

    後者では、実際には静的変数の代わりにクロージャを使用できます。何を使用するかを決定するのは常に開発者次第ですが、静的変数は再帰を使用するときに間違いなく便利であり、開発者の注意を払う価値があることに注意してください。

    返事
    0
  • P粉895187266

    P粉8951872662023-10-20 09:03:53

    「変数スコープ」とは何ですか?

    変数の「範囲」または「アクセスできる場所」は制限されています。 $foo = 'bar'; をアプリケーションの どこかに一度書いたからといって、 foo >他の場所## から $ を参照できるわけではありません。 # アプリケーション内で。変数 $foo には特定のスコープがあり、そのスコープ内で有効であり、同じスコープ内のコードのみが変数にアクセスできます。 PHP でスコープを定義するにはどうすればよいですか?

    非常に単純です: PHP には

    関数スコープ

    があります。これは、PHP に存在する唯一の範囲区切り文字です。関数内の変数は、その関数内でのみ使用できます。関数の外側の変数は関数の外側のどこでも使用できますが、関数の内部では使用できません。これは、PHP には特別なスコープ (global スコープ) があることを意味します。関数の外で宣言された変数はすべて、このグローバル スコープ内にあります。 ###例:### リーリー

    $foo

    は myFunc の

    global

    スコープ内にあり、$baz は myFunc の local スコープ内にあります。 myFunc 内のコードのみが $baz にアクセスできます。 myFunc の外部のコードのみが $foo にアクセスできます。どちらの当事者も他方にアクセスできません: リーリー スコープと含まれるファイル ファイル境界分離されていません 範囲:

    a.php

    リーリー

    b.php

    リーリー

    include

    コードに適用されるルールは、他のコードに適用されるルールと同じです。 関数 のみに別個のスコープが適用されます。範囲を広げるために、コードをコピーして貼り付ける次のようなファイルを含めることを検討してください:

    c.php リーリー 上記の例では、

    a.php

    myFunc 内に含まれており、

    a.php

    内の変数はローカル関数スコープのみを持ちます。 a.php 内のグローバル スコープ内にあるように見えるからといって、必ずしも実際にそうであるとは限りません。実際には、コードが含まれる/実行されるコンテキストによって異なります。 関数やクラス内の関数についてはどうすればよいでしょうか? 新しい function 宣言ごとに、新しいスコープが導入されます。これは非常に簡単です。

    (匿名)関数内の関数

    リーリー ###コース### リーリー

    スコープの用途は何ですか?

    スコープの問題に対処するのは面倒に思えるかもしれませんが、 変数のスコープを制限することは、複雑なアプリケーションを作成する上で非常に重要です。

    宣言したすべての変数がアプリケーション内の他の場所から利用できる場合、何が変更されたのかを追跡する実際の方法がないまま、変数のすべてをステップ実行することになります。変数に付けられる適切な名前には制限があるため、変数 "

    $name

    " を複数の場所で使用することが必要な場合があります。この一意の変数名をアプリケーション内で 1 回しか使用できない場合は、変数が一意であることを確認し、間違ったコード部分から間違った変数を変更しないようにするために、非常に複雑な命名スキームを採用する必要があります。

    ###観察する:### リーリー

    スコープがない場合、上記の関数は何をするのでしょうか?

    $bar

    それはどこから来たのですか?それはどのようなステータスを持っていますか?初期化でもされているのでしょうか?毎回確認する必要がありますか?これは保守不可能です。これにより...

    範囲の境界を越える

    正しい方法: 変数の受け渡しと変数の受け渡し

    リーリー

    変数$barは、この範囲を関数パラメータとして明示的に入力します。この関数を見るだけで、使用する値がどこから来たのかは明らかです。次に、明示的に 値を返します。呼び出し元は、関数がどの変数を使用するか、その戻り値がどこから来るかを知っているという自信を持っています。 リーリー 変数のスコープを匿名関数に拡張する

    リーリー

    匿名関数は、周囲のスコープに

    $foo

    を明示的に組み込みます。これは global スコープとは異なることに注意してください。 間違った方法:

    グローバル

    前述したように、グローバル スコープはやや特殊であり、関数はそこから変数を明示的にインポートできます。 リーリー

    この関数は、グローバル変数

    $foo

    を使用および変更します。 ###こんなことしないで!

    (自分が何をしているのか本当に本当に理解している場合を除き、たとえそうであったとしても、それはやめてください!) この関数の呼び出し元に表示される内容は次のとおりです: リーリー この関数に

    副作用があるという兆候はありません

    が、副作用はあります。一部の関数は常に

    を変更し、

    に何らかのグローバル状態を必要とするため、これは簡単に混乱を招く可能性があります。関数を ステートレスにして、何度呼び出しても、入力に対してのみ動作し、定義された出力を返すようにする必要があります。 可能であれば、いかなる方法でもグローバル スコープの使用を避けるべきです。最も確実なのは、変数をグローバル スコープからローカル スコープに「プル」しないことです。

    返事
    0
  • キャンセル返事