はじめに
PHPには、可変変数という変数名を動的に指定できる機能があるのですが、これが使えない場合というやつに引っかかったのでメモしておきます。この投稿では、可変変数の説明を軽くしたあと、可変変数が使えない場合とそのサンプルについて言及することにします。
可変変数とは
例を先に挙げてしまうと、以下のようなことができる機能です。
$hoge = 'fuga';
$fuga = 'piyo';
echo $$hoge; // => piyo
echo $$hoge;
はecho ${$hoge};
と等価で、{}
内が先に処理されてecho ${'fuga'};
になり、piyo
が出力されたと考えればわかりやすいでしょう。詳しい説明は公式ドキュメントPHP: 可変変数 - Manualをご参照ください。
失敗したケース
スーパーグローバルに対して一気に処理をしようと思って以下のようなコードを書きました。// =>
は実行結果です。var_dump($_SERVER);
をするとUndefined variable
などのエラーが出るかと思ったのですが、なんと消したはずの$_SERVER
が存在してしまっています。
function UnsetSuperGlobals() {
$super_globals = [
'_SERVER',
'_GET',
'_POST',
'_FILES',
'_COOKIE',
'_SESSION',
'_REQUEST',
'_ENV',
];
foreach ($super_globals as $super_global) {
unset($$super_global);
}
}
UnsetSuperGlobals();
var_dump($_SERVER); // => いろいろ表示される
$_SERVER
はスーパーグローバルなので、関数内で消しても外で生きている、ということもなさそうだし、降参してドキュメントを見に行きました。
ちゃんと書いてあった
警告
関数やクラスメソッドの内部で、可変変数と PHP の スーパーグローバル配列 とを組み合わせては使用できないということに注意してください。 $this も特別な変数であり、 動的に参照することはできません。
今回は「関数の内部で」、「可変変数とPHPのスーパーグローバルとを組み合わせ」たので、この警告に当てはまっております。
実験して確かめておく
せっかくなので、ダメなケースを実際に確かめておくことにしました。スーパーグローバルの場合だけですが、以下のようなコードを書きました。
$variable_name_global = '_SERVER';
var_dump($$variable_name_global); // => いろいろ出てくる
// 関数の場合
function sample_function() {
$variable_name_local = '_SERVER';
var_dump($$variable_name_local);
}
sample_function(); // => NULL
class SampleClass
{
// クラスメソッドの場合
public static function sample_class_method()
{
$variable_name_class = '_SERVER';
var_dump($$variable_name_class);
}
// インスタンスメソッドの場合
public function sample_instance_method()
{
$variable_name_instance = '_SERVER';
var_dump($$variable_name_instance);
}
}
SampleClass::sample_class_method(); // => NULL
(new SampleClass)->sample_instance_method(); // => NULL
めでたく、可変変数が使えないことが確かめられました。
おわりに
最後まで読んでいただきありがとうございました。指摘やコメントなどは大歓迎なので教えていただけると幸いです。
あと、可変変数って「Variable variable」って言うんですね。