ZetCode

PHP 可调用类型

最后修改于 2025 年 4 月 16 日

PHP 的 callable 类型表示任何可以被调用为函数的东西。它用于将函数作为参数传递或将其存储在变量中。可调用类型实现了诸如回调函数之类的强大编程模式。

基本定义

PHP 中的 callable 是一种可以像函数一样被调用的类型。有几种东西符合可调用类型:作为字符串的函数名、对象方法、静态类方法、闭包以及实现 __invoke() 的对象。

is_callable 函数用于检查变量是否可调用。可调用类型通常用作 array_mapusort 等函数的参数(回调参数)。

可调用语法各不相同:函数使用 'functionName',方法使用 [$object, 'method'],匿名函数使用 function() {}。类型提示可确保参数是可调用的。

基本函数回调

此示例展示了将常规函数作为可调用类型传递。

basic_callable.php
<?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。可调用类型提示确保只接受有效的回调。函数名以字符串形式传递。

类方法回调

此示例演示了将对象方法用作可调用类型。

method_callable.php
<?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 函数也适用于不同的可调用类型。

静态方法回调

此示例展示了将静态类方法用作可调用类型。

static_callable.php
<?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 语法或包含类名的数组来调用静态方法。这两种形式都是有效的可调用类型。静态可调用类型不需要实例化对象。

闭包作为可调用类型

此示例演示了将匿名函数(闭包)用作可调用类型。

closure_callable.php
<?php

declare(strict_types=1);

$greeting = function(string $name): void {
    echo "Hi there, $name!";
};

process($greeting, 'Dave');

闭包是可赋值给变量的匿名函数。它们自然是可调用的,并且可以使用 use 关键字访问父作用域的变量。闭包常用于简短的回调逻辑。

可调用对象

此示例展示了实现 __invoke() 的对象被用作可调用类型。

invokable_callable.php
<?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 魔术方法的对象可以像函数一样被调用。当传递给期望可调用类型的函数时,对象本身就足够了。这种模式对于有状态的可调用类型很有用。

可调用类型验证

此示例演示了在使用可调用类型之前对其进行验证。

validate_callable.php
<?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 的数组函数一起使用。

array_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 中可调用类型的一个常见用例。

最佳实践

来源

PHP 可调用类型文档

本教程涵盖了 PHP 可调用类型,并提供了实际示例,展示了在 PHP 应用程序中创建和使用可调用类型的各种方法。

作者

我叫 Jan Bodnar,是一名热情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。至今,我已撰写了 1400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出 所有 PHP 教程