Retour au cours

backend / php-laravel

Bases de PHP : variables, types, opérateurs

Leçon 11 exercice

Explication

Un peu d'histoire

PHP est créé en 1994 par Rasmus Lerdorf, un programmeur danois-canadien, pour suivre les visiteurs de son CV en ligne : il l'appelle alors "Personal Home Page Tools" (PHP/FI). Le langage évolue ensuite en un vrai langage de script côté serveur et devient, au fil des versions (PHP 5 en 2004 avec la vraie POO, PHP 7 en 2015 avec un moteur deux fois plus rapide, PHP 8 en 2020 avec le JIT et les types union), l'un des langages les plus utilisés pour construire des sites web dynamiques. Laravel, lui, est créé en 2011 par Taylor Otwell, un développeur américain frustré par la lourdeur d'un autre framework PHP (CodeIgniter) qui manquait de fonctionnalités modernes comme l'authentification intégrée. Laravel s'impose rapidement comme LE framework PHP de référence grâce à sa syntaxe élégante et son écosystème complet.

Pourquoi apprendre PHP et Laravel aujourd'hui

PHP fait tourner environ 75% des sites web dont on connaît la technologie serveur, dont des géants comme Wikipedia, Facebook (à ses débuts) ou WordPress (qui à lui seul propulse plus de 40% du web). Laravel est aujourd'hui le framework PHP le plus demandé sur le marché de l'emploi français et international, utilisé aussi bien par des startups que par de grandes entreprises pour construire des APIs, des back-offices et des applications web complètes. Apprendre PHP et Laravel ouvre donc l'accès à un immense volume d'offres d'emploi en développement backend, avec un langage relativement simple à démarrer mais qui monte en puissance jusqu'à des architectures très sophistiquées.

Ce que vous allez apprendre

  • Déclarer des variables PHP et comprendre pourquoi leur type n'est pas fixé à la déclaration
  • Distinguer == (comparaison avec conversion) de === (comparaison stricte) pour éviter les pièges historiques du langage
  • Utiliser l'opérateur de fusion null (??) pour gérer proprement des valeurs potentiellement absentes
  • Écrire une expression match moderne à la place d'un switch classique
  • Typer les paramètres et le retour d'une fonction, y compris avec des types nullable et union

Dans quel contexte ?

Imagine que tu rejoins une équipe qui maintient une API de gestion de commandes en PHP. Le fichier ProduitService.php calcule des prix, vérifie des configurations, et doit absolument éviter les bugs silencieux liés à des comparaisons de types mal maîtrisées — un classique en PHP pour qui débute. Comprendre précisément comment PHP traite les types dès cette première leçon évite des heures de débogage plus tard sur un vrai projet.

Des variables sans étiquette de type fixe

D'abord, une différence fondamentale avec des langages comme Java ou C# : en PHP, une variable commence toujours par $ et ne porte pas de type figé à sa création. La même variable $valeur peut contenir un texte, puis un nombre, sans que PHP ne s'y oppose par défaut.

C'est pratique pour aller vite, mais ça devient une source de bugs dès que le projet grossit. C'est exactement pour ça que declare(strict_types=1) existe : placée en tout début de fichier, cette ligne empêche PHP de convertir silencieusement les types dans les appels de fonctions typées.

Prérequis

Aucune connaissance préalable de PHP n'est nécessaire. Un minimum de logique de programmation (variables, conditions) aide à suivre plus vite, mais cette leçon part de zéro.

Le piège historique : == contre ===

Une fois les bases posées, il faut absolument comprendre la différence entre les deux opérateurs d'égalité. == compare seulement la valeur, en convertissant les types si besoin, tandis que === compare la valeur ET le type, sans aucune conversion.

Avant PHP 8, 0 == "abc" renvoyait true, ce qui a piégé des générations entières de développeurs (une chaîne non numérique était convertie en 0). Depuis PHP 8, ce comportement précis a été corrigé, mais la prudence reste de mise : dans le doute, utilise toujours ===.

OpérateurCompareConvertit les types ?Exemple piégeux
==Valeur seulementOui"10" == "1e1"true
===Valeur et typeNon10 === 10.0false

Ensuite, un outil bien plus sûr pour les valeurs manquantes

Il reste un problème très courant : que faire quand une clé de tableau ou une variable peut être absente ? Avant, il fallait écrire des isset() à rallonge. L'opérateur ?? (null coalescing) résout ça en une ligne : $config["mode"] ?? "production" renvoie la valeur si elle existe, sinon la valeur par défaut.

Astuce

??= va encore plus loin : $config["mode"] ??= "production" n'assigne la valeur par défaut que si la clé est absente ou nulle, sans jamais écraser une valeur déjà définie. Un réflexe à prendre systématiquement pour les valeurs de configuration.

Enfin, une meilleure façon d'écrire des embranchements

match (PHP 8+) remplace avantageusement switch : il est strict (comparaison === implicite, pas de conversion surprise), ne nécessite pas de break, et retourne directement une valeur au lieu de nécessiter des variables intermédiaires.

Piège fréquent

Un switch classique compare avec == en interne : switch ($statut) { case "2": ... } matchera aussi $statut = 2 (entier), ce qui peut cacher des bugs. match ne fait jamais cette conversion silencieuse — c'est justement pourquoi il est recommandé pour tout nouveau code.

Maintenant que tu maîtrises les variables, les types et les comparaisons, la prochaine étape logique est d'organiser ce code en fonctions réutilisables : c'est exactement l'objet de la leçon suivante, où tu découvriras les arguments nommés et les closures.

Commandes & code

Bases de PHP : variables, types, opérateurs

php
<?php
// Une variable PHP commence toujours par $, pas de déclaration de type obligatoire
$nom = "Alice";           // string
$age = 28;                 // int
$taille = 1.72;            // float
$estActif = true;          // bool
$rien = null;               // null

// Typage strict recommandé en début de fichier (sinon PHP fait des conversions implicites)
declare(strict_types=1);

// Interpolation de chaînes
echo "Bonjour $nom, tu as $age ans.
";
echo "Bonjour {$nom}, tu as " . ($age + 1) . " ans l'an prochain.
"; // concaténation avec .

// Opérateurs de comparaison : == compare la valeur, === compare valeur ET type
var_dump(0 == "abc");   // false depuis PHP 8 (avant: true, piège historique)
var_dump("10" == "1e1"); // true : comparaison numérique de chaînes numériques
var_dump(10 === 10.0);   // false : int !== float

// Opérateur de fusion null (null coalescing)
$config = ["debug" => false];
$mode = $config["mode"] ?? "production"; // valeur par défaut si clé absente ou null

// Opérateur de fusion null assignation
$config["mode"] ??= "production"; // assigne seulement si null/absent

// match (PHP 8+) : comme switch mais strict et avec valeur de retour
$statut = 2;
$libelle = match ($statut) {
    0, 1 => "en attente",
    2 => "validé",
    default => "inconnu",
};
echo $libelle . "
";

// Types scalaires en signature de fonction (depuis PHP 7)
function addition(int $a, int $b): int {
    return $a + $b;
}

// Types nullable et union types (PHP 8+)
function formatePrix(int|float $montant, ?string $devise = null): string {
    $devise ??= "EUR";
    return number_format($montant, 2) . " " . $devise;
}

echo formatePrix(19.9) . "
";

Résumé

  • declare(strict_types=1) évite les conversions de types implicites surprenantes.
  • === compare type ET valeur, == fait des conversions (souvent piégeuses).
  • ?? (null coalescing) et ??= remplacent les isset() verbeux.
  • match est l'équivalent strict et expressif de switch.

Exercices pratiques

1 disponible
1

Mission : traquer un bug de comparaison dans ProduitService

Objectif : Diagnostiquer un bug de comparaison de types apparu apres une migration PHP 7 vers PHP 8, puis le corriger avec les bons operateurs.

Contexte

Tu reprends le fichier ProduitService.php d'une equipe qui vient de migrer de PHP 7.4 vers PHP 8.2. Une fonction estCodePromoValide(string $code): bool contient simplement return $code == 0; pour detecter un vieux formulaire qui envoyait parfois la valeur 0 quand aucun code n'etait saisi. Depuis la migration, un testeur signale qu'un vrai code promo texte comme PROMO2024 est desormais refuse a tort, alors qu'il fonctionnait avant (a tort egalement, mais dans l'autre sens). Le fichier ne contient ni declare(strict_types=1), ni ===, ni match.

Résoudre l’exercice →