use默认值传递,捕获发生在匿名函数创建时;加&才实现真正引用传递;对象传参看似可改属性实为标识符副本,替换对象本身需显式引用。

是的,use 默认就是值传递 —— 闭包定义时会拷贝一份当前作用域中变量的值,之后外部变量再怎么改,闭包里都看不到。
use 变量是在定义时捕获,不是调用时
很多人误以为闭包执行时才去读外部变量,其实不是。捕获发生在 function() use ($x) { ... } 这行代码执行(即匿名函数被创建)的那一刻。
- 如果
$x此时未定义,会直接报Notice: Undefined variable - 如果
$x = 42,那闭包内部的$x就固定是42,哪怕之后你把$x改成99,闭包里还是42 - 数组、对象等复合类型也是“值传递”,但要注意:对象是传对象引用的副本(即指向同一块内存),所以修改对象属性会影响外部;而数组是深拷贝(PHP 7+ 中对非引用数组是写时复制,但语义上仍视为值传递)
想让闭包和外部共享变量?必须显式加 &
只有加 & 才真正实现引用传递,变量本体被共享。这是唯一可靠方式。
-
use ($count)→ 外部改$count,闭包里不变;闭包里改$count,外部也不变 -
use (&$count)→ 两边看到的是同一个变量,任一方修改都会立即反映到另一方 - 注意:
use (&$this)在静态闭包中非法,PHP 会报Fatal error -
use后只能跟变量名,不能跟表达式,比如use ($arr[0])或use ($obj->prop)都语法错误
对象传参时“看似”能双向修改,但这不是引用传递
传对象不加 & 也能在闭包里改属性并影响外部,容易让人误解为“自动引用”。其实这只是对象行为的副作用,本质仍是值传递(传递的是对象标识符,类似指针值)。
立即学习“PHP免费学习笔记(深入)”;
$obj = new stdClass(); $obj->val = 1;$f = function() use ($obj) { $obj->val = 2; };- 执行后
$obj->val确实变成2,但如果你给$obj赋新值:$obj = new stdClass();,闭包里的$obj不会变 —— 这说明它持有的是原对象的副本标识,不是引用本身 - 若真要替换对象本身(比如
$obj = null),就必须用use (&$obj)
最容易被忽略的是:use 捕获时机和变量生命周期绑定,而不是和闭包调用绑定;另外,& 引用只对变量本体有效,对对象内部状态的修改只是巧合共享,不能当成通用方案来依赖。



















