本文目录导读:

PHP 闭包(Closure)也称为匿名函数,是PHP中非常强大的特性,让我详细介绍它的用法:
基本语法
<?php
// 基础闭包
$greet = function($name) {
echo "Hello, " . $name . "!\n";
};
$greet('World'); // 输出: Hello, World!
use 关键字使用外部变量
<?php
$message = 'Hello';
$greet = function($name) use ($message) {
echo $message . ', ' . $name . "!\n";
};
$greet('PHP'); // 输出: Hello, PHP!
// use 按值传递(拷贝)
$number = 1;
$add = function() use ($number) {
$number++;
echo $number . "\n";
};
$add(); // 输出: 2
echo $number; // 输出: 1 (原值不变)
// 使用 & 按引用传递
$number = 1;
$add = function() use (&$number) {
$number++;
echo $number . "\n";
};
$add(); // 输出: 2
echo $number; // 输出: 2 (值已改变)
作为回调函数使用
<?php
// 数组处理
$numbers = [1, 2, 3, 4, 5];
// 使用 array_map
$squared = array_map(function($n) {
return $n * $n;
}, $numbers);
print_r($squared); // [1, 4, 9, 16, 25]
// 使用 array_filter
$even = array_filter($numbers, function($n) {
return $n % 2 == 0;
});
print_r($even); // [2, 4]
// 使用 usort
$fruits = ['apple', 'Orange', 'banana'];
usort($fruits, function($a, $b) {
return strcmp(strtolower($a), strtolower($b));
});
print_r($fruits); // ['apple', 'banana', 'Orange']
作为函数参数传递
<?php
// 定义接受闭包的函数
function processData($data, $callback) {
$result = [];
foreach ($data as $item) {
$result[] = $callback($item);
}
return $result;
}
$numbers = [1, 2, 3, 4];
// 传入闭包
$doubled = processData($numbers, function($n) {
return $n * 2;
});
print_r($doubled); // [2, 4, 6, 8]
返回闭包(工厂模式)
<?php
// 创建一个乘法器
function createMultiplier($factor) {
return function($number) use ($factor) {
return $number * $factor;
};
}
$double = createMultiplier(2);
$triple = createMultiplier(3);
echo $double(5); // 输出: 10
echo $triple(5); // 输出: 15
绑定 $this(闭包绑定)
<?php
class User {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
$user = new User('Alice');
// 创建闭包
$closure = function() {
return $this->getName();
};
// 绑定闭包到对象
$bound = $closure->bindTo($user);
echo $bound(); // 输出: Alice
// 使用 Closure::call (PHP 7+)
echo $closure->call($user); // 输出: Alice
箭头函数(PHP 7.4+)
<?php
// 箭头函数简洁语法
$factor = 10;
$numbers = [1, 2, 3];
// 传统闭包
$result1 = array_map(function($n) use ($factor) {
return $n * $factor;
}, $numbers);
// 箭头函数
$result2 = array_map(fn($n) => $n * $factor, $numbers);
print_r($result1); // [10, 20, 30]
print_r($result2); // [10, 20, 30]
实际应用示例
<?php
// 示例1:构建灵活的过滤系统
class ProductFilter {
private $products;
public function __construct($products) {
$this->products = $products;
}
public function filter($callback) {
return array_filter($this->products, $callback);
}
}
$products = [
['name' => 'Laptop', 'price' => 999],
['name' => 'Mouse', 'price' => 25],
['name' => 'Keyboard', 'price' => 50]
];
$filter = new ProductFilter($products);
// 找到价格低于100的产品
$cheapProducts = $filter->filter(function($product) {
return $product['price'] < 100;
});
print_r($cheapProducts);
// 示例2:事件系统
class EventEmitter {
private $listeners = [];
public function on($event, $callback) {
$this->listeners[$event][] = $callback;
}
public function emit($event, $data = null) {
if (isset($this->listeners[$event])) {
foreach ($this->listeners[$event] as $callback) {
$callback($data);
}
}
}
}
$emitter = new EventEmitter();
$emitter->on('user_login', function($user) {
echo "用户 {$user} 登录了\n";
});
$emitter->on('user_login', function($user) {
echo "记录登录日志: {$user}\n";
});
$emitter->emit('user_login', '张三');
闭包的常用方法
<?php
$closure = function($param) {
return $param * 2;
};
// 检查类型
echo get_class($closure); // Closure
// 使用反射
$reflection = new ReflectionFunction($closure);
echo $reflection->getNumberOfParameters(); // 1
echo $reflection->getName(); // {closure}
// bind/bindTo 方法
$boundClosure = Closure::bind($closure, null, 'SomeClass');
注意事项
<?php
// 1. use 捕获变量时是副本
$var = 'outside';
$closure = function() use ($var) {
echo $var;
};
$var = 'changed';
$closure(); // 输出: outside
// 2. 作用域问题
$prev = function() {
// 无法访问外部变量,除非使用 use
// echo $externalVar; // 错误
};
// 3. 递归闭包需要显式声明
$factorial = function($n) use (&$factorial) {
if ($n <= 1) return 1;
return $n * $factorial($n - 1);
};
echo $factorial(5); // 120
闭包在PHP中的主要用途:
- 回调函数
- 函数式编程
- 事件处理
- 依赖注入
- 状态封装
- 延迟计算
掌握闭包可以让你写出更灵活、更简洁的代码,在面向对象和函数式编程之间架起桥梁。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播