如何使用PHPDoc键入提示Callable的参数?

rin*_*ter 20 php phpdoc phpstorm

我有一个接受回调作为参数的方法.我想为回调提供一个参数签名作为PHPDoc,以便我的IDE(PHPStorm)可以为传递给我的方法的函数生成有效的类型提示,或者至少有人查看代码可以确定回调的签名我打算提供.

例如:

class Foo {
  public $items = [];
  /**
  * @param Callable(
  *   @param ArrayObject $items The list of items that bar() will return
  * ) $baz A callback to receive the items
  **/
  public function bar(Callable $baz) {
    $items = new ArrayObject($this->items);
    $baz($items);
  }
}
Run Code Online (Sandbox Code Playgroud)

该方法bar有一个参数,$baz它是一个回调函数.作为参数传递的任何函数bar()必须接受a ArrayObject作为其唯一参数.

理想情况下,应该可以包含多个参数Callable,就像任何其他方法一样.

当我写下面的代码时:

$foo = new Foo();
$foo->bar(function(
Run Code Online (Sandbox Code Playgroud)

...然后我应该收到一个参数列表,该列表正确提示ArrayObject此函数调用的可接受参数的type().

这样的事情可能吗?PHPStorm或其他IDE是否支持它?即使没有IDE支持,是否有推荐/标准的方法来记录它?

Zhu*_*ukV 11

可以使用callable\Closure输入提示。

举个例子:

/**
 * @param callable(int, string): int $callable
 *
 * @return int
 */
function some(callable $callable): int
{
    return $callable(1, 'foo-bar');
}

/**
 * @param Closure(\stdClass, array): void  $closure
 *
 * @return mixed
 */
function some2(\Closure $closure): int
{
    return $closure((object) [], []);
}
Run Code Online (Sandbox Code Playgroud)

注意:仅当您提供返回类型提示时它才有效:

/**
 * @param callable(): int $callable - Work
 * @param callable: int $callable - Don't work (missed arguments)
 * @param callable(int, int, string) - Don't work (missed return type hint)
 * @param callable(int, int, SomeClass): void - Work
 */
Run Code Online (Sandbox Code Playgroud)

PhpStorm 和静态分析器(例如phpstan )可以正确阅读此符号。


rck*_*ckd 7

PHP 7+:

使用可调用的接口与匿名类相结合将起到作用.它不是很方便,导致类消费者的代码过于复杂,但目前它是静态代码分析方面的最佳解决方案.

/**
 * Interface MyCallableInterface
 */
interface MyCallableInterface{
    /**
     * @param Bar $bar
     *
     * @return Bar
     */
    public function __invoke(Bar $bar): Bar;
}

/**
 * Class Bar
 */
class Bar{
    /**
     * @var mixed
     */
    public $data = null;
}

/**
 * Class Foo
 */
class Foo{
    /**
     * @var Bar
     */
    private $bar = null;

    /**
     * @param MyCallableInterface $fn
     *
     * @return Foo
     */
    public function fooBar(MyCallableInterface $fn): Foo{
        $this->bar = $fn(new Bar);
        return $this;
    }
}

/**
 * Usage
 */
(new Foo)->fooBar(new class implements MyCallableInterface{
    public function __invoke(Bar $bar): Bar{
        $bar->data = [1, 2, 3];
        return $bar;
    }
});
Run Code Online (Sandbox Code Playgroud)

如果您正在使用PhpStorm,它甚至会__invoke在匿名类中自动生成-Method的签名和正文.


ual*_*ker 3

目前在 PhpStorm 中还不可能。我什至想不出其他解决方案可以通过其他方式实现相对相同的效果。

  • 目前正在为即将推出的 PHP-DOC“官方”规范计划/讨论此功能,[此处](https://github.com/phpDocumentor/fig-standards/issues/19) 和 [此处](https:// /github.com/phpDocumentor/fig-standards/issues/7)。 (5认同)