传递给函数的参数必须是可调用的,给定数组

Posted

技术标签:

【中文标题】传递给函数的参数必须是可调用的,给定数组【英文标题】:Argument passed to function must be callable, array given 【发布时间】:2017-08-27 12:03:31 【问题描述】:

我正在尝试对集合中的每个元素运行一个方法。它是驻留在同一类中的对象方法:

protected function doSomething()

    $discoveries = $this->findSomething();
    $discoveries->each([$this, 'doSomethingElse']);


protected function doSomethingElse($element)

    $element->bar();
    // And some more

如果我在调用Collection::each 之前检查is_callable([$this, 'doSomethingElse']),它会返回true,所以显然它是可调用的。然而,调用本身会引发异常:

类型错误:传递给 Illuminate\Support\Collection::each() 的参数 1 必须 可调用,给定数组,在第 46 行的 ---.php 中调用

可以找到尝试调用的方法here。

我只是通过传递一个本身只是调用该函数的闭包来绕过它,但这绝对是一个更清洁的解决方案,我无法找出它抛出错误的原因。

【问题讨论】:

@bxN5 它不应该是一个函数,它应该是一个callableis_callable 返回 true,所以我假设它在传递给期望 callable 的函数时有效。 请尝试将doSomethingElse() 声明为public。恕我直言,我认为 each() 是在 collection 类的上下文中调用的,该类对其他类中的受保护函数没有可见性。 我怀疑findSomethingdoSomethingElse 正在引发异常。以我有限的经验,这个错误消息是一个红鲱鱼。 可能是这样,虽然我解决的方法不同,不记得我使用它的确切位置,因此我无法验证。 【参考方案1】:

将回调方法的可见性更改为公开。

protected function doSomething()

    $discoveries = $this->findSomething();
    $discoveries->each([$this, 'doSomethingElse']);


public function doSomethingElse($element)

    $element->bar();
    // And some more

【讨论】:

这个在其他cmet中已经推荐过多次了,还是不行。【参考方案2】:

从 PHP 7.1 开始,您可以让您的函数受到保护。现在你可以写:

protected function doSomething()

    $discoveries = $this->findSomething();
    $discoveries->each(\Closure::fromCallable([$this, 'doSomethingElse']));


protected function doSomethingElse($element)

    $element->bar();
    // And some more

Source

【讨论】:

【参考方案3】:

PHP >= 5.4

我无法重现您的错误,但我猜您应该在回调数组中使用 $discoveries 而不是 $this,如下所示:

$discoveries->each([$discoveries, 'doSomethingElse']);

即使$discoveries$this 属于同一类,因此可以访问彼此的受保护和私有方法,但类型提示功能可能不会检查回调数组中的对象是否与当前班级。但是,is_callable() 方法会检查这一点,这可以解释为什么当您从 each() 方法内部调用它时它会返回 true。

PHP

没有名为callable 的类型,因此当您将其用作类型提示时,它指的是一个名为callable。 See this answer.

【讨论】:

我没有指定我使用的 Laravel 版本,但它需要 PHP 5.6+,所以

以上是关于传递给函数的参数必须是可调用的,给定数组的主要内容,如果未能解决你的问题,请参考以下文章

传递给 Illuminate\Database\Eloquent\Model::__construct() 的参数 1 必须是数组类型,给定对象,

传递给 Illuminate\Database\Grammar::parameterize() 的 Laravel 工厂参数 1 必须是数组类型,给定字符串

传递给 myFunction() 的参数 1 必须是字符串的实例,给定的字符串,调用

lambda表达式

C语言中,数组名作为函数参数,属于啥传递,为啥?

Doctrine - 传递给 __construct 的参数必须是一个数组