Apprendre PHP avec Claude en 2026 : maîtriser le langage sans devenir prisonnier de l'IA

Code review la semaine dernière. Un dev "fullstack" me montre son API Laravel. Propre en surface — controllers bien découpés, migrations Eloquent, validation par Form Requests. Je lui demande pourquoi il utilise $request->all() au lieu de $request->validated() dans son controller. Blanc. Il ne savait pas que all() renvoie tout le payload, y compris les champs non validés. Claude lui avait généré le controller, il avait copié, ça marchait. Six mois de Laravel et une faille de mass assignment dormante dans chaque endpoint.

PHP a un problème que Python n'a pas : sa réputation. "Langage mort", "spaghetti code", "juste bon pour WordPress". En 2026, c'est faux depuis longtemps — PHP 8.3 est un langage typé, moderne, avec des enums, des fibers, du readonly, et une performance que PHP 5 n'aurait jamais imaginée. Mais cette réputation fait que beaucoup de débutants sautent les bases et se jettent directement sur un framework, guidés par l'IA. Le résultat : des opérateurs de Laravel, pas des développeurs PHP. Cet article explique comment utiliser Claude pour devenir le second sans tomber dans le premier.

PHP en 2026 : le langage que les gens adorent détester

Avant de parler pédagogie, réglons le sujet. "Pourquoi apprendre PHP alors que tout le monde passe à Go / Rust / TypeScript ?" Trois faits, pas des opinions.

1. PHP fait tourner 75% du web. WordPress, Shopify (backend), Symfony, Laravel — des millions de projets en production. Les missions PHP ne manquent pas, et elles paient bien parce que les bons devs PHP se font rares. Tout le monde veut coder en Rust, peu de gens savent debugger un Doctrine\ORM\Query\QueryException à 2h du matin.

2. PHP 8.3 n'a rien à voir avec PHP 5. Les type declarations, les enums, readonly, match, les named arguments, les fibers, le JIT — c'est un langage différent. Les critiques de PHP datent de 2012. En 2026, les mêmes patterns qu'on applaudissait en TypeScript existent en PHP natif.

3. L'IA ne debug pas ton contexte métier. Claude génère un UserController en 15 secondes. Mais quand l'auth LDAP du client casse en staging et que les sessions ne se propagent plus entre tes workers PHP-FPM, c'est toi qui dois comprendre le cycle de vie d'une requête HTTP. Si tu n'as jamais compris $_SESSION, tu es bloqué.

Les 5 pièges spécifiques de l'apprentissage PHP avec l'IA

PHP a ses propres anti-patterns d'apprentissage. L'IA les amplifie si tu ne les connais pas.

Piège 1 — Copier du WordPress sans comprendre

Tu demandes "comment créer un formulaire de contact en PHP", Claude te sort du code WordPress avec wp_mail() et des hooks add_action. Tu copies, ça marche dans WordPress. Tu n'as rien appris de PHP. Tu ne sais pas que mail() existe en natif, que c'est une horreur en production (pas d'auth SMTP, pas de TLS), et que PHPMailer résout le vrai problème. WordPress n'est pas PHP — c'est un framework avec son propre dialecte.

Piège 2 — Utiliser un framework avant de comprendre HTTP

Laravel en semaine 1. C'est le piège le plus courant. Le framework abstrait tout : routing, requêtes, réponses, sessions, middleware. Si tu ne comprends pas ce qu'est $_GET, $_POST, $_SERVER['REQUEST_METHOD'], tu ne comprends pas ce que le framework fait pour toi. Et le jour où il fait un truc inattendu, tu es perdu.

Piège 3 — Confondre PHP 5 et PHP 8

L'IA a été entraînée sur des millions de lignes de vieux PHP. Quand tu demandes "comment hasher un mot de passe en PHP", il y a des chances non négligeables que Claude te propose md5() ou sha1() dans certains contextes. Le bon réflexe : password_hash() avec PASSWORD_BCRYPT ou PASSWORD_ARGON2ID. Toujours vérifier la version PHP des patterns proposés.

// ❌ PHP 5 — ne fais JAMAIS ça
$hash = md5($password);
$hash = sha1($password . $salt);

// ✅ PHP 8 — la seule bonne façon
$hash = password_hash($password, PASSWORD_ARGON2ID);
$valid = password_verify($input, $hash);

Piège 4 — Ignorer le typage

PHP est optionnellement typé. L'IA génère souvent du code sans types parce que c'est "plus simple". Résultat : tu apprends un PHP laxiste qui accepte tout et qui pète en production sur des TypeError que tu ne comprends pas. Active declare(strict_types=1) dès le premier fichier. Sans exception.

// ❌ Sans typage — tout passe, rien n'est sûr
function calculatePrice($quantity, $unitPrice) {
    return $quantity * $unitPrice;
}
calculatePrice("3", "19.99"); // Ça marche... par hasard

// ✅ Avec strict_types — les erreurs sont explicites
declare(strict_types=1);

function calculatePrice(int $quantity, float $unitPrice): float {
    return $quantity * $unitPrice;
}
calculatePrice("3", "19.99"); // TypeError immédiat

Piège 5 — PDO vs mysqli : le faux débat

Claude propose tantôt mysqli, tantôt PDO, selon le contexte de la question. Le vrai conseil : utilise PDO, point. C'est la couche d'abstraction standard, elle supporte les prepared statements proprement, et elle fonctionne avec n'importe quel SGBD. mysqli est spécifique à MySQL et n'apporte rien de plus dans 99% des cas.

// ❌ mysqli — couplé à MySQL, API confuse
$conn = new mysqli("localhost", "user", "pass", "db");
$stmt = $conn->prepare("SELECT * FROM users WHERE email = ?");
$stmt->bind_param("s", $email);
$stmt->execute();
$result = $stmt->get_result();

// ✅ PDO — portable, clair, chaînable
$pdo = new PDO('mysql:host=localhost;dbname=db', 'user', 'pass', [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]);
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email');
$stmt->execute(['email' => $email]);
$user = $stmt->fetch();

Le workflow qui marche : écrire d'abord, demander ensuite

Le même cycle que pour n'importe quel langage — j'en ai parlé dans le guide Python — mais avec des exemples PHP concrets.

Étape 1 — Écrire ta version, même moche

Problème : filtrer un tableau d'utilisateurs pour ne garder que les majeurs. Ta première version, sans IA :

// Ma version — filtrer les utilisateurs majeurs
function getAdults(array $users): array {
    $adults = [];
    foreach ($users as $user) {
        if ($user['age'] >= 18) {
            $adults[] = $user;
        }
    }
    return $adults;
}

Étape 2 — Demander la review, pas la solution

Voici mon code PHP pour filtrer un tableau d'utilisateurs. Ne me donne pas une version corrigée. Dis-moi ce qui pourrait être amélioré et pourquoi, et laisse-moi réécrire moi-même.

Claude va pointer : array_filter existe pour ça. Le typage du retour est array mais pourrait être plus précis avec un commentaire @return array<int, array{name: string, age: int}>. Et si $users est vide ? Est-ce que ta fonction gère le cas ? (Oui, elle le gère — mais tu y as pensé ?)

Étape 3 — Réécrire toi-même

// Ma version améliorée après review
/** @param array<array{name: string, age: int}> $users */
function getAdults(array $users): array {
    return array_filter($users, fn(array $user): bool => $user['age'] >= 18);
}

Tu as découvert array_filter et les arrow functions. Tu comprends que fn() => est du sucre syntaxique pour les closures à expression unique. Tu sais pourquoi c'est plus concis, et tu sais que array_filter préserve les clés (ce qui peut être un piège si tu itères ensuite avec un index numérique).

Étape 4 — Demander "qu'est-ce que je ne vois pas ?"

Voici ma version améliorée. Qu'est-ce que je ne vois pas ? Y a-t-il un pattern plus robuste pour ce type de filtrage ?

Claude va probablement te parler de la match expression pour des filtrages multi-critères, des collections typées avec des classes, et de la différence entre array_filter et array_values(array_filter(...)) pour réindexer le tableau. Trois niveaux de compréhension, et tu as écrit toi-même les deux premiers.

Les prompts qui forment (vs ceux qui assistent)

La différence entre apprendre et déléguer tient à la formulation du prompt. Voici les patterns adaptés à PHP.

❌ Prompt passif ✅ Prompt pédagogique
"Écris un CRUD PHP pour gérer des produits" "J'ai écrit cette route POST qui insère un produit avec PDO. Est-ce que mes prepared statements protègent vraiment contre les injections SQL ?"
"Corrige cette erreur" "Ce code lève TypeError: Argument #1 must be of type string, null given. Explique-moi d'où vient le null sans me donner le fix."
"Fais-moi une auth Laravel" "J'ai implémenté une auth session avec password_verify() et un token CSRF. Qu'est-ce qu'un attaquant pourrait exploiter ?"
"C'est quoi les namespaces ?" "J'ai compris que use App\Service\UserService importe une classe. Mais quelle est la différence entre use dans un namespace et use dans une closure ?"
"Écris une classe PHP" "J'ai cette classe User avec 8 propriétés dans le constructeur. Est-ce que les promoted properties de PHP 8 la simplifieraient ? Montre-moi la différence."

Le pattern commun : montrer ce que tu as fait ou compris, puis poser une question précise. Pas "explique-moi les namespaces" mais "j'ai compris ça, qu'est-ce qui me manque ?". Claude adapte sa réponse à ton niveau réel au lieu de te servir la doc PHP.net en version longue.

Le parcours : de zéro à autonome en 8 semaines

Pas un programme rigide — un chemin qui a marché pour des gens que j'ai accompagnés. Adapté aux spécificités PHP. L'IA intervient après l'effort, jamais avant.

Semaines 1-2 — Les bases sans IA

Variables, types, conditions, boucles, fonctions, tableaux. Sans Claude. Utilise la doc officielle PHP (php.net/manual) et fais les exercices à la main. Commence chaque fichier par declare(strict_types=1). Le but : que foreach ($items as $key => $value) devienne un réflexe, pas une formule que tu demandes à chaque fois.

Exercice : écrire un script qui lit un fichier CSV et calcule des statistiques (moyenne, min, max) sur une colonne numérique. Pas de bibliothèque externe. Juste fopen(), fgetcsv(), un tableau associatif. Quand c'est fait, demande à Claude de review.

Semaines 3-4 — POO et namespaces

Classes, interfaces, traits, héritage, composition, namespaces, autoloading PSR-4. C'est ici que PHP se distingue : la POO est au coeur du langage moderne, et les namespaces sont le mécanisme qui structure tout projet non-trivial. Claude passe en mode review.

Exercice : un gestionnaire de tâches en CLI — ajout, suppression, marquage "fait", export JSON. Chaque entité dans sa classe. Utilise readonly, les constructor promoted properties, et les enums pour les statuts. Écris d'abord, review avec Claude ensuite. Il va probablement te parler d'interfaces — c'est le bon moment.

// Ce que tu devrais écrire toi-même en semaine 3
declare(strict_types=1);

enum TaskStatus: string {
    case Todo = 'todo';
    case Done = 'done';
    case Cancelled = 'cancelled';
}

final class Task {
    public function __construct(
        public readonly string $id,
        public readonly string $title,
        public TaskStatus $status = TaskStatus::Todo,
        public readonly \DateTimeImmutable $createdAt = new \DateTimeImmutable(),
    ) {}
}

Semaines 5-6 — Composer, API REST et bases de données

Composer, autoloading, dépendances. PDO, requêtes préparées, migrations manuelles. Écrire une API REST minimale — sans framework. Claude devient un professeur de patterns : "pourquoi séparer le routing de la logique métier ?", "pourquoi ne pas mettre le SQL dans le controller ?".

Exercice : une API REST qui gère des articles de blog (CRUD). Routing manuel ($_SERVER['REQUEST_URI'] + match), PDO pour la base, JSON en entrée/sortie. Gestion des erreurs HTTP (404, 422, 500). Demande à Claude : "mon routing est-il sécurisé ?" — la réponse va te surprendre.

Semaines 7-8 — Un vrai projet complet

Un projet qui combine tout. Deux options calibrées :

  • Un mini MVC à la main — router, controllers, vues PHP, modèles avec PDO, le tout structuré avec des namespaces et Composer autoload. Pas Symfony, pas Laravel — le tien. Tu comprendras enfin ce que les frameworks font sous le capot.
  • Une API complète — authentification JWT, validation des inputs, pagination, gestion des erreurs, tests avec PHPUnit. Le genre de projet qu'on te demande en entretien technique.

Claude passe en mode pair programming : tu écris une fonctionnalité, tu discutes l'architecture avec lui, il challenge tes choix. "Pourquoi tu mets la validation dans le controller et pas dans un service dédié ?" — si tu ne peux pas répondre, c'est que tu n'as pas encore décidé consciemment.

Claude Pro vs Claude Code : quel outil pour apprendre PHP

Deux outils, deux usages. Les deux coûtent $20/mois (Claude Pro) ou $20/mois (Claude Code avec le plan Max) — mais l'expérience d'apprentissage est très différente.

Claude Pro (claude.ai) — le professeur

Interface web, conversation. C'est le bon outil pour :

  • Comprendre un concept — "explique-moi la différence entre abstract class et interface en PHP avec un cas concret"
  • Review de code — coller ton code et demander un feedback structuré
  • Poser des questions "pourquoi" — "pourquoi === et pas == en PHP ?"
  • Préparer un entretien — "pose-moi 5 questions PHP de niveau intermédiaire sur la POO et les types"

Avantage : accessible, pas besoin de terminal, historique de conversation. Limite : tu copies-colles le code, il ne voit pas ton composer.json.

Claude Code — le pair programmer

Dans le terminal, directement dans ton projet. C'est le bon outil pour :

  • Travailler dans le contexte réel — Claude voit tes fichiers, ton composer.json, tes tests PHPUnit
  • Refactorer progressivement — "ce controller fait 300 lignes, aide-moi à extraire un service sans casser les tests"
  • Apprendre les outils — PHPStan, PHP CS Fixer, PHPUnit, Composer scripts — Claude les configure et t'explique pourquoi
  • Debugger en live — il lance php -S, voit l'erreur, t'explique la stack trace

Avantage : contexte complet du projet, exécution réelle. Limite : plus technique à installer, nécessite un terminal.

La combinaison idéale

Semaines 1-4 : Claude Pro pour les concepts et la review. Tu n'as pas encore de projet complexe, l'interface web suffit. Semaines 5-8 : Claude Code pour le projet. Tu as besoin du contexte fichier, des tests, du debug en live. Claude Pro reste utile pour les questions conceptuelles en parallèle.

Les conventions que l'IA ne t'apprendra pas

Claude écrit du PHP correct. Mais il y a une différence entre du code correct et du code professionnel. Ces conventions s'apprennent en lisant du bon code open source (Symfony, Laravel, PHPStan) et en se faisant corriger.

  • PSR-12 n'est pas optionnel — 4 espaces, accolades sur la ligne suivante pour les classes et méthodes, camelCase pour les méthodes, PascalCase pour les classes. Utilise PHP CS Fixer dès le premier jour.
  • Composer autoload, pas require manuel — si ton projet a plus de 3 fichiers et que tu fais require_once 'lib/User.php', tu fais du PHP de 2008. PSR-4 + composer dump-autoload, point.
  • Dependency injection sans framework — passer les dépendances dans le constructeur au lieu de les instancier à l'intérieur. L'IA génère souvent new PDO(...) dans chaque méthode. C'est un anti-pattern majeur.
  • declare(strict_types=1) partout — sans ça, PHP convertit silencieusement "42abc" en 42. Avec, il lève un TypeError. Tu veux la deuxième version.
  • Les tableaux ne sont pas des objets — un array PHP qui contient des données structurées devrait être un DTO (Data Transfer Object) avec des propriétés typées. L'IA adore les tableaux associatifs. Résiste.
  • Un fichier = une classe — PSR-4 l'impose. Si ton fichier contient deux classes, Composer ne sait plus quoi autoloader. Claude ne te dira jamais spontanément "sépare ces classes".

Mesurer ta progression

Comment savoir si tu apprends vraiment et pas juste si tu "fais des trucs avec Claude" ? Trois tests concrets.

Test 1 — Le tableau blanc. Prends un problème que tu as résolu avec Claude la semaine dernière. Réécris la classe de mémoire, sans IDE, sans IA. Si tu bloques sur la syntaxe du constructeur promoted properties, tu n'as pas appris — tu as délégué.

Test 2 — L'explication. Explique ton code à quelqu'un. Chaque méthode. Si tu dis "cette partie avec le match je sais pas trop pourquoi c'est comme ça", c'est un trou dans ta compréhension.

Test 3 — Le debug sans filet. Introduis un null quelque part dans ta chaîne d'appels. Ferme Claude. Trouve le TypeError avec var_dump(), error_log(), ou juste en lisant la stack trace. Le temps que tu mets mesure ton autonomie réelle.

📚 Le cours PHP complet, gratuit et interactif

Envie de pratiquer ce parcours pour de vrai ? Le cours PHP de ce site reprend ces bases leçon par leçon : du code que tu exécutes directement dans la page, des quiz, et des projets corrigés construits avec l'IA. On apprend en faisant, pas en lisant. Pour cibler : sessions et cookies, base de données SQL, ou le projet livre d'or en SQLite.

Conclusion

PHP n'est pas mort, il a juste grandi plus vite que sa réputation. Le langage de 2026 — typé, avec des enums, du readonly, du match, des fibers — n'a plus grand-chose à voir avec le PHP des blagues sur Reddit. Mais cette modernité ne sert à rien si tu la découvres via le copier-coller depuis Claude. La discipline reste la même : écrire d'abord, demander ensuite, réécrire soi-même.

Le développeur qui sort de ces 8 semaines sait lire une stack trace, choisir entre un tableau et un DTO, écrire du code PSR-12 que d'autres peuvent relire, et utiliser Claude comme un multiplicateur — pas comme une béquille. C'est exactement le profil qui manque sur le marché : quelqu'un qui sait coder en PHP et qui sait tirer le meilleur de l'IA.

Le même workflow s'applique à n'importe quel langage. Si tu viens de Go, j'ai écrit le guide équivalent pour Go. Pour Python, c'est par ici.

Commentaires (0)