はじめに
PHPには「変数変数」という機能があります。${$var}
のように書くと、変数名を動的に組み立ててアクセスできます。しかし、関数のローカル変数に対してこれを使おうとすると、Warningが出てNULLになります。
この記事では、その理由と正しいアクセス方法について解説します。
目次
ソースコード
再現コード
<?php
declare(strict_types=1);
error_reporting(-1);
function func1(){
$local_num = 987;
}
$v_name = 'func1::local_num';
var_dump(${$v_name});
実行結果:
Warning: Undefined variable $func1::local_num in /var/www/html/p24.php on line 9
NULL
なぜこうなるのか?
ローカル変数は関数内だけ有効
PHPでは、関数内で宣言された変数はローカルスコープに属します。
これは関数が実行されている間だけ存在し、関数外から直接参照することはできません。
つまり $local_num
は func1()
の中だけの存在で、外からは見えません。
変数変数の探索範囲
${$v_name}
は、現在のスコープで $v_name
の値を名前とする変数を探します。今回 $v_name
には func1::local_num
という文字列が入っていますが、そのような変数は存在しないためUndefined variable
が発生します。
func1::local_num
という構文は存在しない
func1::local_numという構文は存在しない
クラス名::定数名
という書き方はクラスの定数アクセス構文ですが、関数にはこのような変数アクセスの仕組みはありません。func1::local_num
という「関数内変数」参照構文はPHPには存在しないのです。
正しい値の取得方法
方法1:戻り値を使う(推奨)
function func1(){
$local_num = 987;
return $local_num;
}
$value = func1();
var_dump($value); // int(987)
方法2:グローバル変数(非推奨)
function func1(){
global $local_num;
$local_num = 987;
}
func1();
var_dump($local_num); // int(987)
※グローバル変数は依存関係が不透明になるため、保守性が下がります。
方法3:static変数を使う
function func1(){
static $local_num = 987;
return $local_num;
}
var_dump(func1()); // int(987)
※staticは関数が終了しても値を保持します。
まとめ
- 関数内のローカル変数は関数外から直接参照できない
- 変数変数
${$var}
は現在のスコープでしか変数を探さない func1::local_num
のような構文は存在しない- 値を取り出すなら戻り値か、明示的にスコープをまたぐ方法を使うべき
PHPでは「変数がどのスコープに存在するか」を理解しておくと、バグや予期せぬ挙動を防げます。