是否有数组到可调用函数?

Is there an array-to-callable function?

设置

SomeClass 中有 f2member 接受两个整数参数并产生其和。测试通过表明调用实际有效并检索到预期结果。这是使用两个参数 11 返回 2 调用 $g

重要提示:这仅适用于 php 5.4.11 及更高版本 compatibility check

class SomeClass extends PHPUnit_Framework_TestCase
{   
    function f2member($a,$b)
    {
        return $a + $b;
    }

    /**
     * @test
     */
    public function test()
    {
        $g = array($this,'f2member');
        $this->assertEquals(2, $g(1,1)); // squiggle line under $g
    }
}

问题

但是,这会在 phpStorm 中对每个方法调用产生警告,并在 $g:

下产生一条波浪线

Function name must be callable - string, Closure or class implementing __invoke, currently array

我很清楚警告的来源,现在我正在寻找避免这些警告的方法。 一个要求是,我不想改变调用函数的风格。我不想做的另一件事是停用此警告。 我宁愿在它周围包裹一些东西,它为 类型系统 提供必要的信息。

尝试

我已经遇到了几种删除警告的解决方案。一种是定义一个用户定义的函数,它只记录所需的目标类型。

/**
 * @param array $arr
 *
 * @return callable
 */
function callable_for($arr)
{
    return $arr;
}

这个 returns 一个数组,但也明确地告诉类型系统 callable_for 函数的结果。有了这个类型注释 phpStorm 现在不再抱怨这个警告,尽管它仍然是 returns 一个数组。

$g = callable_for(array($this,'f2member'));

问题

难道没有像我在 php 中的 callable_for 这样开箱即用的东西来实现这个目标吗?如果答案是否定的,那么 我正在寻找我们能找到的最简洁的解决方案。

我已经尝试查看 SO、php.net 和 google。也许,我只是搜索了错误的单词组合,这里只是两个示例:

大图

为了防止出现嫌疑人,这是 X/Y problem: I have another function taking a callable as a parameter. With closures it is very natural to define something, which can be invoked later on. However, how do i define a callable for a member or a static method without wrapping it in another delegation Closure? The array notation allows to be used to uniformly pass: closures or static/member method handles to my later function. I am now trying to find a concise solution to this, which comes close to this

因此,另一个进步可能是修改 callable_for 以接受两个参数并包装两个职责;创建数组并记录目标 return 类型。

/**
 * @param mixed $context
 * @param string $method
 *
 * @return callable
 */
function callable_for($context, $method)
{
    return array($context, $method);
}

使用此实现将 $g 声明的简洁性提高到可接受的水平。

$g = callable_for($this,'f2member');

这个函数仍然return是一个数组,但是类型系统可以使用给定的信息正确地处理这个数组以进行动态方法调用。

这个问题是四年前提出的,但经过一些研究,我发现了 Closure::fromCallable 方法:https://www.php.net/manual/de/closure.fromcallable.php