$ Globalsの操作によって引き起こされるグローバルな状態のカオスのデバッグ
$ Globalsの操作は、PHPで予測不可能なバグを引き起こす可能性があります。それをデバッグして解決するために、1。$ Globalsがすべての変数へのグローバルなアクセスを提供し、状態の変更を追跡するのが難しくなることを理解してください。 2.戦略的なデバッグロギングとGlobalsWatcherクラスを使用して、変更をスナップショットおよび報告して、不要な変更を検出します。 3. Xdebugを使用してソースをトレースし、debug_backtrace()を使用してスタックトレースを使用し、$ Globals割り当てのコードベースを検索します。 4. App :: set()/get()などの制御されたサービスコンテナを使用して、依存関係への噴射に依存することにより、将来の問題を防ぎ、PHPSTANまたはPHP_CodesNifferを介してコーディング標準を実施して、直接$ Globalsアクセスをブロックし、最終的には厳格な制御を必要とする危険で有用なツールのように$ Globalsを扱います。
PHPのグローバル変数、特にSuperGlobal $GLOBALS
、関数やファイル間でデータを共有する便利な方法です。しかし、悪用されると、特にグローバルな状態が制御されていない操作のために予測不可能になったとき、彼らはデバッグの悪夢を導入します。神秘的なバグ、一貫性のない行動、または追跡が困難な副作用を扱っている場合、 $GLOBALS
改ざんが犯人かもしれません。

$GLOBALS
操作に起因するカオスをデバッグして解決する方法は次のとおりです。
1。 $GLOBALS
何をするかを理解します
$GLOBALS
、グローバル範囲で現在定義されているすべての変数への参照を含むPHP SuperGlobalです。変数名(文字列として)でインデックスが付けられているため、 $GLOBALS['foo']
グローバル変数$foo
を指します。

$ foo = 'hello'; echo $ globals ['foo']; //出力:こんにちは
危険は、コードの一部(ファイル、サードパーティライブラリを含む機能)のいずれかが、 $GLOBALS
から読み取りまたは書き込み、明確な可視性なしにグローバルな状態を変更する可能性があるためです。
2。不要な変更を検出します
$GLOBALS
常にアクセス可能であるため、変更されている場所を追跡するには、意図的な検査が必要です。

デバッグロギングを戦略的に使用します
キーポイントにロギングを挿入して、変更を監視します。
関数debug_globals($ label){ error_log( "===グローバルスナップショット:$ label ==="); foreach(['fality_var'、 'config'、 'user'] as $ key){//特定のキーを見る if(ISSET($ globals [$ key])){ error_log( "$ key ="。json_encode($ globals [$ key])); } } } //疑わしいエリアの前後に配置します debug_globals( 'function call'前 '); some_risky_function(); debug_globals( 'function call');
これにより、予期しない変更がいつどこで発生するかを特定するのに役立ちます。
グローバルステートウォッチャー(Advanced)をセットアップする
開発中にカスタムハンドラーを使用してアクセスをラップできます。
クラスGlobalSwatcher { プライベート静的$スナップショット。 public static関数はnapshot(){ self :: $ snapshot = array_keys($ globals); } public static function diffaNdReport(){ $ current = array_keys($ globals); $ addid = array_diff($ current、self :: $ snapshot); $ remaved = array_diff(self :: $ snapshot、$ current); if(!empty($ red)){ error_log( "新しいグローバルが追加されました:"。prode( '、'、$ add)); } if(!empty($ remaved)){ error_log( "globals removed:"。prode( '、'、$ remaved)); } //また、既知のグローバルの価値の変化を確認してください foreach(['$ config'、 '$ user'] as $ var){ $ name = ltrim($ var、 '$'); if(isset(self :: $ snapshot [$ name])&& isset($ globals [$ name])){ if(self :: $ snapshot [$ name]!== globals [$ name]){ error_log( "グローバル変数\ $$名が変更されました!"); } } } self :: $ snapshot = $ current; } } // 使用法 GlobalsWatcher :: TakeNapShot(); // ...コードを実行します GlobalSwatcher :: diffandreport();
これを重要なセクションの周りで実行して、突然変異をキャッチします。
3.変更のソースをトレースします
ログがあっても、グローバルが変更された場所を正確に特定するのは難しい場合があります。
ステップバイステップ検査にはXdebugを使用します
IDEでXDEBUGと設定ブレークポイントを有効にします。それから:
- 疑わしいファイル/ラインに条件付きブレークポイントを設定します。
- または、ログコール内で
debug_zval_dump()
またはvar_dump(debug_backtrace())
を使用して、グローバルが変更されたときにスタックトレースをキャプチャします。
例:
if(Isset($ globals ['user'])&& $ globals ['user'] ['status']!== 'Active'){ error_log( 'ユーザーステータスが変更されました!'); error_log(print_r(debug_backtrace(false)、true)); }
これにより、突然変異につながるコールスタックが明らかになります。
コードベースを検索して、 $GLOBALS
に書き込みをします
コマンドラインツールを使用して、危険なパターンを見つけます。
grep -r "\ $ globals \ ['"/path/to/project grep -r '\ $ globals \ ['/path/to/project | grep -v 'read_only'
探す:
- 直接割り当て:
$GLOBALS['x'] = ...
- 意図しない作成:
$GLOBALS['configg']
のようなタイプミス - ループまたは条件内の変更
含まれる、オートローダー、ミドルウェア、またはレガシーコードを含むことに特に注意してください。
4.将来の混乱を防ぎます
問題をデバッグしたら、グローバル国家への依存を減らします。
依存関係注射に向けてリファクタリングします
$GLOBALS['config']
にアクセスする代わりに、依存関係を明示的に合格します。
function processuser($ config、$ user){ // $ globals ['config']の代わりにここで$ configを使用します }
これにより、動作は予測可能でテスト可能になります。
構成コンテナまたはサービスロケーターを使用します(Globalsが避けられない場合)
あなたがグローバルに状態を共有する必要がある場合、それをカプセル化します:
クラスアプリ{ private static $ services = []; public static関数セット($ key、$ value){ self :: $ services [$ key] = $ value; } public static function get($ key){ self :: $ services [$ key] ??ヌル; } } //制御アクセス app :: set( 'config'、$ config); $ config = app :: get( 'config');
これでset()
にロギングまたは検証を追加できます。
コーディング標準を介して直接$GLOBALS
アクセスを無効にします
php_codesnifferやphpstanなどのツールを使用してルールを強制します。
-
$GLOBALS
使用にフラグを立てるスニフを作成します。 - または、
$GLOBALS\['
を含むコミットをブロックするために、コミット前のフックでRegexを使用します。
例phpstanルール( phpstan.neon
で):
パラメーター: 無視する: - '#Access to Global変数\ $ Globals#'
より良い:無視しないでください - 検出して排除します。
結論
$GLOBALS
はフットガンです。クイックハッキングを可能にしますが、状態の変更が見えない、または散らばっている場合、地獄のデバッグにつながります。コントロールを取り戻すには:
- キーポイントでグローバル状態を記録してスナップショットします。
- バックトレースと検索ツールを使用したトレース変更。
- 明示的な依存関係に向けてリファクタリングします。
- 静的分析による回帰を防ぎます。
制御されていない$GLOBALS
使用を排除すると、アプリはより保守性が高く、テスト可能であり、正気になります。
基本的に、火のような$GLOBALS
を扱います。制御された状態で役立ち、チェックされていない場合は危険です。
以上が$ Globalsの操作によって引き起こされるグローバルな状態のカオスのデバッグの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undress AI Tool
脱衣画像を無料で

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

DependencyInjection(di)$ globalShidesthem.2.diimprovestestabilityの依存性による依存性の依存性の$ globalshidesthem.2.dieasyManipulatingglobalState.3.ductupeStightcouplingbydecoupなどの依存性を維持することで、依存性$ globals becaudeItmakesdependenciesexplicitの発行中心

$ globalSallowsunintendedvariablewritingのチェックされていない、aTmingStrationCriticalDatalidSoridSorolosErolosErowSOROUTS Validation;

$ GlobalsとGlobalはどちらも関数のグローバル変数にアクセスするために使用されますが、重要な違いがあります。1。$ Globalsは、$ Globals ['var']などのキー名を介して変数にアクセスするハイパーグローバルアレイです。 2. $ Globalsは事前宣言を必要とせず、直接使用することができます。グローバルは最初に宣言し、次に使用する必要があります。 3. $ Globalsは、$ Globals [$ varname]などの動的アクセスをサポートし、Globalは動的宣言をサポートしていません。 4.Unset($ Globals ['var'])はグローバル変数自体を削除しますが、Unset($ var)はグローバル$ vです

$ globalsmanipulationcancusuasusunpredicablebugsinphp; todebugandresolveit、1。$ globalsprovidesglobalacesstoallvariables、makestatechangeshardtotrack;

$ globalscreateShidDedendenciesを使用して、functionshardertotetest、壊れやすい、andunReusableを使用します

$ globalsMayBeAcceptableGACYSYSTEMSLIKEWORDPRESSPRUGINSWHEREITENSURESCOMPATIBILITYを使用する$を使用してください

ModernPhpframeworkslikelavalavelandsymfonyusedepentyinjectiontoEliminaterelianceon $ globalsbyinjectingdependenciesexplicty、改善可能性と測定のカップリング

$ Globalsを使用すると、単体テストが破壊され、隠された依存関係が導入され、テスト間の状態共有、混乱のある設定、分離が不十分で、シミュレートが困難になります。 2。ソリューションは次のとおりです。最初に保存してから、汚染を避けるためにグローバルな状態を復元します。 3. $ Globals Accessをサービスクラスにカプセル化し、依存関係の注入を通過して、テストでの模擬オブジェクトの使用を容易にします。 4.軽量の依存関係注入でさえ、テスト能力を大幅に改善する可能性があり、グローバル変数を直接読み取ることは避ける必要があります。 5.将来の問題を防ぐために、$ Globalsを無効にし、代わりに構成オブジェクト、依存関係噴射コンテナ、または環境変数を使用し、静的分析ツールを使用してハイパーグローバル変数の使用を検出します。最終的な答えは、$グローバルへの依存性をカプセル化と依存噴射を通じて徐々に排除する必要があります
