如何使用带有重载方法的phpDoc?

Posted

技术标签:

【中文标题】如何使用带有重载方法的phpDoc?【英文标题】:How to use phpDoc with overloaded methods? 【发布时间】:2010-11-23 20:18:07 【问题描述】:

假设我有一个名为 Colorphp 类,它的构造函数接受各种参数。

// hex color
$myColor = new Color('#FF008C');

// rgb channels
$myColor = new Color(253,15,82);

// array of rgb channels
$myColor = new Color(array(253,15,82));

// X11 color name
$myColor = new Color('lightGreen');

我应该如何使用 phpDoc 为构造函数和其他类似方法创建 API 文档?

如何使用重载方法的phpDoc?

class Color 

    /**
     * Constructor
     * what should be here?
     */
    public function __construct() 
        /* CODE */
    


【问题讨论】:

【参考方案1】:

只是我的观点,但首先你不应该有多个构造函数 - 你的构造函数将充满 if/else-ladders,这真的不是一个好主意,特别是对于像 a 这样的轻量级的东西颜色的表示。

我强烈建议您尝试这样的方法:

class Color

    protected function __construct($r, $g, $b)
     ... 

    public static function fromHex($hex) 
        return new Color(...);
    

    public static function fromRGB($r, $g, $b)  ... 

    public static function fromArray(array $rgb)  ... 

    ...

现在,在消费者代码中,而不是像这样有点神秘和模棱两可的构造函数调用:

$a = new Color(0,0,0);
$b = new Color('#000000');

相反,您可以拥有更清晰和语义更清晰的消费者代码,如下所示:

$a = Color::fromRGB(0,0,0);
$b = Color::fromHex('#000000');

这对于阅读消费者代码的人来说可能更有意义,它消除了使模棱两可的构造函数工作所需的逻辑,并且作为奖励(如果您使用的是 PhpStorm 之类的 IDE),您可以通过所有检查.如果您正在运行文档生成器,这还可以确保所有选项都单独记录,而不是集中在口头描述中。

请注意,我声明了构造函数 protected - 这是个人偏好,但如果我要拥有多个静态工厂方法,我更愿意看到在消费者代码中始终使用的那些,而不是有时看到 @987654325 @ 和其他时间new Color(...)

【讨论】:

你是对的。使用静态工厂方法的解决方案会产生更清晰的代码。 这个答案值得更多的赞誉,因为它促进了更好的编程实践。 也就是说,我意识到它并没有严格回答原始(相当老的)问题。就我个人而言,我认为这就像通过说“为什么不使用锤子?”来解释如何使用螺丝刀敲钉子。 我是说“螺丝刀是敲钉子的错误工具”——即使这不是你想要的答案,它也是正确的答案,除非你一心想弯曲你的指甲,用手指敲打自己。【参考方案2】:

我认为对类/接口使用@method 注释更好,它声明了重载方法。这个问题对我来说也很有趣。

 /**
  * @method void setValue(int $value)
  * @method void setValue(string $value)
  * @method void setValue(string $value, int $startFrom)
  */
 class Example
 
     public function setValue($arg1, $arg2)
     
        // ...
     
 

见http://phpdoc.org/docs/latest/references/phpdoc/tags/method.html

【讨论】:

我个人在做同样的事情,我更喜欢使用你的方法。它很清晰,有用且智能感知工作非常好。我使用 __Call 方法来匹配正确的参数并调用私有函数或 void 以完成我的逻辑。然而,php 开发人员应该注意改进重载,以便提供一种更健壮的方式来使用这种非常有用的实现。在 .NET(我来自哪里)中,重载方法/函数是一种常见的做法,它是一个非常强大的东西。 我最近试过这个,我的 IDE (PhpStorm / IntelliJ IDEA) 不喜欢它;它在重复声明上显示警告,未能正确突出语法并拒绝稍后建议重复方法。【参考方案3】:

因为您允许可变长度参数,所以我有两种方法可以做到这一点。

我会简单地列出允许的参数是参数。

/**
 * @param mixed $arg1 ... description
 * @param mixed $arg2 ... description
 * @param mixed $arg3 ... description
 */
 public function __construct() 

或者我只是用一些例子来解释一下。

/**
 * Explanation of different expected argument combinations.
 */
public function __construct() 

另一种选择,因为只有一个示例具有多个参数,因此只需在方法签名中定义参数,使最后 2 个可选。像这样:

/**
 * @param mixed $arg1 ...
 * @param int $arg2 ...
 * @param int $arg3 ...
 */
public function __construct($arg1, $arg2 = null, $arg3 = null) 

【讨论】:

我将使用第二种解决方案,一个带有描述的参数(它是一到三个参数和各种格式)和一些 @see 示例标签。 这是旧的,但只是为了提供一个可供参考的替代方案——你也可以说@param mixed $args ... Variable number of arguments representing blah blah【参考方案4】:

我知道用 phpDoc 没有优雅的方法来做到这一点。 phpDoc 注释/api 格式基于Javadoc 格式。 Javadoc 没有支持这一点的功能集,因为在 java 中,如果您希望方法具有可变数量的参数,您需要为每个变体重新声明方法原型。

public double foo() 


public double foo(double my_param)         

所以,我的性能偏好是做类似的事情

/**
 * My General description
 * 
 * Here explain what each argument combination can do
 * @param mixed $arg1 can be array, string, hex as string, or int 
 * @param int $arg2 if arg1 is int, then this is etc, otherwise optional 
 * @param int $arg3 if ar1 is int, then this is etc, otherwise optional
 */

但这可能不适用于各种自动文档工具。

可以在phpDoc site 找到根据 Hoyle 的方法来完成此操作。

【讨论】:

以上是关于如何使用带有重载方法的phpDoc?的主要内容,如果未能解决你的问题,请参考以下文章

什么是 PHPDoc Eclipse 多类型:以及如何使用它?

我应该如何 PHPDoc 回调?

如何在 ASP.NET CORE 3.0 中配置路由以使用带有 [FromQuery] 参数的重载 [HttpGet] 方法?

如何使用 PHP 解析 phpDoc 样式的注释块?

如何将 PHP 代码块放入 PHPDoc DocBlock

带有箭头函数的打字稿重载方法