匿名函数 #
一、匿名函数基础 #
1.1 什么是匿名函数 #
匿名函数是没有名称的函数,也称为闭包(Closure):
php
<?php
$greet = function(string $name): string {
return "Hello, $name!";
};
echo $greet("John");
1.2 赋值给变量 #
php
<?php
$add = function(int $a, int $b): int {
return $a + $b;
};
echo $add(1, 2);
1.3 作为参数传递 #
php
<?php
function execute(callable $callback, mixed $value): mixed
{
return $callback($value);
}
$result = execute(function($x) {
return $x * 2;
}, 5);
echo $result;
1.4 立即执行 #
php
<?php
$result = (function(int $a, int $b): int {
return $a + $b;
})(1, 2);
echo $result;
二、闭包与use关键字 #
2.1 从父作用域继承变量 #
php
<?php
$message = "Hello";
$greet = function() use ($message) {
echo $message;
};
$greet();
2.2 值传递vs引用传递 #
php
<?php
$counter = 0;
$increment = function() use ($counter) {
$counter++;
echo $counter . "\n";
};
$increment();
echo "Outside: $counter\n";
$counter = 0;
$incrementRef = function() use (&$counter) {
$counter++;
echo $counter . "\n";
};
$incrementRef();
echo "Outside: $counter\n";
2.3 多个变量 #
php
<?php
$prefix = "Hello";
$suffix = "!";
$greet = function(string $name) use ($prefix, $suffix): string {
return "$prefix, $name$suffix";
};
echo $greet("John");
2.4 修改继承的变量 #
php
<?php
$total = 0;
$addToTotal = function(int $value) use (&$total): int {
$total += $value;
return $total;
};
echo $addToTotal(10);
echo $addToTotal(20);
echo $addToTotal(30);
三、回调函数 #
3.1 array_map #
php
<?php
$numbers = [1, 2, 3, 4, 5];
$squared = array_map(function($n) {
return $n ** 2;
}, $numbers);
print_r($squared);
3.2 array_filter #
php
<?php
$numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
$even = array_filter($numbers, function($n) {
return $n % 2 === 0;
});
print_r($even);
3.3 array_reduce #
php
<?php
$numbers = [1, 2, 3, 4, 5];
$sum = array_reduce($numbers, function($carry, $item) {
return $carry + $item;
}, 0);
echo $sum;
3.4 usort #
php
<?php
$users = [
['name' => 'John', 'age' => 25],
['name' => 'Jane', 'age' => 30],
['name' => 'Bob', 'age' => 20]
];
usort($users, function($a, $b) {
return $a['age'] <=> $b['age'];
});
print_r($users);
3.5 preg_replace_callback #
php
<?php
$text = "The price is $100 and $200";
$result = preg_replace_callback('/\$(\d+)/', function($matches) {
return '¥' . ($matches[1] * 7);
}, $text);
echo $result;
四、高阶函数 #
4.1 返回函数 #
php
<?php
function createMultiplier(int $factor): callable
{
return function(int $number) use ($factor): int {
return $number * $factor;
};
}
$double = createMultiplier(2);
$triple = createMultiplier(3);
echo $double(5);
echo $triple(5);
4.2 函数组合 #
php
<?php
function compose(callable $f, callable $g): callable
{
return function($x) use ($f, $g) {
return $f($g($x));
};
}
$addOne = fn($x) => $x + 1;
$double = fn($x) => $x * 2;
$addOneThenDouble = compose($double, $addOne);
echo $addOneThenDouble(5);
4.3 柯里化 #
php
<?php
function curry(callable $fn, ...$args): callable
{
return function(...$moreArgs) use ($fn, $args) {
$allArgs = array_merge($args, $moreArgs);
$reflection = new ReflectionFunction($fn);
if (count($allArgs) >= $reflection->getNumberOfParameters()) {
return $fn(...$allArgs);
}
return curry($fn, ...$allArgs);
};
}
function add($a, $b, $c) {
return $a + $b + $c;
}
$curriedAdd = curry('add');
echo $curriedAdd(1)(2)(3);
五、Closure类 #
5.1 Closure对象 #
php
<?php
$greet = function(string $name): string {
return "Hello, $name!";
};
var_dump($greet instanceof Closure);
5.2 bindTo #
php
<?php
class Person
{
private string $name = 'John';
}
$getPrivate = function() {
return $this->name;
};
$bound = $getPrivate->bindTo(new Person(), Person::class);
echo $bound();
5.3 call #
php
<?php
class Person
{
private string $name = 'John';
}
$getPrivate = function() {
return $this->name;
};
echo $getPrivate->call(new Person());
5.4 fromCallable #
php
<?php
function greet(string $name): string
{
return "Hello, $name!";
}
$closure = Closure::fromCallable('greet');
echo $closure("John");
六、实际应用 #
6.1 路由处理 #
php
<?php
$routes = [];
function get(string $path, callable $handler): void
{
global $routes;
$routes['GET'][$path] = $handler;
}
get('/users', function() {
return json_encode(['users' => []]);
});
get('/users/{id}', function(int $id) {
return json_encode(['user' => ['id' => $id]]);
});
6.2 中间件 #
php
<?php
function logger(callable $next): callable
{
return function($request) use ($next) {
echo "Request: {$request['path']}\n";
$response = $next($request);
echo "Response: $response\n";
return $response;
};
}
function auth(callable $next): callable
{
return function($request) use ($next) {
if (!isset($request['user'])) {
return 'Unauthorized';
}
return $next($request);
};
}
$handler = function($request) {
return 'Hello, ' . $request['user'];
};
$handler = logger($handler);
$handler = auth($handler);
6.3 事件处理 #
php
<?php
class EventEmitter
{
private array $listeners = [];
public function on(string $event, callable $listener): void
{
$this->listeners[$event][] = $listener;
}
public function emit(string $event, mixed $data = null): void
{
foreach ($this->listeners[$event] ?? [] as $listener) {
$listener($data);
}
}
}
$emitter = new EventEmitter();
$emitter->on('user.created', function($user) {
echo "User created: {$user['name']}\n";
});
$emitter->emit('user.created', ['name' => 'John']);
6.4 延迟执行 #
php
<?php
function defer(callable $callback): callable
{
return $callback;
}
$cleanup = defer(function() {
echo "Cleanup executed\n";
});
register_shutdown_function($cleanup);
七、最佳实践 #
7.1 使用类型声明 #
php
<?php
$process = function(array $data): array {
return array_map('strtoupper', $data);
};
7.2 避免过度使用闭包 #
php
<?php
$users = array_filter($users, fn($u) => $u->isActive());
function filterActiveUsers(array $users): array
{
return array_filter($users, fn($u) => $u->isActive());
}
7.3 使用箭头函数简化 #
php
<?php
$squared = array_map(function($n) {
return $n ** 2;
}, $numbers);
$squared = array_map(fn($n) => $n ** 2, $numbers);
八、总结 #
本章学习了:
- 匿名函数基础
- 闭包与use关键字
- 回调函数
- 高阶函数
- Closure类
- 实际应用
下一章将学习箭头函数。
最后更新:2026-03-26