WEBサービス創造記

WEBサービスを作ったり保守したりしてる人のメモブログです。

PHPでの変数のスコープ

      2015/05/20

PHPでの変数のスコープの種類

プログラミングPHP 第3版の”2.3.3 変数のスコープ”を読んでPHPのスコープについて復習したときのメモです。

変数のスコープとは変数の有効範囲のことです。
変数が定義されたコンテキスト(場所、状況)によってスコープが決まります。

スコープにはいくつかの種類がありますが、この章で記載されているスコープの種別は以下の4つです。

  • グローバルスコープ
  • ローカルスコープ
  • static変数
  • 関数のパラメータ

以下にそれぞれの具体例をコードを書いてみていきたいと思います。

グローバルスコープ

関数の外側で定義した変数はグローバル変数と呼ばれ、基本的にはプログラムのどこからでもアクセスすることができます。
ただし、デフォルトでは関数内からはアクセスすることができません。

<?php

$hoge = "foo";    // グローバル変数

function scope_test() {
    echo $hoge;
}

scope_test();    // => 何も出力されない

echo $hoge;      // => "foo"

関数内からもグローバル変数にアクセスできるようにするにはglobalキーワードの使用が必要となります。

<?php

$hoge = "foo";

function scope_test() {
    global $hoge;    // これが必要
    echo $hoge;
}

scope_test();    // => "foo"

グローバル変数のスコープはグローバルスコープと呼ばれます。

ローカルスコープ

関数内で定義された変数のことをローカル変数と呼びます。
ローカル変数の有効範囲は、グローバル変数とは違って定義された関数の中だけとなります。

<?php

$hoge = "foo";

function scope_test() {
    $local_var = "local";
}

echo $local_var;    // => 何も出力されない
<?php

$hoge = "foo";    // グローバル変数

function scope_test() {
    $hoge = "bar";    // ローカル変数
    echo $hoge;
}

scope_test();    // => "bar"

ローカル変数は関数が終了した時点で破棄されます。

ローカル変数のスコープはローカルスコープと呼ばれます。

static変数

static変数はスコープはローカル変数と同様ですが、関数が終了しても破棄されません。
static変数はstaticキーワードをつけて宣言します。

<?php

function count_up() {
    static $count = 0;    // static変数宣言
    return ++$count;
}

echo count_up();    // => 1
echo count_up();    // => 2
echo count_up();    // => 3

関数のパラメータ

関数のパラメータはローカルスコープと同じく関数内でのみ有効で、関数終了後破棄となります。

<?php
function scope_test($hoge) {
    echo $hoge;
}

$hoge = "foo";
scope_test($hoge);    // => "foo"

まとめ

それぞれのスコープでの有効範囲や変数破棄のタイミングなどをまとめると下表の通りとなります。
なお、空欄のものは書籍に記載がありませんでしたので、分かり次第記載します。

スコープ名 有効範囲 変数破棄のタイミング 備考
グローバルスコープ どこでも有効 関数内で使うときはglobalキーワードが必要
ローカルスコープ 関数内のみ 関数終了時
static変数 関数内のみ 関数終了しても破棄されない
関数のパラメータ 関数内のみ 関数終了時 ローカルスコープと同じ

グローバルスコープとstatic変数破棄のタイミングはスクリプト終了時だと思っていますが信頼性の高い資料による裏が取れてないので引き続き調査中です。

グローバル変数とstatic変数の破棄に関しては、PHPのガベージコレクションに収集されるタイミングに準拠と考えて良さそうです。

PHP の変数 (zval) はリファレンスカウンティングで管理されており、不要になった変数は型を問わず、参照カウンタが 0 になった時点で削除されます。

参照カウンタがデクリメントされるのは主に変数が unset されたとき、別の値が代入されたとき、定義されたスコープを抜けたとき等です。

また、リクエストが終了した時点 (CLI ではプロセスが終了した時点) で変数が登録されているシンボルテーブルが破棄され、その際にすべての変数は再帰的に開放されます。

PHP5 のオブジェクトの消滅タイミング – PHPプロ!Q&A掲示板より抜粋

以上です。

参考資料

 - PHP , , , , , ,