
先日、こんな事件がありました。
<?php
class Hoge
public function doSomething() {
$func = $this->func;
$func();
// これ以降 $func は使われていない
}
}
このようなコードがあり、これを
<?php
class Hoge
public function doSomething() {
$this->func();
}
}
こう書き換えた結果事故った。という事件がありました。
どういうことなのか
一見正しく変更したように見えるコードですが、何がだめなんでしょう。
$func = $this->func; $func()
これが
$this->func()
こうなっただけです。なんか下の書き方も正しそうに見えますよね?
もっとわかりやすく
こうです
$this->func = function() {
echo 'やったぜ';
}
$func = $this->func;
$func();
これの結果はどうなるでしょう?
当然「やったぜ」になります。
では
$this->func = function() {
echo 'やったぜ';
}
$this->func();
これは?
「やったぜ」になりそうな気がしません。
何が間違いなの?
正しくはこうです
$this->func = function() {
echo 'やったぜ';
}
($this->func)();
何が違うのでしょう。
具体的に動くコードで見てみる
わかりましたか?
つまり、 $this->func() は クラスに実装されたメソッドを呼ぶというコードになるのです。
クラスのプロパティを呼ぶのは $this->func で、そのプロパティが callable な場合は ($this->func)() として、さきにプロパティとして解決させてあげてから、それをcallableとして呼ぶ、というように書く必要があるのです。
実はこの ($this->func)() という書き方、PHP7から使えるようになりました。PHP7以前は、最初に書いたように
$func = $this->func; $func();
と一回変数に置く書き方でしか呼べないので、このコードは正しかったわけです。
PHP7になり Type Hinting 等便利な機能が多数つきましたが、地味にこういう機能もついてたんでしたね。へー。
*1:gistの貼り付け機能をはじめて使ってみた気がする