PHP - 参数 #3 ($modifier) 必须是可调用类型,给定字符串

问题描述 投票:0回答:1

我正在尝试将可调用/闭包存储为类字段/属性。

我最初的尝试是这样的:

class MyClass
{
    protected callable $modifier;

    public function __construct(callable $modifier) {
        $this->modifier = $modifier;
    }
}

class SomeOtherClass
{
    public function func()
    {
        return ['a' => 'b'];
    }
}

$test = new MyClass('SomeOtherClass::func');

这返回了一个错误:

$修饰符不能具有可调用类型

然后,在网上阅读this后,我尝试了这个但没有成功:

class MyClass
{
    protected Closure $modifier;

    public function __construct(callable $modifier) {
        $this->modifier = Closure::fromCallable($modifier);
    }
}

class SomeOtherClass
{
    public function func()
    {
        return ['a' => 'b'];
    }
}

$test = new MyClass('SomeOtherClass::func');

最后一个返回此错误:

参数 #1 ($modifier) 必须是可调用类型,给定字符串

然后我尝试了这个:

class MyClass
{
    protected Closure $modifier;

    public function __construct(callable $modifier) {
        $this->modifier = Closure::fromCallable($modifier);
    }
}

class SomeOtherClass
{
    public function func()
    {
        return ['a' => 'b'];
    }
}

$test = new MyClass(['SomeOtherClass', 'func']); // <----- changed string to an array

这会返回此错误:

参数 #1 ($modifier) 必须是可调用类型,给定数组

这可以用 PHP 实现吗?

php callback
1个回答
0
投票

假设您使用的是 PHP 8.1 或更高版本(在撰写本文时,这是 PHP 仅受支持的版本),那么您可以使用 first-class callable 语法,如 8.1 中所述。

为此,您可以使用函数名称,然后使用

(...)
作为传入的参数。

就您而言,您可以这样做:

class MyClass
{
    protected Closure $modifier;

    public function __construct(callable $modifier) {
        $this->modifier = Closure::fromCallable($modifier);
    }

    public function runClosure()
    {
        var_dump(($this->modifier)());
    }
}

class SomeOtherClass
{
    public function func()
    {
        return ['a' => 'b'];
    }
}

$soc = new SomeOtherClass();
$test = new MyClass($soc->func(...));
$test->runClosure();

现场演示:https://3v4l.org/iEAiM

注意上面的代码假设您想要使用

func()
作为实例方法。如果它应该是静态的,您需要进行一些小的调整:

class MyClass
{
    protected Closure $modifier;

    public function __construct(callable $modifier) {
        $this->modifier = Closure::fromCallable($modifier);
    }
    
    public function runClosure()
    {
        var_dump(($this->modifier)());
    }
}

class SomeOtherClass
{
    public static function func()
    {
        return ['a' => 'b'];
    }
}

$test = new MyClass(SomeOtherClass::func(...));
$test->runClosure();
© www.soinside.com 2019 - 2024. All rights reserved.