タイトル: スコープ
SEOタイトル: PHP 変数スコープ完全ガイド (global / static / use / Arrow Function)
| この記事の要点 |
|
変数スコープの基本
PHP の変数は定義した場所によって参照できる範囲が決まる仕組みです。これをスコープと呼びます。
global キーワード
関数内からグローバル変数を読み書きしたい場合に global を宣言します:
true];
function showConfig() {
global $config; // ★ グローバルから取り込む
var_dump($config);
}
showConfig(); // ['debug' => true]
// 同じことは $GLOBALS でも可能
function showConfig2() {
var_dump($GLOBALS['config']);
}
// ⚠️ アンチパターン: グローバル変数は依存関係が見えなくなる
// 推奨は引数渡し or DI
function showConfigBetter(array $config) {
var_dump($config);
}
showConfigBetter($config);
static 変数: 関数呼び出しを跨いで保持
関数引数: 値渡し vs 参照渡し
Closure と use 句
無名関数(Closure)は外側スコープを自動では取り込まないのが PHP の特徴。use で明示的に渡します:
PHP 7.4+ Arrow Function は自動キャプチャ
$prefix . $msg;
echo $logger('ok'); // [INFO] ok
// 1 式しか書けない(return が暗黙)
// 複数行 / 副作用が必要なら通常の Closure を使う
// 配列操作で重宝
$users = [['age' => 30], ['age' => 20], ['age' => 40]];
$ages = array_map(fn($u) => $u['age'], $users);
$adults = array_filter($users, fn($u) => $u['age'] >= 20);
// 注意: Arrow Function は値渡し(参照渡し不可)
$count = 0;
$inc = fn() => $count++; // 外側 $count は変わらない
$inc();
echo $count; // 0
クラスのスコープ修飾子
| 修飾子 | 意味 | アクセス |
|---|---|---|
public | 公開 | どこからでも |
protected | 保護 | 同クラス + 継承先 |
private | 非公開 | 同クラスのみ |
self:: | クラス自身 | 定義したクラス参照 |
static:: | 遅延静的束縛 | 呼び出し元クラスを参照 |
parent:: | 親クラス | 継承元参照 |
ベストプラクティス
- グローバル変数は使わない: テスト困難・依存関係不明・並列実行で衝突
- 関数 / メソッドは引数で必要な値を受ける
- クラスはDI コンテナ (Container) 経由で依存を注入
- Closure はuse 句を最小限に(多すぎたら別関数化)
static変数はメモ化など限定用途のみ。状態を持つならクラス化
FAQ
Q: global $var と $GLOBALS["var"] どちらが推奨?
A: どちらも非推奨だが、止むを得ず使うなら $GLOBALS。理由は global 宣言を後で見落としやすいから。最善はどちらも使わず引数渡し。
Q: Arrow Function で複数行書きたい
A: 仕様上 1 式のみ。複数行が必要なら通常の function () use (...) {} を使ってください。
Q: self:: と static:: の使い分け
A: 継承先で挙動を上書きしたいなら static::(遅延静的束縛)。固定したいなら self::。ファクトリメソッドは static:: が一般的です。