基礎

PHPのstatic変数|関数呼び出し間で値を保持する方法

PHPのstatic変数は、関数内で宣言された変数でありながら、関数の呼び出しが終わっても値を保持し続ける特殊な変数です。通常のローカル変数は関数の実行が終わると破棄されますが、static変数は次の呼び出し時にも前回の値が残っています。

カウンターやキャッシュ、初回実行時のみの初期化処理など、関数の呼び出し回数や前回の状態を記憶する必要がある場面で非常に有用です。

基本的な使い方

関数内で static キーワードを付けて変数を宣言します。初期値は最初の呼び出し時に一度だけ設定されます。

PHP
<?php
function counter() {
    static $count = 0;
    $count++;
    echo "呼び出し回数: {$count}\n";
}

counter();
counter();
counter();
実行結果
呼び出し回数: 1
呼び出し回数: 2
呼び出し回数: 3

static $count = 0; の初期化は最初の呼び出し時にのみ実行されます。2回目以降の呼び出しでは前回の値が保持されているため、カウントが増え続けます。

通常の変数との比較

PHP
<?php
function normalVar() {
    $count = 0;  // 毎回リセットされる
    $count++;
    echo "通常変数: {$count}\n";
}

function staticVar() {
    static $count = 0;  // 値が保持される
    $count++;
    echo "static変数: {$count}\n";
}

normalVar();  // 1
normalVar();  // 1(毎回リセット)
normalVar();  // 1

staticVar();  // 1
staticVar();  // 2(前回の値が残る)
staticVar();  // 3
実行結果
通常変数: 1
通常変数: 1
通常変数: 1
static変数: 1
static変数: 2
static変数: 3

キャッシュとしての活用

計算コストの高い処理の結果をstatic変数にキャッシュすることで、2回目以降の呼び出しを高速化できます。

PHP
<?php
function getConfig(string $key): ?string {
    static $config = null;

    // 初回のみ設定を読み込む
    if ($config === null) {
        echo "(設定ファイル読み込み中...)\n";
        $config = [
            "db_host" => "localhost",
            "db_name" => "myapp",
            "debug" => "true",
        ];
    }

    return $config[$key] ?? null;
}

echo getConfig("db_host") . "\n";
echo getConfig("db_name") . "\n";
echo getConfig("debug") . "\n";
実行結果
(設定ファイル読み込み中...)
localhost
myapp
true

「設定ファイル読み込み中...」のメッセージは1回目の呼び出しでのみ表示されます。2回目以降はキャッシュされた値が使われるため、効率的です。

実用的な例

PHP
<?php
// ユニークIDジェネレータ
function generateId(string $prefix = "ID"): string {
    static $sequence = 0;
    $sequence++;
    return $prefix . "-" . str_pad($sequence, 4, "0", STR_PAD_LEFT);
}

echo generateId() . "\n";
echo generateId("USER") . "\n";
echo generateId("ORDER") . "\n";
echo generateId() . "\n";

// フィボナッチ数列(メモ化)
function fibonacci(int $n): int {
    static $memo = [];
    if ($n <= 1) return $n;
    if (isset($memo[$n])) return $memo[$n];
    $memo[$n] = fibonacci($n - 1) + fibonacci($n - 2);
    return $memo[$n];
}

for ($i = 0; $i <= 10; $i++) {
    echo fibonacci($i) . " ";
}
echo "\n";
実行結果
ID-0001
USER-0002
ORDER-0003
ID-0004
0 1 1 2 3 5 8 13 21 34 55 
ポイント

static変数はスクリプトの実行が終了するまで値を保持します。Webアプリケーションでは1リクエストごとにスクリプトが実行されるため、リクエスト間で値は共有されません。永続的なデータ保持にはデータベースやセッションを使用してください。

注意

static変数は関数に隠れた状態を持たせるため、テストが難しくなる場合があります。ユニットテストでstatic変数をリセットする手段がないため、テスタビリティを重視する場合はクラスのプロパティとして管理する方が適切です。

まとめ

  • static を付けた変数は関数の呼び出し間で値が保持される
  • 初期値は最初の呼び出し時に一度だけ設定される
  • カウンター、キャッシュ、ユニークID生成などに活用できる
  • スクリプト終了で値は破棄され、リクエスト間では共有されない
  • テスタビリティの観点から、必要な場面に限定して使うのが望ましい