Как использовать phpDoc с перегруженными методами?

Скажем, у меня есть класс PHP под названием Color, он конструктор принимает различные параметры.

// 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

Поскольку вы разрешаете аргументы переменной длины, я бы это сделал двумя способами.

Я бы просто перечислил разрешенные аргументы как параметры.

/**
 * @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) {}

Ответ 2

Просто моя точка зрения, но у вас не должно быть нескольких конструкторов в первую очередь - ваш конструктор будет заполнен if/else-ladders, что действительно не очень хорошая идея, особенно для чего-то легкого, как представление цвета.

Я настоятельно рекомендую вам попробовать что-то вроде этого:

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

Это, вероятно, имеет смысл для кого-то, читающего потребительский код, он устраняет логику, необходимую для работы двусмысленного конструктора, и в качестве бонуса (если вы используете IDE, например PhpStorm), вы можете пройти все ваши проверки, Если вы используете генератор документации, это также гарантирует, что все параметры документированы индивидуально, а не объединены в словесное описание.

Обратите внимание, что я объявил конструктор protected - это личное предпочтение, но если у меня будет несколько статических factory -методов, я предпочитаю видеть те, которые последовательно используются в потребительском коде, а не иногда видя Color::fromRGB(...) и другие времена new Color(...).

Ответ 3

Я думаю, что лучше использовать аннотацию @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

Ответ 4

Я не знаю, какой элегантный способ сделать это с помощью phpDoc. Форматирование phpDoc comment/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.