はじめに
PHPのクロージャ(無名関数)を使っていると、$this
の扱いに「ん?」と感じることがあります。
特に、クロージャ内で $this
をそのまま参照する場合と、クロージャに $this
を引数として渡す場合では、見た目は似ていても意味が大きく異なります。
この記事では、次の2つのコードを例に、それぞれの $this
がどのように動作するのかをわかりやすく解説します。
目次
サンプルコード
① クロージャ内で $this
を参照する場合
class Hoge{
public function foo(){
$f = function(){
var_dump($this);
};
$f();
}
}
(new Hoge())->foo();
② クロージャに $this
を引数で渡す場合
class Hoge{
public function foo(){
$f = function($this){
var_dump($this);
};
$f($this);
}
}
(new Hoge())->foo();
クロージャ内で $this
を参照する場合
$f = function(){
var_dump($this);
};
$f();
この場合、クロージャはクラスのメソッド内で定義されています。
PHPでは メソッド内で定義されたクロージャは自動的に $this
をキャプチャ するため、クロージャの中から $this
をそのまま参照できます。
実行結果は以下のように、呼び出し元のオブジェクト(Hogeインスタンス)が出力されます。
object(Hoge)#1 (0) {
}
クロージャに $this
を引数で渡す場合
$f = function($this){
var_dump($this);
};
$f($this);
こちらでは、クロージャの定義部分に function($this)
と書いています。
この $this
は「PHPの特別な変数 $this
」ではなく、単なる関数の引数名 にすぎません。
$f($this)
として呼び出すと、引数として渡したオブジェクトが $this
という名前のローカル変数に入ります。そのため出力は同じに見えますが、仕組みが全く違います。
違いの整理
パターン | $this の意味 | 動作の仕組み |
---|---|---|
① function() { var_dump($this); } | クラスインスタンス(暗黙的にバインド) | クロージャが $this を自動的にキャプチャ |
② function($this) { var_dump($this); } | 単なる関数引数 | $this はただのローカル変数であり、特別扱いされない |
注意点
実行結果はどちらも「Hogeインスタンス」が出力されますが、意味は大きく異なります。
特に②のように $this
を引数名に使うのは、可読性を下げて誤解を招く ため実務では避けるべき書き方です。
まとめ
- クロージャ内の
$this
は「呼び出し元のオブジェクト」を自動で参照できる - クロージャの引数
$this
は「ただの変数名」であって特別扱いされない - 出力は同じでも意味合いが違うので、②の書き方は混乱の元になる