匿名函数 #

一、匿名函数基础 #

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