はじめに
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では「変数がどのスコープに存在するか」を理解しておくと、バグや予期せぬ挙動を防げます。
