T: / Articles techniques / PHP
Corrige cette erreur, grâce à ce récapitulatif PHPStan : tout pour bien déclarer la structure de tes tableaux.
Nouvelle série d’articles sur PHPStan. Si tu ne connais pas PHPStan, c’est un analyseur de code statique. Ce qui veut dire qu’il analyse le code, avant qu’il soit exécuté pour trouver d’éventuels bugs :
Et des choses aussi beaucoup + complexes mais ce n’est pas le sujet pour le moment 🙂
Pour réaliser cette analyse, PHPStan s’appuie sur ton code… et sur la PHPDoc, les commentaires qui ressemblent à ça :
/**
* @property bool $awesomeArticleAboutPHPStan
*/
L’idée est de documenter, préciser certains éléments du code.
Ci-dessus, c’est un booléen, ça a peu d’intérêt car le typage permet de spécifier qu’une variable contient un booléen (Avec PHP 8.2 on pourra aussi préciser true ou false, cf. lien en bas de page). Mais dans le cas d’un tableau, array, c’est différent. Un tableau peut être structuré d’une infinité de façons différentes :
Et là, le typage ne permet pas de spécifier cela en détails.
Quand on lance PHPStan, c’est une erreur que l’on a souvent, qui rappelle que l’on n’a pas détaillé la structure de notre tableau.
Voici donc une liste de tableaux, et la définition PHPStan qui va avec.
Pour les exemples, j’utilise @param, mais ce sont les mêmes déclarations pour @var, @property, @return, etc.
Par exemple :
$numbers = [1, 2, 3, 4];
/**
* Ecriture simplifiée, il est induit que les index sont numériques
*
* @param int[] $numbers
* @param float[] $decimalNumbers
* @param string[] $words
* @param bool[] $conditions
*
* Fonctionne également avec des objets
*
* @param MySuperClass[] $supers
*
*/
/**
* Ecriture classique où l'on précise le type des index
*
* @param array<int, int> $numbers
* @param array<int, float> $decimalNumbers
* @param array<int, string> $words
* @param array<int, bool> $conditions
*
* @param array<int, MySuperClass> $supers
*
*/
Je conseille d’utiliser toujours la seconde écriture. De cette manière, on a des déclarations au format homogène avec les déclarations de tableaux + complexes.
Par exemple :
$ages = [
'marie' => 22,
'pierre' => 20,
'paul' => 22,
'martine' => 25,
'clement' => 30,
'sophie' => 19,
];
/**
* On spécifie donc forcément le type d'index
*
* @param array<string, int> $numbers
* @param array<string, float> $decimalNumbers
* @param array<string, string> $words
* @param array<string, bool> $conditions
*
* @param array<string, MySuperClass> $supers
*
*/
Par exemple :
// Jours fériés
$holidays = [
'janvier' => [1],
'fevrier' => [],
'mars' => [],
'avril' => [10],
'mai' => [1, 8],
// ...
];
Il va falloir imbriquer les déclarations les unes dans les autres :
/**
* Rappel : le premier élément après array< est le type de l'index :
*
* @param array<string, array<int, int>> $holidays
*/
Par exemple :
$person = [
'first_name' => 'Elon',
'last_name' => 'Musk',
'age' => 51,
'companies' => ['Tesla', 'SpaceX', 'Twitter'],
];
/**
*
* PHPStan permet de déclarer spécifiquement la structure du tableau
* En précisant à chaque fois le couple clé:type
*
* @param array{first_name: string, last_name: string, age: int, companies: array<int, string>} $person
*/
Remarque qui n’a rien à voir avec PHPStan : si tu as un tableau qui ressemble à ça, il peut être envisagé de le remplacer par une classe qui a des attributs. Le typage classique permettra de sécuriser l’ensemble.
C’est un premier tour d’horizon, il y a des cas plus complexes qui sont possibles. Garde cette page en favori pour t’y référer lorsque tu rencontreras cette fameuse erreur No value type specified in iterable type 😉
Voici les liens à la doc officielle de PHPStan :
Un peu de précisions sur les true type avec PHP 8.2
Et si tu cherches un bon moyen de mettre tout ça en pratique, il y a de grandes chances qu’un challenge intermédiaire te fasse gérer quelques tableaux.
Other content to discover