PHP 可调用类型
最后修改于 2025 年 4 月 16 日
PHP 的 callable 类型表示任何可以被调用为函数的东西。它用于将函数作为参数传递或将其存储在变量中。可调用类型实现了诸如回调函数之类的强大编程模式。
基本定义
PHP 中的 callable 是一种可以像函数一样被调用的类型。有几种东西符合可调用类型:作为字符串的函数名、对象方法、静态类方法、闭包以及实现 __invoke() 的对象。
is_callable 函数用于检查变量是否可调用。可调用类型通常用作 array_map 或 usort 等函数的参数(回调参数)。
可调用语法各不相同:函数使用 'functionName',方法使用 [$object, 'method'],匿名函数使用 function() {}。类型提示可确保参数是可调用的。
基本函数回调
此示例展示了将常规函数作为可调用类型传递。
<?php
declare(strict_types=1);
function greet(string $name): void {
echo "Hello, $name!";
}
function process(callable $callback, string $name): void {
$callback($name);
}
process('greet', 'John');
该代码定义了一个 greet 函数,并将其作为可调用类型传递给 process。可调用类型提示确保只接受有效的回调。函数名以字符串形式传递。
类方法回调
此示例演示了将对象方法用作可调用类型。
<?php
declare(strict_types=1);
class Greeter {
public function greet(string $name): void {
echo "Hello, $name from Greeter!";
}
}
$greeter = new Greeter();
process([$greeter, 'greet'], 'Alice');
该代码创建了一个带有 greet 方法的 Greeter 类。该方法使用数组语法作为可调用类型传递:[object, methodName]。第一个示例中的 process 函数也适用于不同的可调用类型。
静态方法回调
此示例展示了将静态类方法用作可调用类型。
<?php
declare(strict_types=1);
class StaticGreeter {
public static function greet(string $name): void {
echo "Hello, $name from static method!";
}
}
process('StaticGreeter::greet', 'Bob');
// Or alternatively:
process([StaticGreeter::class, 'greet'], 'Charlie');
可以使用 ClassName::methodName 语法或包含类名的数组来调用静态方法。这两种形式都是有效的可调用类型。静态可调用类型不需要实例化对象。
闭包作为可调用类型
此示例演示了将匿名函数(闭包)用作可调用类型。
<?php
declare(strict_types=1);
$greeting = function(string $name): void {
echo "Hi there, $name!";
};
process($greeting, 'Dave');
闭包是可赋值给变量的匿名函数。它们自然是可调用的,并且可以使用 use 关键字访问父作用域的变量。闭包常用于简短的回调逻辑。
可调用对象
此示例展示了实现 __invoke() 的对象被用作可调用类型。
<?php
declare(strict_types=1);
class InvokableGreeter {
public function __invoke(string $name): void {
echo "Greetings, $name from invokable!";
}
}
$invokable = new InvokableGreeter();
process($invokable, 'Eve');
实现 __invoke 魔术方法的对象可以像函数一样被调用。当传递给期望可调用类型的函数时,对象本身就足够了。这种模式对于有状态的可调用类型很有用。
可调用类型验证
此示例演示了在使用可调用类型之前对其进行验证。
<?php
declare(strict_types=1);
function safeProcess(callable $callback, string $name): void {
if (!is_callable($callback)) {
throw new InvalidArgumentException('Provided callback is not callable');
}
$callback($name);
}
try {
safeProcess('nonexistent_function', 'Frank');
} catch (InvalidArgumentException $e) {
echo "Error: " . $e->getMessage();
}
该代码在调用回调之前检查它是否实际上是可调用的。is_callable 验证回调是否可以执行。这可以防止在处理动态可调用引用时出现错误。
数组函数中的可调用类型
此示例展示了将可调用类型与 PHP 的数组函数一起使用。
<?php
declare(strict_types=1);
$numbers = [1, 2, 3, 4, 5];
// Using closure
$squared = array_map(function($n) { return $n * $n; }, $numbers);
// Using named function
function cube($n) { return $n * $n * $n; }
$cubed = array_map('cube', $numbers);
print_r($squared);
print_r($cubed);
像 array_map 这样的 PHP 数组函数接受可调用类型来转换数组元素。命名函数和闭包都可以工作。这是 PHP 中可调用类型的一个常见用例。
最佳实践
- 类型提示:为回调参数使用可调用类型提示。
- 验证:在需要时使用 is_callable() 验证可调用类型。
- 清晰性:对于复杂的回调,优先使用命名函数。
- 闭包:对于简单的一次性回调,使用闭包。
- 性能:静态方法比对象方法快。
来源
本教程涵盖了 PHP 可调用类型,并提供了实际示例,展示了在 PHP 应用程序中创建和使用可调用类型的各种方法。
作者
列出 所有 PHP 教程。