PHP闭包函数怎么用

wen PHP项目 2

本文目录导读:

PHP闭包函数怎么用

  1. 基本语法
  2. use 关键字使用外部变量
  3. 作为回调函数使用
  4. 作为函数参数传递
  5. 返回闭包(工厂模式)
  6. 绑定 $this(闭包绑定)
  7. 箭头函数(PHP 7.4+)
  8. 实际应用示例
  9. 闭包的常用方法
  10. 注意事项

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中的主要用途:

  • 回调函数
  • 函数式编程
  • 事件处理
  • 依赖注入
  • 状态封装
  • 延迟计算

掌握闭包可以让你写出更灵活、更简洁的代码,在面向对象和函数式编程之间架起桥梁。

抱歉,评论功能暂时关闭!