W.I.S. Laboratory
menu-bar

PHP


PHPの関数内関数から外側関数のローカル変数にアクセスしたい

PHPは関数の中に関数が書ける言語だ。
こういう言語は他にもたくさんあり、JavaScriptやPythonも関数内に関数が書ける。
ただ、「書ける」ということと、内側関数のスコープが外側関数と繋がっているかどうかということは別物だ。
どういうことかというと、

このコードを読むと、直感的には「100」が表示されそうな感じがする。
しかし実際には「Undefined variable $x」というワーニングが表示されてしまう。
そうかそうか、useすれば良いんだな、ということで、

こんなコードにすると、今度は「syntax error, unexpected token "use", expecting "{"」エラーが出てしまう。
PHPでuse命令が使えるのはラムダ式(無名関数)だけなので、通常の関数には使えない。
では、どうすればinner関数の中からouter関数のローカル変数「$x」にアクセスできるのだろうか。
まずPHPの関数内関数がどのようにPHPに認識されているかを調べてみる。

このコードは直感的には動きそうにない。
しかしこれはちゃんと動くのだ。
inner関数は、outer関数の中でしか呼び出せそうにないが、実際はどこからでも呼び出せる。
ただし、

呼び出す順序を逆にすると「Uncaught Error: Call to undefined function inner()」エラーになってしまう。
PHPは関数が書かれたコードが実際に動いて初めて関数定義されるので、未定義になってしまうのだ。

下のコードも直感的には問題なさそうなのだが、

outer2を呼び出したときに、「inner」関数はもう定義済みだよというエラーが出てしまう。
つまり、PHPの関数内関数は、見た目こそ関数の中にあるが、単なる「関数」なのだ。
どこに書くかという違いがあるだけで、PHP内では同一次元で扱われている。
ということで、今やろうとしていることは、

これと同じことだということが分かる。
つまり不可能だ。
どうしても $x にアクセスしたければ、outer関数の中から inner($x) として引数で渡すしかない。
こういう仕様の言語はPHPに限ったことではなく、例えばRubyも同じだ。
では諦めるしかないかというとまったくそんなことはなく、ラムダ式(無名関数)を使ってuseすればいい。


[ 戻る ]
saluteweb