Contrôler les données d'un tableau

En PHP, on ne peut pas déclarer à l'initialisation d'un tableau le type de données qu'il va contenir. En java par exemple, si on veut déclarer un tableau d'entier, on peut faire :

int [] var;

Donc pour combler ce manque, il peut nous arriver d'écrire ce genre de code lorsqu'on utilise un tableau.

class Foo
{
    private array $items;
    
    public function __construct(array $items)
    {
        foreach ($items as $item) {
            if (!is_int($item)) {
                throw new Exception('Wrong type for item '.$item);
            }
        }
        
        $this->items = $items;
    } 
    
    // ...
}

$foo = new Foo([1, 2, 3, 4]);

On s'assure ici que chaque élément est bien un entier. Mais savez-vous qu'il est possible de déléguer ce traitement directement à PHP ?

D'après ce que j'ai lu ici et là, ce que je vous présente ensuite est valable pour des petites collections. Si vous avez à traiter de gros volumes de données, il est apparemment déconseillé d'utiliser ça.

L'opérateur de décomposition

On peut utiliser l'opérateur de décomposition dans la déclaration d'une fonction et aussi lors de son appel. Nous allons donc utiliser cet opérateur pour faciliter le contrôle des données.

class Foo
{
    private array $items;
    
    public function __construct(int ...$items)
    {
        $this->items = $items;
    }
}

$foo = new Foo(...[1, 2, 3, 4]);

Et si vous voulez vous assurer que votre tableau ait au moins un élément, il faut rajouter un paramètre dans le constructeur.

class Foo
{
    private array $items;
    
    public function __construct(int $item, int ...$items)
    {
        $this->items = [$item, ...$items];
    }
}

$foo = new Foo(...[1, 2, 3, 4]);

Par rapport à la gestion d'erreur

  • Si vous passez un tableau vide alors que vous vous attendiez à avoir au moins un élément, il faut faire un try / catch sur ArgumentCountError
class Foo
{
    private array $items;
    
    public function __construct(int $item, int ...$items)
    {
        $this->items = [$item, ...$items];
    }
}

try {
    $foo = new Foo(...[]);
} catch (ArgumentCountError $e) {
    echo $e->getMessage();
}
  • Si le type de vos données n'est pas bon, c'est une TypeError
try {
    $foo = new Foo(...['a', 'n']);
} catch (TypeError $e) {
    echo $e->getMessage();
}
  • Si vous voulez gérer les deux types d'erreur d'un coup, vous pouvez utiliser Throwable ou Error
try {
    $foo = new Foo(...['a', 'n']);
} catch (Error $e) {
    echo $e->getMessage();
}

Cet article t'a plu ? Si oui, je te propose de t'inscrire à ma dev letter pour recevoir régulièrement dans ta boîte mail mes conseils, mes nouveaux articles, des vidéos à voir, des outils à découvrir et encore bien d’autres choses.

Je m'inscris