繁体   English   中英

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

[英]How can I use PHPDoc to type-hint the parameters of a Callable?

我有一个接受回调作为参数的方法。 我想为回调提供一个参数签名作为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);
  }
}

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

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

当我写下面的代码时:

$foo = new Foo();
$foo->bar(function(

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

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

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;
    }
});

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

目前在PhpStorm中是不可能的。 我甚至无法想到通过其他方式做出相对相同的其他解决方案。

我通过使用callable在类中定义static function克服这个问题。 该函数有自己的doc-block,我只是在使用PHPDoc的@see标记要求我的callable的方法中引用它。

class Foo
{
    /**
     * Description of the "bar" callable. Used by {@see baz()}.
     *
     * @param int $index A 1-based integer.
     * @param string $name A non-empty string.
     * @return bool
     * @see baz()
     * @throws \Exception This is a prototype; not meant to be called directly.
     */
    public static barCallable($index, $name)
    {
        throw new \Exception("barCallable prototype called");
    }

    /**
     * Description of the baz() method, using a {@see barCallable()}.
     *
     * @param callable $bar A non-null {@see barCallable()}.
     * @see barCallable()
     */
    public function baz(callable $bar)
    {
        // ...
        call_user_func($bar, 1, true);
        // ...
    }
}

这在PhpStorm 10中运行良好。 快速文档允许轻松地从方法文档导航到原型文档。

我让我的原型函数抛出一个异常,以明确它并不意味着被调用。 我可以使用protectedprivate范围,但是PHPDoc并不总是选择doc-block来生成文档。

不幸的是,PhpStorm无法跟踪回调的使用情况。 在使用需要回调的方法时,它不提供参数信息 ,但回调至少是正式记录的。

此方法还具有在运行时从原型的反射验证回调定义的额外好处。

PHPDoc现在允许callable类型提示: @param callable $var_name

class MyClass {
  /**
   * @param callable $func
   */
  public static function callme($func) {
    $func();
  }
}

MyClass::callme([MyClass::class, 'callme']); // Do not run this line! Test only!

PhpStorm(2019)在我输入第一个'后,将'callme'建议为自动完成项,表示它正确理解了提示。 没有暗示它说“没有建议”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM