Top Code 2024, les challenges sont de nouveau disponibles dans les boards pour les participant(e)s => Boards

PHPStan #1 No value type specified in iterable type

Corrige cette erreur, grâce à ce récapitulatif PHPStan : tout pour bien déclarer la structure de tes tableaux.

Introduction

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 :

  • Est ce que la fonction retourne bien le type d’informations spécifié dans sa déclaration ?
  • Pour une fonction avec beaucoup de if, est ce qu’il n’y a pas un cas particulier qui serait oublié et ne générerait pas de retour ?
  • Est ce que la propriété de ma classe a bien été déclarée ?
  • Etc.

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 :

  • index numériques
  • index string
  • contient des entiers
  • contient des chaînes de caractères
  • contient des objets
  • plusieurs dimensions
  • etc.

Et là, le typage ne permet pas de spécifier cela en détails.

Error No value type specified in iterable type

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.

Array de 1 dimension avec index numériques

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.

Array de 1 dimension avec index chaînes de caractères

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

Array de plusieurs dimensions

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

Array qui contient des types différents

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.

Conclusion

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.


Qui a codé ce superbe contenu ?

Keep learning

Autres contenus à découvrir


Ta newsletter chaque mois

Corrigés, challenges, actualités, veille technique... aucun spam.