Donc, dans PHPDoc, on peut spécifier @var
au-dessus de la déclaration de variable membre pour faire allusion à son type. Ensuite, un IDE, par exemple. PHPEd, saura avec quel type d'objet il travaille et sera en mesure de fournir un aperçu du code pour cette variable.
<?php
class Test
{
/** @var SomeObj */
private $someObjInstance;
}
?>
Cela fonctionne très bien jusqu'à ce que je doive faire de même avec un tableau d'objets pour pouvoir obtenir un indice approprié lorsque j'itérerai ces objets plus tard.
Alors, existe-t-il un moyen de déclarer une balise PHPDoc pour spécifier que la variable membre est un tableau de SomeObj
s? @var
tableau ne suffit pas, et @var array(SomeObj)
ne semble pas être valide, par exemple.
Réponses:
Utilisation:
lors de la saisie de types de variables en ligne, et
pour les propriétés de classe.
Réponse précédente de '09 lorsque PHPDoc (et les IDE comme Zend Studio et Netbeans) n'avaient pas cette option:
Le mieux que vous puissiez faire est de dire:
Je fais beaucoup ça dans Zend Studio. Je ne connais pas les autres éditeurs, mais cela devrait fonctionner.
la source
/** @var $Obj Test */
ne fonctionne pas.@var Object[] $objects
dit que "$ objects" est un tableau d'instances d'Object.)/** @var TYPE $variable_name */
est la syntaxe correcte; n'inversez pas l'ordre du type et du nom de variable (comme suggéré plus haut dans les commentaires) car cela ne fonctionnera pas dans tous les cas.Dans l'IDE PhpStorm de JetBrains, vous pouvez utiliser
/** @var SomeObj[] */
, par exemple:La documentation de phpdoc recommande cette méthode:
la source
foreach(getSomeObjects() as $obj)
ne fonctionne pas, mais cela fonctionne pour$objs = getSomeObjects(); foreach($objs as $obj)
@var Obj[string]
pour les tableaux associatifs.Astuces Netbeans:
Vous obtenez l'achèvement du code sur
$users[0]->
et$this->
pour un tableau de classes d'utilisateurs.Vous pouvez également voir le type du tableau dans une liste de membres de classe lorsque vous effectuez
$this->...
la source
array_pop()
ou des fonctions similaires pour une raison quelconque. Il semble que Netbeans ne réalise pas que ces fonctions renvoient un seul élément du tableau d'entrée.Pour spécifier une variable est un tableau d'objets:
Cela fonctionne dans Netbeans 7.2 (je l'utilise)
Fonctionne également avec:
Par conséquent, l'utilisation d'une déclaration à l'intérieur du
foreach
n'est pas nécessaire.la source
/* @var $Obj Test */
annotation à chaque fois./**
2. Le format correct est@var <data-type> <variable-name>
PSR-5: PHPDoc propose une forme de notation de style générique.
Syntaxe
Les valeurs d'une collection PEUVENT même être un autre tableau et même une autre collection.
Exemples
Remarque: Si vous vous attendez à ce qu'un IDE aide le code, alors c'est une autre question de savoir si l'IDE prend en charge la notation des collections de style générique PHPDoc.
De ma réponse à cette question .
la source
Je préfère lire et écrire du code propre - comme indiqué dans "Clean Code" de Robert C. Martin. Lorsque vous suivez son credo, vous ne devez pas obliger le développeur (en tant qu'utilisateur de votre API) à connaître la structure (interne) de votre tableau.
L'utilisateur de l'API peut demander: est-ce un tableau avec une seule dimension? Les objets sont-ils répartis à tous les niveaux d'un réseau multidimensionnel? De combien de boucles imbriquées (foreach, etc.) ai-je besoin pour accéder à tous les objets? Quels types d'objets sont "stockés" dans ce tableau?
Comme vous l'avez indiqué, vous souhaitez utiliser ce tableau (qui contient des objets) comme un tableau unidimensionnel.
Comme indiqué par Nishi, vous pouvez utiliser:
pour ça.
Mais encore une fois: soyez conscient - ce n'est pas une notation standard de docblock. Cette notation a été introduite par certains producteurs IDE.
D'accord, d'accord, en tant que développeur, vous savez que "[]" est lié à un tableau en PHP. Mais que signifie "quelque chose []" dans un contexte PHP normal? "[]" signifie: créer un nouvel élément dans "quelque chose". Le nouvel élément pourrait être tout. Mais ce que vous voulez exprimer, c'est: tableau d'objets avec le même type et c'est le type exact. Comme vous pouvez le voir, le producteur IDE introduit un nouveau contexte. Un nouveau contexte qu'il fallait apprendre. Un nouveau contexte que d'autres développeurs PHP ont dû apprendre (pour comprendre vos docblocks). Mauvais style (!).
Parce que votre tableau a une dimension, vous voudrez peut-être appeler ce "tableau d'objets" une "liste". Sachez que "liste" a une signification très spéciale dans d'autres langages de programmation. Il serait préférable de l'appeler "collection" par exemple.
N'oubliez pas: vous utilisez un langage de programmation qui vous permet toutes les options de POO. Utilisez une classe au lieu d'un tableau et rendez votre classe traversable comme un tableau. Par exemple:
Ou si vous souhaitez stocker les objets internes à différents niveaux dans une structure de tableau / objet multidimensionnelle:
Cette solution remplace votre tableau par un objet de type "orderCollection", mais n'activez pas la complétion de code dans votre IDE jusqu'à présent. D'accord. L'étape suivante:
Implémentez les méthodes introduites par l'interface avec docblocks - en particulier:
N'oubliez pas d'utiliser l'indication de type pour:
Cette solution arrête d'introduire beaucoup de:
partout dans vos fichiers de code (par exemple dans les boucles), comme Zahymaka l'a confirmé avec sa réponse. Votre utilisateur d'API n'est pas obligé d'introduire ces docblocks pour que le code soit complété. Avoir @return sur un seul endroit réduit la redondance (@var) le plus possible. Saupoudrer "docBlocks avec @var" rendrait votre code le moins lisible.
Finalement, vous avez terminé. Semble difficile à atteindre? On dirait de prendre un marteau pour casser une noix? Pas vraiment, puisque vous êtes familier avec ces interfaces et avec du code propre. Rappelez-vous: votre code source est écrit une fois / lu plusieurs.
Si l'achèvement du code de votre IDE ne fonctionne pas avec cette approche, passez à une meilleure (par exemple IntelliJ IDEA, PhpStorm, Netbeans) ou déposez une demande de fonctionnalité sur le suivi des problèmes de votre producteur IDE.
Merci à Christian Weiss (d'Allemagne) d'avoir été mon entraîneur et de m'avoir enseigné un truc tellement génial. PS: Rencontrez-moi et lui sur XING.
la source
SomeObj[]
vous savez qu'il s'agit d'un tableau d'SomeObj
instances bidimensionnel, vous savez quoi en faire. Je ne pense pas qu'il ne respecte pas le credo "code propre".@return <className>
forcurrent()
et all guys. PhpStorm prend en charge, donc cela m'a beaucoup aidé. Merci mon pote!À utiliser
array[type]
dans Zend Studio.Dans Zend Studio,
array[MyClass]
ouarray[int]
ou mêmearray[array[MyClass]]
fonctionne très bien.la source
Dans NetBeans 7.0 (peut-être aussi plus bas), vous pouvez déclarer le type de retour "tableau avec des objets Text" de la même manière
@return Text
et l'indication de code fonctionnera:Edit: mise à jour de l'exemple avec la suggestion @Bob Fanger
et il suffit de l'utiliser:
Ce n'est pas parfait mais il vaut mieux alors juste le laisser juste "mélangé", ce qui n'apporte aucune valeur.
CONS est que vous êtes autorisé à fouler le tableau en tant qu'objet texte, ce qui générera des erreurs.
la source
Comme DanielaWaranie mentionné dans sa réponse - il y a un moyen de spécifier le type de $ article lorsque vous itérer articles $ en $ collectionObject: Ajouter
@return MyEntitiesClassName
aucurrent()
et le reste duIterator
etArrayAccess
-méthodes les valeurs de retour.Boom! Pas besoin de
/** @var SomeObj[] $collectionObj */
plusforeach
, et fonctionne correctement avec l'objet collection, pas besoin de retourner la collection avec la méthode spécifique décrite comme@return SomeObj[]
.Je soupçonne que tous les IDE ne le supportent pas, mais cela fonctionne parfaitement dans PhpStorm, ce qui me rend plus heureux.
Exemple:
Quelle utilité j'allais ajouter en postant cette réponse
Dans mon cas
current()
et le reste desinterface
méthodes sont implémentées dans laAbstract
classe -collection et je ne sais pas quel type d'entités sera finalement stocké dans la collection.Voici donc l'astuce: ne spécifiez pas le type de retour dans la classe abstraite, utilisez plutôt l'instuction PhpDoc
@method
dans la description de la classe de collection spécifique.Exemple:
Maintenant, l'utilisation des classes:
Encore une fois: je soupçonne que tous les IDE ne le supportent pas, mais PhpStorm le fait. Essayez le vôtre, postez en commentaire les résultats!
la source
Je sais que je suis en retard à la fête, mais j'ai récemment travaillé sur ce problème. J'espère que quelqu'un voit cela parce que la réponse acceptée, bien que correcte, n'est pas la meilleure façon de le faire. Pas dans PHPStorm au moins, je n'ai pas testé NetBeans cependant.
La meilleure façon consiste à étendre la classe ArrayIterator plutôt qu'à utiliser des types de tableaux natifs. Cela vous permet de taper hint au niveau de la classe plutôt qu'au niveau de l'instance, ce qui signifie que vous n'avez à PHPDoc qu'une seule fois, pas dans tout votre code (ce qui est non seulement désordonné et viole DRY, mais peut également être problématique en ce qui concerne refactoring - PHPStorm a l'habitude de manquer PHPDoc lors du refactoring)
Voir le code ci-dessous:
La clé ici est le PHPDoc remplaçant
@method MyObj current()
le type de retour hérité d'ArrayIterator (qui estmixed
). L'inclusion de ce PHPDoc signifie que lorsque nous parcourons les propriétés de la classe à l'aideforeach($this as $myObj)
, nous obtenons ensuite l'achèvement du code lorsque nous nous référons à la variable$myObj->...
Pour moi, c'est la meilleure façon d'y parvenir (au moins jusqu'à ce que PHP introduise des tableaux typés, s'ils le font), car nous déclarons le type d'itérateur dans la classe itérable, pas sur les instances de la classe dispersées dans le code.
Je n'ai pas montré ici la solution complète pour étendre ArrayIterator, donc si vous utilisez cette technique, vous pouvez également vouloir:
offsetGet($index)
etnext()
is_a($object, MyObj::class)
du constructeur dans une méthode privéeoffsetSet($index, $newval)
etappend($value)
la source
Le problème est qu'il
@var
ne peut désigner qu'un seul type - Ne pas contenir de formule complexe. Si vous aviez une syntaxe pour "tableau de Foo", pourquoi vous arrêter là et ne pas ajouter une syntaxe pour "tableau de tableau, qui contient 2 Foo et trois barres"? Je comprends qu'une liste d'éléments est peut-être plus générique que cela, mais c'est une pente glissante.Personnellement, j'ai parfois utilisé
@var Foo[]
pour signifier "un tableau de Foo", mais ce n'est pas pris en charge par les IDE.la source
/* @var $foo Foo[] */
. Je viens d'écrire une réponse ci-dessous à ce sujet. Cela peut également être utilisé à l'intérieur desforeach(){}
bouclesla source
J'ai trouvé quelque chose qui fonctionne, cela peut sauver des vies!
la source