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

时间:2012-11-30 16:30:11

标签: php phpstorm phpdoc

我有一个接受回调作为参数的方法。我想为回调提供一个参数签名作为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支持,是否有推荐/标准的方法来记录它?

4 个答案:

答案 0 :(得分:6)

PHP 7 +:

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

for $x in xdmp:directory("/documents/","1")/id/tbl_Keysight_Input
where count($x/preceding-sibling::tbl_Keysight_Input[fn:deep-equal(.,$x)]) = 0
return $x

如果您正在使用PhpStorm,它甚至会自动生成/** * 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; } }); - 方法的签名&身体在匿名课堂内。

答案 1 :(得分:3)

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

答案 2 :(得分:1)

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

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无法跟踪回调的使用情况。在使用需要回调的方法时,它不提供参数信息,但回调至少是正式记录的。

此方法还具有在运行时从原型的reflection验证回调定义的附加好处。

答案 3 :(得分:0)

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'后建议将'作为自动完成项,表明它正确理解了提示。没有提示,它说“没有建议”。