[解決済み] 関数内のPHPグローバル
質問
の効用は何でしょうか? グローバルキーワード ?
ある方法と別の方法を好む理由はありますか?
- セキュリティ?
- パフォーマンス?
- その他は?
方法1:
function exempleConcat($str1, $str2)
{
return $str1.$str2;
}
方法2
function exempleConcat()
{
global $str1, $str2;
return $str1.$str2;
}
どのような場合に
global
?
私の場合、それは は危険に見える ... でも、それは単なる知識不足かもしれません。 私が興味を持ったのは 文書化された (例:コードの例、ドキュメントへのリンク...) 技術的な理由に興味があります。
事前にありがとうございます!
懸賞金
これはこのトピックに関する素晴らしい一般的な質問です。私 (@Gordon) は追加の回答を得るために懸賞金を提供します。あなたの回答が私の回答と一致するか、あるいは異なる視点を提供するかは重要ではありません。というのも
global
のトピックは時々出てくるので、私たちはリンクするために良い "canonical"の答えを使うことができます。
どのように解決するのですか?
グローバルは悪である
これは
global
キーワードだけでなく、ローカルスコープからグローバルスコープに到達する他のすべてのもの(静的、シングルトン、レジストリ、定数)にも当てはまります。これらは使いたくないものです。関数呼び出しは、外部の何かに依存する必要はありません。
function fn()
{
global $foo; // never ever use that
$a = SOME_CONSTANT // do not use that
$b = Foo::SOME_CONSTANT; // do not use that unless self::
$c = $GLOBALS['foo']; // incl. any other superglobal ($_GET, …)
$d = Foo::bar(); // any static call, incl. Singletons and Registries
}
これらのすべては、あなたのコードを外部に依存させることになります。つまり、これらのどれかを確実に呼び出す前に、あなたのアプリケーションが置かれている完全なグローバル状態を知っていなければなりません。関数はその環境なしには存在できません。
スーパーグローバルを使うことは明らかな欠点ではないかもしれませんが、もしあなたがコードをコマンドラインから呼び出すなら、あなたは
$_GET
または
$_POST
. もしあなたのコードがこれらからの入力に依存しているのなら、あなたはWeb環境に制限されています。リクエストをオブジェクトに抽象化して、それを代わりに使えばいいのです。
ハードコードされたクラス名(静的、定数)の結合の場合、あなたの関数もそのクラスが利用可能でなければ存在することができません。同じ名前空間からのクラスであれば問題は少ないですが、異なる名前空間からの混合を開始すると、もつれた混乱を作成することになります。
再利用は上記のすべてによってひどく妨げられています。 ユニットテストもそうです .
また、グローバルスコープにカップリングする際、関数のシグネチャが嘘のようになっています。
function fn()
は嘘つきです。なぜなら、何も渡さずにその関数を呼び出すことができると主張しているからです。関数本体を見たときに初めて、環境を特定の状態に設定しなければならないことを知りました。
もし関数が実行するために引数を必要とするならば、それを明示的にして渡すようにしましょう。
function fn($arg1, $arg2)
{
// do sth with $arguments
}
は、呼び出されるために必要なことを署名から明確に伝えています。特定の状態であることを環境に依存しない。をする必要はありません。
$arg1 = 'foo';
$arg2 = 'bar';
fn();
pull in (グローバルキーワード) vs push in (引数)の問題です。依存関係をプッシュ・イン/インジェクションすると、その関数はもう外部に依存しなくなります。あなたが
fn(1)
を実行するとき、外部のどこかで1を保持する変数を持つ必要はない。しかし、グローバルに引き込むと
$one
を関数内に引き込むと、グローバルスコープに結合し、どこかでその変数が定義されていることを期待することになります。この場合、関数はもはや独立したものではありません。
さらに悪いことに、関数内部でグローバルを変更していると、関数があちこちに副作用を及ぼすため、コードがすぐに完全に理解不能になります。
より良い例がないため、次のように考えてみましょう。
function fn()
{
global $foo;
echo $foo; // side effect: echo'ing
$foo = 'bar'; // side effect: changing
}
そして、あなたは
$foo = 'foo';
fn(); // prints foo
fn(); // prints bar <-- WTF!!
を見る方法はありません。
$foo
が変更されたことを確認する方法はありません。なぜ同じ関数を同じ引数で呼び出すと、突然出力が変わったり、グローバルな状態の値が変わったりするのでしょうか?関数は定義された入力 Y に対して X を実行する必要があります。
なぜなら、OOPはカプセル化についてであり、グローバルスコープに手を伸ばせば、カプセル化を破ることになるからです。フレームワークで見られるこれらのシングルトンやレジストリはすべて、依存性注入を優先して削除されるべきコード臭です。コードをデカップリングしましょう。
その他のリソース
関連
-
[解決済み】XAMPPポート80をPID 4の「Unable to open process」が使用中 [重複] XAMPPポート80をPID 4の「Unable to open process」が使用中。]
-
[解決済み】Apache + PHPで「ヘッダの前にスクリプトの出力が終了する」件
-
[解決済み] libapache2-mod-php7 パッケージの場所がわからない
-
[解決済み] PHPで配列から要素を削除する
-
[解決済み] PHPでSQLインジェクションを防ぐにはどうしたらいいですか?
-
[解決済み] PHPでHTML/XMLをパースして処理する方法とは?
-
[解決済み] PHPのエラーを表示させるにはどうしたらいいですか?
-
[解決済み] PHPのstartWith()関数とendsWith()関数
-
[解決済み】PHPの'foreach'は実際どのように動作するのですか?
-
[解決済み] リファレンス - このシンボルは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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Weird PHP error: 'Can't use function return value in write context'.
-
[解決済み】move_uploaded_fileは、「failed to open stream: Permission denied" というエラーが出る
-
[解決済み] 整形されていない数値が発生しました。
-
[解決済み】空の配列要素を削除する
-
[解決済み] SAJAXは死んだか?何を置き換えるべきか?
-
[解決済み】未定義のメソッド mysqli_stmt::get_result を呼び出す。
-
[解決済み】mysqli_select_db()は、パラメータ1がmysqliであることを期待し、文字列が与えられる。
-
[解決済み】既に開始されているPHPセッション【重複あり
-
[解決済み] オートロードとは何ですか; spl_autoload、__autoload、spl_autoload_register はどのように使うのですか?
-
[解決済み] mysql_field_nameを新しいmysqliに変更します。