Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/239.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用PHPDoc键入可调用函数的提示参数?_Php_Phpstorm_Phpdoc - Fatal编程技术网

如何使用PHPDoc键入可调用函数的提示参数?

如何使用PHPDoc键入可调用函数的提示参数?,php,phpstorm,phpdoc,Php,Phpstorm,Phpdoc,我有一个接受回调作为参数的方法。我想为回调提供一个参数签名,作为PHPDoc,这样我的IDE(PHPStorm)就可以为传递给我的方法的函数生成有效的类型提示,或者至少有人查看代码可以确定他们打算提供的回调的签名 例如: class-Foo{ 公共$项目=[]; /** *@param可调用( *@param ArrayObject$items bar()将返回的项目列表 *)$baz用于接收项目的回调 **/ 公共功能栏(可调用$baz){ $items=新阵列对象($this->items)

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

例如:

class-Foo{
公共$项目=[];
/**
*@param可调用(
*@param ArrayObject$items bar()将返回的项目列表
*)$baz用于接收项目的回调
**/
公共功能栏(可调用$baz){
$items=新阵列对象($this->items);
$baz(项目);
}
}
方法
bar
有一个参数,
$baz
,它是一个回调函数。作为参数传递给
bar()
的任何函数必须接受
ArrayObject
作为其唯一参数

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

当我编写以下代码时:

$foo=newfoo();
$foo->bar(函数(
…然后,我将收到一个参数列表,该列表正确地提示此函数调用所接受参数的类型(
ArrayObject


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

目前在PHPStorm中还不可能。我甚至想不出其他通过其他方式做相对相同的解决方案。

我通过定义
静态函数克服了这个问题使用
可调用的
在类中调用
。该函数有自己的doc块,我只是在需要使用PHPDoc的
可调用的方法中引用它。请参见
标记

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中运行良好。快速文档允许轻松地从方法文档导航到原型文档

我让我的原型函数抛出一个异常,以明确它不应该被调用。我可以使用
受保护的
私有的
范围,但是PHPDoc不会总是选择文档块来生成文档

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


这种方法还有一个额外的好处,就是在运行时验证原型的回调定义。

PHP7+:

将可调用接口与匿名类结合使用就可以做到这一点。这并不十分方便,而且会导致类使用者的代码过于复杂,但就静态代码分析而言,这是目前最好的解决方案


如果您使用的是PhpStorm,它甚至会在匿名类中自动生成
\u invoke
-方法的签名和正文。

PHPDoc现在允许
可调用
类型提示:
@param callable$var\u name

class-MyClass{
/**
*@param可调用$func
*/
公共静态函数callme($func){
$func();
}
}
MyClass::callme([MyClass::class,'callme']);//不要运行此行!仅测试!

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

NetBeans似乎可以应付(如果我理解您的意思的话):目前正在为即将到来的“官员"PHP-DOC的规范,以及。这个RFC本可以让它变得更好,但它以22:6被投了反对票。我不知道为什么。恕我直言,这并没有回答OP的问题。他们的问题是他们如何在可调用文件本身中指定各种参数。
我想为回调提供一个*参数签名*,名为PHPDoc
/**
 * 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;
    }
});