function foo () {
global $var;
// rest of code
}
私の小さなPHPプロジェクトでは、通常、手続き型の方法を使用します。私は通常、システム構成を含む変数を持っており、関数でこの変数にアクセスする必要がある場合は、そうしますglobal $var;
。
これは悪い習慣ですか?
function foo () {
global $var;
// rest of code
}
私の小さなPHPプロジェクトでは、通常、手続き型の方法を使用します。私は通常、システム構成を含む変数を持っており、関数でこの変数にアクセスする必要がある場合は、そうしますglobal $var;
。
これは悪い習慣ですか?
回答:
人々が他の言語でグローバル変数について話すとき、それはPHPで行うこととは異なる何かを意味します。これは、PHPでは変数が実際にはグローバルではないためです。典型的なPHPプログラムのスコープは、1つのHTTPリクエストです。セッション変数は、通常、多くのHTTPリクエストを含むため、実際にはPHPの「グローバル」変数よりも広い範囲を持っています。
多くの場合(常に?)、次のようpreg_replace_callback()
なメソッドでメンバー関数を呼び出すことができます。
preg_replace_callback('!pattern!', array($obj, 'method'), $str);
詳細については、コールバックを参照してください。
重要なのは、オブジェクトがPHPにボルトで固定されており、ある意味で厄介なことにつながるということです。
さまざまな言語の標準や構成をPHPに適用することについて過度に心配する必要はありません。もう1つのよくある落とし穴は、オブジェクトモデルをすべての上に貼り付けることによって、PHPを純粋なOOP言語に変えようとすることです。
他のものと同様に、「グローバル」変数、手続き型コード、特定のフレームワーク、およびOOPを使用します。これは、理にかなっており、問題を解決し、作成する必要のあるコードの量を減らし、保守しやすく、理解しやすくするためです。あなたがすべき。
array ($obj, 'callbackMethod')
呼び出しでフォームのコールバックを使用できませんpreg_replace_callback()
か?(私はこのOOPの落とし穴の餌食になりました...)
グローバル変数を注意深く使用しないと、問題を見つけるのが難しくなる可能性があります。phpスクリプトをリクエストし、一部の関数に存在しない配列のインデックスにアクセスしようとしているという警告が表示されたとします。
アクセスしようとしている配列が関数に対してローカルである場合は、関数をチェックして、そこで間違いがないかどうかを確認します。関数への入力に問題がある可能性があるため、関数が呼び出される場所を確認してください。
ただし、その配列がグローバルである場合は、そのグローバル変数を使用するすべての場所を確認する必要があります。それだけでなく、グローバル変数への参照にアクセスする順序を把握する必要があります。
コードの一部にグローバル変数がある場合、そのコードの機能を分離することは困難です。なぜ機能を分離したいのですか?したがって、テストして他の場所で再利用できます。テストする必要がなく、再利用する必要もないコードがある場合は、グローバル変数を使用しても問題ありません。
私はクレタスに同意します。私は2つのことを追加します:
よろしく、ドン
$DB = 'foo';
経験、大学の学位、ソフトウェアエンジニアリングに反対する人は誰ですか?私じゃない。オブジェクト指向のシングルページPHPアプリケーションを開発する場合、名前空間の衝突を心配せずにすべてを最初から作成できることがわかっていると、もっと楽しくなります。ゼロから構築することは、多くの人がもうやらないことです。彼らには、気になる仕事、締め切り、ボーナス、または評判があります。これらのタイプは、非常に多くの事前に作成されたコードを使用する傾向があるため、グローバル変数を使用するリスクはまったくありません。
プログラムのグローバル領域でのみ使用されている場合でも、グローバル変数を使用するのは悪いことかもしれませんが、ただ楽しんで何かを機能させたいだけの人を忘れないでください。
それがグローバル名前空間でいくつかの変数(<10)を使用することを意味する場合、それはプログラムのグローバル領域でのみ使用されます。はい、はい、MVC、依存性注入、外部コード、何とか、何とか、何とか、何とか。ただし、コードの99.99%を名前空間とクラスに含め、外部コードがサンドボックス化されている場合、グローバル変数を使用すると、世界は終了しません(繰り返しますが、世界は終了しません)。
一般的に、グローバル変数を使用することは悪い習慣だとは言いません。プログラムのグローバル領域外でグローバル変数(フラグなど)を使用することは、問題を引き起こし、(長期的には)状態を簡単に追跡できなくなる可能性があるため、お勧めできません。また、学習すればするほど、グローバル変数への依存度が低くなります。これは、グローバル変数の使用に関連するバグを追跡する「喜び」を体験できるためです。これだけで、同じ問題を解決する別の方法を見つけるように促されます。偶然にも、これはPHPの人々を名前空間とクラス(静的メンバーなど)の使用方法を学ぶ方向に押しやる傾向があります。
コンピュータサイエンスの分野は広大です。悪いラベルを付けたためにみんなを怖がらせて何かをするのをやめさせると、ラベルの背後にある理由を真に理解する楽しみを失います。
必要に応じてグローバル変数を使用しますが、グローバル変数がなくても問題を解決できるかどうかを確認します。衝突、テスト、およびデバッグは、問題の説明だけでなく、問題の本質を深く理解している場合に意味があります。
終了したSOドキュメンテーションベータから再投稿
この問題は、次の擬似コードで説明できます。
function foo() {
global $bob;
$bob->doSomething();
}
ここでの最初の質問は明らかです
どこ
$bob
から来たの?
混乱していますか?良い。グローバルが混乱し、悪い習慣と見なされている理由を学びました。これが実際のプログラムである場合、次の楽しみは、のすべてのインスタンスを追跡し$bob
、適切なインスタンスを見つけることを期待することです(これは、$bob
どこでも使用すると悪化します)。さらに悪いことに、誰かが行って定義した場合$bob
(またはその変数を忘れて再利用した場合)、コードが破損する可能性があります(上記のコード例では、オブジェクトが間違っているか、オブジェクトがまったくない場合、致命的なエラーが発生します)。事実上すべてのPHPプログラムがinclude('file.php');
あなたの仕事のようなコードを利用するので、このようなコードを維持することはあなたがより多くのファイルを追加するほど指数関数的に難しくなります。
グローバルを回避するにはどうすればよいですか?
グローバルを回避する最良の方法は、依存性注入と呼ばれる哲学です。ここで、必要なツールを関数またはクラスに渡します。
function foo(\Bar $bob) {
$bob->doSomething();
}
これは、理解と保守がはるかに簡単です。$bob
発信者はそれを知る責任があるので、どこに設定されたかを推測することはできません(それは私たちが知る必要があることを私たちに渡します)。さらに良いことに、型宣言を使用して、渡されるものを制限できます。つまり、それ$bob
がBar
クラスのインスタンスであるか、の子のインスタンスであるBar
ことがわかります。つまり、そのクラスのメソッドを使用できることがわかります。標準のオートローダー(PHP 5.3以降で使用可能)と組み合わせると、Bar
定義されている場所を追跡できるようになります。PHP 7.0以降には、拡張型宣言が含まれており、スカラー型(int
またはなどstring
)を使用することもできます。
$bob = Bar::instance();
すれば、必要なときにいつでもできます。
なので:
global $my_global;
$my_global = 'Transport me between functions';
Equals $GLOBALS['my_global']
悪い習慣です(Wordpressのように$pagenow
)...うーん
これを考慮してください:
$my-global = 'Transport me between functions';
PHPエラーですが:
$GLOBALS['my-global'] = 'Transport me between functions';
エラーではありません。ハイフンは、のような「一般的な」ユーザー宣言変数と衝突しません$pagenow
。また、大文字を使用すると、スーパーグローバルが使用されていること、コードで簡単に見つけられること、ファイル内で検索して追跡できることを示します
次のように、単一のソリューションのすべてのクラスを構築するのが面倒な場合は、ハイフンを使用します。
$GLOBALS['PREFIX-MY-GLOBAL'] = 'Transport me ... ';
しかし、より広い使用のケースでは、私が使っONE配列としてグローバルを:
$GLOBALS['PREFIX-MY-GLOBAL']['context-something'] = 'Transport me ... ';
$GLOBALS['PREFIX-MY-GLOBAL']['context-something-else']['numbers'][] = 'Transport me ... ';
後者は私にとって、データを「キャッシュ」するために毎回シングルトンクラスで乱雑にするのではなく、「コーラライト」の目的または使用に関するグッドプラクティスです。私が間違っているか、ここで愚かな何かを見逃している場合はコメントしてください...