匿名函数(Closure)是 PHP 5.3+ 引入的第一类函数对象。use 子句控制外部变量如何被捕获到闭包作用域:值捕获(默认,复制快照)与 引用捕获(&$var,绑定原变量)。
<?php
function factory() {
$param2 = 'every';
return function ($param1) use ($param2) { // 值捕获
$param2 .= 'one'; // 修改副本
echo $param1 . ' ' . $param2;
};
}
$fn = factory();
$fn('hello'); // 输出: hello everyone
关键点:闭包创建时复制 $param2 的值,后续外部修改不影响闭包内部,闭包内修改也不影响外部。
<?php
function factory() {
$param2 = 'everyone';
$fn = function ($param1) use ($param2) {
echo $param1 . ' ' . $param2;
};
$param2 = 'everybody'; // 外部修改
return $fn;
}
$fn = factory();
$fn('hello'); // 输出: hello everyone(闭包捕获的是 'everyone')
<?php
function factory() {
$param2 = 'everyone';
$fn = function ($param1) use (&$param2) { // 引用捕获
echo $param1 . ' ' . $param2;
};
$param2 = 'everybody'; // 外部修改
return $fn;
}
$fn = factory();
$fn('hello'); // 输出: hello everybody(闭包看到最新值)
<?php
$users = [
['name' => 'Alice', 'age' => 25],
['name' => 'Bob', 'age' => 30],
];
$minAge = 28;
$filtered = array_filter($users, function ($user) use ($minAge) {
return $user['age'] >= $minAge;
});
// $filtered 仅含 Bob
Closure::bindTo()<?php
class Service {
private $secret = 'internal-data';
}
$svc = new Service();
$closure = function () {
return $this->secret; // 访问私有属性
};
// 绑定到 $svc 实例,作用域为 Service 类
$bound = Closure::bind($closure, $svc, 'Service');
echo $bound(); // 输出: internal-data
<?php
function heavyComputation() {
// 耗时操作...
return 42;
}
// 立即执行版
$result = heavyComputation();
// 惰性版:仅在调用时执行
$lazy = function () { return heavyComputation(); };
// 业务逻辑决定是否调用
if ($needResult) { echo $lazy(); }
<?php
class Handler {
public function __invoke() { echo 'handled'; }
}
$handler = new Handler();
$closure = $handler; // 自动转为 Closure,绑定 $this
$closure(); // 输出: handled
| 场景 | 建议 |
|---|---|
| 大量循环创建闭包 | 移出循环复用,或改用普通函数/类方法 |
| 引用捕获大数组/对象 | 谨慎使用,可能导致内存无法释放(循环引用需手动打破) |
| 序列化闭包 | 需用 opis/closure 库,原生 serialize() 不支持 |
use (&$var)。$this(PHP 7.1+ 自动绑定),显式 use ($this) 易循环引用。function (int $id) use (string $token): array { ... } 提升可读性与静态分析能力。use 子句是 PHP 闭包变量捕获的核心控制机制。掌握「值捕获快照」与「引用捕获绑定」的语义差异,结合 Closure::bindTo、惰性求值、回调模式等进阶技巧,能编写出更灵活、函数式风格的 PHP 代码。下一篇将探讨「生成器」与「协程」在异步编程中的应用。