
PHP匿名函数里用不到外部变量?那是没加use
PHP匿名函数默认无法访问定义它的作用域里的变量,这不是bug,是设计——它不自动继承上下文。想用就得显式声明,靠use关键字把变量“搬进去”。
常见错误现象:Undefined variable警告,或变量值始终是null/0,尤其在循环里反复创建匿名函数时,容易误以为闭包自动捕获了最新值。
-
use后面必须跟变量名,不能是表达式(比如use ($a + $b)非法) - 要修改外部变量,得加
&引用符号:use (&$count),否则只传值副本 - PHP 7.4+ 支持箭头函数
fn() =>,它自动继承父作用域变量,但只读、不支持引用、不能写多行
循环中创建多个匿名函数,为什么都记住同一个值?
因为变量本身被复用,而use捕获的是变量的“引用位置”,不是当时值。循环结束时,那个变量只剩最后一次迭代的结果。
使用场景:生成一组回调,每个对应不同ID或配置;比如事件监听器、路由处理器。
立即学习“PHP免费学习笔记(深入)”;
- 解决办法:在循环内用临时变量“快照”当前值,再
use它:$id = $item['id']; $handler = function() use ($id) { ... }; - 或者直接在
use里赋值(PHP 7.4+):function() use ($item = $item) { ... },但注意这仅限于简单赋值 - 别依赖
foreach ($list as $k => $v)中的$v在use里“自动快照”——它不会
use能传哪些东西?超全局变量、$this、常量怎么处理?
use只能传变量(包括数组元素、对象属性引用),不能传函数、常量、超全局数组(如$_POST)本身,也不能直接传$this——但可以传$self = $this后再use ($self)。
性能影响:传大数组或对象不会深拷贝,只是增加引用计数;传引用&$data则共享内存地址,改了会影响外部。
- 超全局变量要先赋给局部变量:
$post = $_POST; $fn = function() use ($post) { ... }; -
$this可用$self = $this中转,箭头函数fn()可直接用$this(PHP 7.4+) - 常量不能
use,但函数体内可直接用self::CONST或MY_CONST
匿名函数里改了use进来的变量,外面看不到?
默认按值传递,改了只影响函数内部。要让外部也变,必须用引用传递,而且外部变量本身得可写(比如不是函数返回值或字面量)。
容易踩的坑:以为use ($arr)后$arr[] = 1会改变原数组——不会;得use (&$arr)才行。但对象不用引用也能改属性,因为对象变量本身就是引用句柄。
- 数组、字符串、数字等标量类型:必须
use (&$var)才能双向同步 - 对象、资源:按值
use ($obj)已足够修改其属性,无需& - 注意引用生命周期:
unset($var)后,闭包里use (&$var)仍能读写,但外部变量已销毁
use那一刻就决定了它和谁绑着,之后外部重赋值不影响闭包里的那份快照——除非你主动用了引用。











