107 votes

Quelle est la meilleure façon de documenter les options Array dans PHPDoc ?

Je m'efforce d'écrire une documentation lisible et facile à comprendre qui décrit la structure multi-arborescente des options Array transmises à une fonction.

Voici un exemple de structure de tableau.

$arr = [
   'fields' => [
       'title' => [
           'name'     => 'Document.title',
           'format'   => 'string',
           'readonly' => true
       ]
   ]
];

Il existe de nombreuses options possibles pour le tableau ci-dessus, mais celui-ci est utilisé comme paramètre d'une fonction qui comprend cette structure.

function doSomething(array $arr) { ... }

J'aimerais documenter la façon dont le tableau devrait être structuré dans PHPDoc, mais je ne suis pas sûr de l'approche correcte.

Voici ce que j'ai maintenant.

/**
 * Holds configuration settings for each field in a model.
 * Defining the field options
 *
 * array['fields'] array Defines the feilds to be shown by scaffolding.
 * array['fields'][fieldName] array Defines the options for a field, or just enables the field if array is not applied.
 * array['fields'][fieldName]['name'] string Overrides the field name (default is the array key)
 * array['fields'][fieldName]['model'] string (optional) Overrides the model if the field is a belongsTo assoicated value.
 * array['fields'][fieldName]['width'] string Defines the width of the field for paginate views. Examples are "100px" or "auto"
 * array['fields'][fieldName]['align'] string Alignment types for paginate views (left, right, center)
 * array['fields'][fieldName]['format'] string Formatting options for paginate fields. Options include ('currency','nice','niceShort','timeAgoInWords' or a valid Date() format)
 * array['fields'][fieldName]['title'] string Changes the field name shown in views.
 * array['fields'][fieldName]['desc'] string The description shown in edit/create views.
 * array['fields'][fieldName]['readonly'] boolean True prevents users from changing the value in edit/create forms.
 * array['fields'][fieldName]['type'] string Defines the input type used by the Form helper (example 'password')
 * array['fields'][fieldName]['options'] array Defines a list of string options for drop down lists.
 * array['fields'][fieldName]['editor'] boolean If set to True will show a WYSIWYG editor for this field.
 * array['fields'][fieldName]['default'] string The default value for create forms.
 *
 * @param array $arr (See above)
 * @return Object A new editor object.
 **/

Mon problème est que lorsque le document HTML est généré, il n'est pas très bien formaté. De plus, je ne suis pas sûr que le texte ci-dessus explique clairement la structure du tableau.

Existe-t-il une autre approche ?

18voto

jk2K Points 1920

Syntaxe Markdown pour la notation d'objets (MSON) pourrait être un meilleur choix.

exemple

/**
 * @param array $config
 *   + app (string, required) - app directory name
 *   + view (string, required) - view directory name
 *   + type (enum[string]) - site type
 *     + pc - PC version
 *     + wap - mobile version
 *     + other - other, default value
 *   + table_prefix (string) - database table prefix
 */

4voto

jgmjgm Points 36

Les tableaux en PHP sont plutôt des structs anonymes.

Pour les structures de données arbitraires, il existe un certain nombre de validateurs de schémas, mais malheureusement, ils ne sont pas largement pris en charge dans les indications de type. Peut-être que certains schémas communs ont des plugins ? Le problème est que les choses ne fonctionnent qu'à un ou quelques endroits. Vous pouvez faire fonctionner la bonne chose pour votre IDE mais lancer une analyse statique et tout peut partir en vrille.

Il faut veiller à séparer les choses afin que, dans la mesure du possible, les autres outils ne prenant pas en charge un schéma, par exemple via un plugin, l'ignorent tout simplement.

PHPDoc a tendance à être supporté partout mais est également très limité.

Il y a souvent des propositions mais il n'y a pas vraiment de bonne norme. La plupart des solutions sont non standard, peu supportées, des bidouillages partiels avec des limitations ou purement superficiels (documentation).

Il y a des implémentations spécifiques dans des endroits spécifiques mais rien de répandu et dédié à PHP lui-même. Bien que vous puissiez créer vos propres schémas en PHP, les IDE ont tendance à manquer de ponts de code décents, même ceux dont le nom contient PHP.

Vous devez définir votre structure de champ séparément. Votre structure de données externe est un pseudo code @key fields field[] plutôt que de les représenter sous forme de tableaux multidimensionnels. Sur le plan conceptuel et de la confusion, vous pouvez aller jusqu'à :

@start struct custom
@key \stdClass *
@end struct

@start struct fields
@key string hostname
@key string databaseName
@key string password
@key int port=1433
@key custom|undefined sublevel
@end struct

@start struct connection
@key fields fields
@end struct

Ou voler le C et inventer un langage...

struct connection {
    struct fields {
        string hostname;
        string databaseName;
        string password;
        int port = 1433;
        custom optional sublevel {
            stdClass *;
        };
    };
};

Vous pouvez inventer un schéma basé sur les structs pour permettre à la fois le flat et le nested. L'imbrication devrait être la valeur par défaut, les choses ne devraient être définies que pour être aussi accessibles qu'elles doivent l'être pour être réutilisées.

Une approche inhabituelle consiste à utiliser des objets. Cela n'implique pas nécessairement l'utilisation d'interfaces telles que l'accès aux tableaux. En PHP, un objet contient un tableau pour les propriétés. Il est possible de convertir un tableau en objet (sans implémentation, seulement les propriétés) et inversement.

Si vous utilisez les objets comme un tableau associatif ($array[$key] versus $object->{$key}), vous pouvez créer des objets factices pour tromper l'IDE...

final class PersonStruct {
    /** @var int */
    public $x;

    /** @var int $y */

    public int $z;
}

Parmi ces trois options, celle qui peut fonctionner ou non dépend de l'outil utilisé.

Vous pouvez alors mentir...

/** @var PersonStruct $ps */
$ps = (object)['x' => 0, 'y' => 1, 'z' => 2];

/**
 * @param PersonStruct $ps
 * @return PersonStruct
 */
function f(object $ps):object {
    return $ps;
}

/**
 * @param PersonStruct $ps
 * @return PersonStruct
 */
function f(stdClass $ps):stdClass {
    return $ps;
}

Le problème est que cela implique de convertir des tableaux en objets. Cela a des implications sur les performances et change le passage par valeur en passage par référence. Lequel est le plus rapide est discutable. Les tableaux devraient en théorie être plus rapides, bien que les objets aient des avantages étant des références par défaut et fonctionnent mieux avec JSON qui sépare l'objet du tableau contrairement à PHP.

Les objets ne supportent pas non plus une propriété qui pourrait ne pas être très bien définie en ce qui concerne l'indication du type, même si les propriétés d'un objet ne sont qu'un tableau PHP (utiliser ->{key} au lieu de [key] ). Il y a le potentiel pour d'autres choses bizarres.

Si les performances sont un réel souci, vous pouvez transformer PHP en langage compilé. De la même façon que vous pouvez étendre une interface pour rendre un objet compilable, vous pouvez faire la même chose pour un objet où vous pouvez tout faire avec la POO et l'auto-complétion, mais vous pouvez alors faire l'équivalent de l'inlining d'une classe en spécifiant la propriété qu'elle enveloppe, puis en utilisant la réflexion pour remplacer les utilisations par le contenu des méthodes correspondantes, avec quelques bits supplémentaires nécessaires (marquer ce qui doit être inline ou converti en procédural, une seule propriété à envelopper ou plusieurs, etc).

Le concept est similaire à celui de la boxe et de l'unboxing. Si vous tenez vraiment à ce que l'AS soit prise en charge et à ce que les IDE (autocomplétion, vérification, etc.), les analyseurs, les outils, etc. soient largement pris en charge, c'est peut-être la seule solution.

3voto

CommaToast Points 1165

J'aime mieux ça :

 * @param array $doc
 *          'type'=>Doc::MY_DOC_TYPE,
 *          'created'=>$now,
 *          'modified'=>$now

Je colle simplement le code à partir duquel il est initialisé, rapide et facile.

1voto

Mark Baker Points 90240

Étant donné qu'il s'agit d'un simple affichage plutôt que d'une directive, et que le formatage de l'espace doit être conservé dans les documents, je serais enclin à privilégier la lisibilité avec une indentation plutôt qu'un mur de caractères :

 * array['fields'] array Defines the feilds to be shown by scaffolding.
 *           [fieldName] array Defines the options for a field, or just enables
 *                             the field if array is not applied.
 *                 ['name'] string Overrides the field name (default is the
 *                                  array key)
 *                 ['model'] string (optional) Overrides the model if the field is
 *                                  a belongsTo assoicated value.
 *                 ['width'] string Defines the width of the field for paginate
 *                                  views.
 *                                  Examples are "100px" or "auto"
 *                 ['align'] string Alignment types for paginate views (left, 
 *                                 right, center)
 *                 ['format'] string Formatting options for paginate fields.
 *                                   Options include 'currency', 'nice',
 *                                  'niceShort', 'timeAgoInWords' or a valid 
 *                                  Date() format)
 *                 ['title'] string Changes the field name shown in views.
 *                 ['desc'] string The description shown in edit/create views.
 *                 ['readonly'] boolean True prevents users from changing the
 *                                 value in edit/create forms.
 *                 ['type'] string Defines the input type used by the Form helper
 *                                  (example 'password')
 *                 ['options'] array Defines a list of string options for drop-
 *                                  down lists.
 *                 ['editor'] boolean If set to True will show a WYSIWYG editor
 *                                  for this field.
 *                 ['default'] string The default value for create forms.

Bien que l'utilisation d'une définition de tableau PHP avec indentation soit encore plus propre.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X