2009-08-28 12 views
11

Digamos que tengo una clase PHP llamada Color, su constructor acepta varios params.¿Cómo usar phpDoc con métodos sobrecargados?

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

¿Cómo debo usar phpDoc para crear documentación API para el constructor y otros métodos como este?

¿Cómo se usa phpDoc con métodos sobrecargados?

class Color { 

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

} 

Respuesta

4

Dado que permite argumentos de longitud variable, hay dos formas de hacerlo.

Simplemente enumeraría los argumentos permitidos son parámetros.

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

O simplemente le daré una explicación con algunos ejemplos.

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

Otra alternativa, ya que sólo uno de los ejemplos tiene más de un argumento, sería simplemente definir los argumentos en la firma del método que hace el último 2 opcional. De esta manera:

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

voy a utilizar la segunda solución, un parámetro con la descripción (que es de uno a tres parametros y varios formatos) y algunas etiquetas @see a ejemplos. –

+2

Esto es antiguo, pero solo para ofrecer una alternativa de referencia, también podría decir '@param mixed $ args ... Variable number of arguments que representa blah blah' –

1

Sé de ninguna manera elegante de hacer esto con phpDoc. El formato phpDoc comment/api se basa en el formato Javadoc. Javadoc no tiene una función establecida para admitir esto porque en java, si desea que un método tenga un número variable de argumentos, vuelve a declarar el prototipo del método para cada variación.

public double foo() { 
} 

public double foo(double my_param) {   
} 

Por lo tanto, mi preferencia es el rendimiento de hacer algo como

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

pero esto puede no jugar bien con las diversas herramientas de auto-documentación.

De acuerdo con la forma de Hoyle para lograr esto se puede encontrar en el phpDoc site.

15

Simplemente mi punto de vista, pero no debe tener múltiples constructores en primer lugar - su constructor estará lleno de if/else-ladders, lo cual realmente no es una buena idea, especialmente para algo ligero como una representación de un Color.

Le recomiendo a usted a intentar algo como esto en su lugar:

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) { ... } 

    ... 
} 

Ahora, en el código de consumo, en lugar de llamadas al constructor un tanto misteriosos y ambiguos como éstas:

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

En su lugar puede tener código de consumidor más legible y semántico, como este:

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

Esto probablemente tenga más sentido para alguien que lea el código del consumidor, elimina la lógica requerida para hacer que el constructor ambiguo funcione, y como una bonificación (si está usando un IDE como PhpStorm) puede hacer pasar todas sus inspecciones. Si está ejecutando un generador de documentación, esto también asegura que todas las opciones estén documentadas individualmente, en lugar de agruparse en una descripción verbal.

Tenga en cuenta que he declarado el constructor protected - esta es una preferencia personal, pero si voy a tener varios métodos de fábrica estáticos, prefiero verlos constantemente en el código del consumidor, en lugar de ver Color::fromRGB(...) y otros veces new Color(...).

+0

Tiene razón. La solución con métodos de fábrica estáticos da como resultado un código mucho más claro. –

+2

Esta respuesta merece mucho más prestigio ya que promueve mejores prácticas de programación. – kwah

+0

Dicho esto, me doy cuenta de que no responde estrictamente a la pregunta original (bastante antigua). Personalmente, lo veo como explicando cómo usar un destornillador para clavar un clavo diciendo "¿por qué no usar un martillo?". – kwah

6

Creo que es mejor utilizar la anotación @method para la clase/interfaz, que declara los métodos de sobrecarga. Esta pregunta es interesante para mí también.

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

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

+0

Yo personalmente estoy trabajando de la misma manera y prefiero usar su enfoque. Está claro, el trabajo útil e intellisense realmente bien. Utilizo el método __Call para hacer coincidir los parámetros correctos y llamar a la función privada o anular para completar mi lógica. Howevere php developer debe tener cuidado de mejorar la sobrecarga para proporcionar una forma más robusta de utilizar este tipo de implementación que es realmente útil. En .NET (de donde vengo) es una práctica común sobrecargar un método/función y es una cosa muy poderosa. – makemoney2010

Cuestiones relacionadas