はじめに
PHP でクロージャ(無名関数)を使うとき、外側の変数をスコープに取り込むために use を使います。ところが、この use には
use ($var)→ 値をコピーして保持use (&$var)→ 変数への参照を保持
という重要な違いがあります。この記事では具体例を通して、この挙動の差を整理していきます。
目次
サンプルコード
値渡しの場合
<?php
declare(strict_types=1);
error_reporting(-1);
function hoge(){
$i = 11;
$f = function() use ($i){
echo $i , '<br>';
};
$f();
$i = 22;
$f();
$i = 33;
$f();
}
hoge();参照渡しの場合
<?php
declare(strict_types=1);
error_reporting(-1);
function hoge(){
$i = 11;
$f = function() use (&$i){
echo $i , '<br>';
};
$f();
$i = 22;
$f();
$i = 33;
$f();
}
hoge();実行結果の比較
値渡し (use ($i)) の場合
実行結果
11
11
11参照渡し (use (&$i)) の場合
実行結果
11
22
33解説
use ($i)はクロージャを定義した時点の値をコピーして保持する。use (&$i)はクロージャが外側の変数そのものを参照し続けるため、外側で値を変更するとクロージャの中から見える値も変わる。- クロージャ内で変数を書き換える場合も、コピーか参照かで挙動が大きく変わる。
まとめ
- スナップショットを取りたい →
use ($var) - 外の変数と同期して扱いたい →
use (&$var)
クロージャを使う場面では「コピーするのか、参照するのか」を意識することが大事です。これを理解しておくと、バグの混入を防ぎやすくなります。
