PHP入門 変数の有効範囲(スコープ)

最終更新日

ユーザー定義関数の有効範囲(スコープ)について解説しています。

スコープ

スコープとは、スクリプトの中での変数の有効範囲のことです。PHPのスコープは、スクリプト全体から参照できるグローバルスコープと、定義された関数の中でのみ参照できるローカルスコープとに分類できます。

スコープ図
グローバルスコープとローカルスコープ

グローバル変数とローカル変数

グローバルスコープを持つ変数をグローバル変数、ローカルスコープを持つ変数のことをローカル変数と言います。変数がグローバル変数/ローカル変数のいずれかであるかは、変数の定義している場所によります。

<?php
$x = 10;
function checkScope(): int{
  return ++$x;
}

print checkScope();  //結果:1
print $x;            //結果:10

グローバル変数とローカル変数、スコープの異なる変数は、名前が同一であっても違う変数とみなされる。

関数やクラスは常にグローバルスコープを持ちます。関数内関数であっても、関数の外部から呼び出すことはできますし、逆に関数の中から外部の関数を呼び出してもかまいません。

関数内でグローバル変数を利用する(global命令)

例外的に関数ブロックの中からグローバル変数を操作したい場合、global命令を利用します。ローカル変数を強制的にグローバル変数に割り当てることができます。

<?php
$x = 10;
function checkScope(): int{
  global $x;     //➊
  return ++$x;
}

print checkScope(); //結果:11
print $x;           //結果:11

➊によって、関数内の$xがグローバル変数とみなされます。

静的変数(static命令)

関数の終了後もローカル変数を保持していくには、静的変数を利用します。静的変数は、static命令で定義できます。静的変数は、関数の初回呼び出し時にのみ初期化され、その後、関数の処理が終了しても維持されます。「静的変数はあくまでローカル変数である」ということであり、有効なのは関数ブロックの中だけです。

<?php
$x = 10;
function checkStatic(): int{
  static $x = 0;
  return ++$x;
}

print checkScope(); //結果:1
print checkScope(); //結果:2
print $x;           //結果:空(null)

インクルードファイルのスコープ

require_once命令などによって読み込まれたインクルードファイルのスコープは、読み込み元のスコープによって変動します。つまり、関数の外でファイルを読み込んだ場合、インクルードファイルのスコープはグローバルスコープになりますし、関数の中から読み込んだファイルはローカルスコープとなります。

例:インクルードファイルを、それぞれ関数の外、中から読み込む

scope_included.php

<?php
$scope = 'アクセスできました。';

scope_include_global.php

<?php
require_once 'scope_included.php';
print $scope;  //結果:アクセスできました。

scope_include_local.php

インクルードファイルファイルがcheckScope関数の中から呼び出されるので、変数$scopeはローカルスコープとなります。結果、checkScope関数経由であれば変数$scopeにアクセスできます。

<?php
function checkScope(): string{
  require_once 'scope_included.php';
  return $scope;
}
print checkScope();  //結果:アクセスできました。
print $scope;        //結果:カラ(表示されない)

unset関数の挙動

unset関数を利用することで変数を破棄できます。しかし、globalキーワードで定義された変数や、静的変数(static変数)を破棄する場合には、注意する点もあります。

globalキーワード

<?php
$x = 10;
function checkScope(): int{
  global $x;
  unset($x);
  return ++$x;
}

print checkScope(); //結果:1
print $x;           //結果:10

あくまで破棄されるのは「グローバル変数のようにふるまうローカル変数」だけです。関数外部のグローバル変数には影響しません。

関数の中でグローバル変数を破棄したい場合は

unset($GLOBALS['x']);

のように。$Globalsを介する必要があります。$GLOBALSは、すべてのグローバル変数を管理する特殊な連想配列です。

staticキーワード

静的変数を破棄したい場合は、その関数での以降の処理でのみ変数を破棄します。

<?php
function checkStatic():void{
  static $x =0;                //➊
  $x++;                        //➊
  print "unset前:{$x}";       //➊
  unset($x);                   //➋
  $x = 13;                     //➌
  print "unset後:{$x}<br />"  //➌
}
checkStatic();  //結果:unset前:1 unset後:13
checkStatic();  //結果:unset前:2 unset後:13

この例の場合、➊の段階では静的変数は有効です。そして、➋で$xを破棄していますが、この時点でも、静的変数を解除して一時的に$xをローカル変数にしているというだけで、静的変数そのものは破棄されていません。そのため、➌で$xに異なる値をセットしても、静的変数$xには影響が及ばないというわけです。