Cours PHP Complet 🐘
Les 12 chapitres essentiels — de la syntaxe de base à la POO et aux bases de données, avec exemples et quiz
7. Fonctions
2. Variables et types
8. POO : Classes et objets
3. Opérateurs et expressions
9. Héritage et interfaces
4. Structures conditionnelles
10. Bases de données (PDO)
5. Les boucles
11. Formulaires et sécurité
6. Les tableaux (Arrays)
12. PHP 8+ et bonnes pratiques
Introduction et premier script
// PHP = Hypertext Preprocessor — langage serveur
echo « Bonjour le monde ! »;
// Afficher avec formatage
print_r($variable); // Affiche un array/objet lisiblement
var_dump($variable); // Affiche type + valeur (debug)
?>
PHP s'exécute côté serveur. Le navigateur ne reçoit que le HTML résultant. Chaque fichier PHP commence par . Le tag de fermeture ?> est optionnel (et déconseillé) dans les fichiers 100% PHP.
| Caractéristique | PHP |
|---|---|
| Exécution | Côté serveur — Apache, Nginx, ou built-in server |
| Typage | Dynamique (types déclarés optionnels depuis PHP 7+) |
| Usage principal | Sites web dynamiques, APIs, WordPress, Laravel |
| Fichiers | .php |
| Serveur local | php -S localhost:8000 |
| Convention | $camelCase pour variables, PascalCase pour classes |
Variables et types
$nom = « Alice »; // string
$age = 25; // int
$taille = 1.75; // float
$actif = true; // bool
$rien = null; // null
$fruits = [« pomme », « banane »]; // array
// Vérifier le type
gettype($nom); // « string »
is_string($nom); // true
is_int($age); // true
is_array($fruits); // true
isset($nom); // true (existe et pas null)
empty($nom); // false (non vide)
$nom = « Alice »;
echo « Bonjour $nom ! »; // Bonjour Alice !
echo « Age: »; // Accolades pour les expressions
// Guillemets simples — texte brut (pas d'interpolation)
echo 'Bonjour $nom !'; // Bonjour $nom !
// Concaténation avec le point (.)
echo « Bonjour « . $nom . » ! »;
// Fonctions string
strlen($nom); // 5
strtoupper($nom); // « ALICE »
strtolower($nom); // « alice »
trim( » hello « ); // « hello »
str_replace(« A », « a », $nom); // « alice »
substr($nom, 0, 3); // « Ali »
str_contains($nom, « lic »); // true (PHP 8+)
str_starts_with($nom, « A »); // true (PHP 8+)
explode(« , », « a,b,c »); // [« a », « b », « c »]
implode(« , », $arr); // « a,b,c »
$n = (int) « 42 »; // 42
$s = (string) 42; // « 42 »
$f = (float) « 3.14 »; // 3.14
$b = (bool) « »; // false
intval(« 42abc »); // 42
// Constantes (immuables)
const PI = 3.14159;
define(« MAX », 100); // Alternative (ancienne syntaxe)
Piège courant : PHP fait du type juggling (conversion implicite). 0 == « abc » était true avant PHP 8 ! Depuis PHP 8, c'est corrigé, mais utilisez toujours === pour les comparaisons.
"Hello $nom"). Simples » = texte brut, pas d'interpolation. Les simples sont légèrement plus rapides.Opérateurs et expressions
0 == « 0 » // true
1 == true // true
« » == false // true
« » == 0 // true ⚠️
// === (strict) — compare VALEUR et TYPE
0 === « 0 » // false ✅
1 === true // false ✅
// Spaceship operator (PHP 7+)
1 <=> 2 // -1 (inférieur)
2 <=> 2 // 0 (égal)
3 <=> 2 // 1 (supérieur)
// Null coalescing (??) — valeur par défaut si null
$nom = $_GET['nom'] ?? « Inconnu »;
// Null coalescing assignment (??=)
$x ??= « défaut »; // Assigne seulement si $x est null
// Nullsafe operator (?->) (PHP 8+)
$ville = $user?->getAddress()?->city;
// Retourne null au lieu de crash si $user ou getAddress() est null
Règle d'or : utilisez TOUJOURS === (comparaison stricte). L'opérateur == fait des conversions implicites imprévisibles et est la source de bugs subtils en PHP.
Structures conditionnelles
if ($age < 18) elseif ($age < 65) else
// switch (comparaison loose ==)
switch ($jour)
// match (PHP 8+) — comparaison STRICTE, retourne une valeur
$result = match($status) ;
match > switch. Depuis PHP 8, préférez match : comparaison stricte (===), pas besoin de break, retourne une valeur, et lance une erreur si aucun cas ne correspond (sauf avec default).
false
0 // int zéro
0.0 // float zéro
« » // chaîne vide
« 0 » // ⚠️ la chaîne « 0 » est falsy en PHP ![] // array vide
null
Les boucles
for ($i = 0; $i < 5; $i++)
// foreach — LE plus utilisé en PHP
$fruits = [« pomme », « banane », « cerise »];
foreach ($fruits as $fruit)
// foreach avec clé
$ages = [« Alice » => 25, « Bob » => 30];
foreach ($ages as $nom => $age)
// while
while ($i < 10)
// do-while
do while ($i < 10);
Les tableaux (Arrays)
$fruits = [« pomme », « banane », « cerise »];
$fruits[0]; // « pomme »
// Array associatif (clé => valeur) — comme un dictionnaire
$user = [
« nom » => « Alice »,
« age » => 25,
« email » => « alice@mail.com »,
];
$user[« nom »]; // « Alice »
En PHP, Array = tout à la fois. Contrairement à d'autres langages, un seul type array sert de list, dict, set, stack, queue. C'est à la fois sa force et sa confusion.
| Fonction | Action | Exemple |
|---|---|---|
| count() | Nombre d'éléments | count($arr) |
| array_push() | Ajouter à la fin | $arr[] = « x » (raccourci) |
| array_pop() | Retirer le dernier | array_pop($arr) |
| array_shift() | Retirer le premier | array_shift($arr) |
| array_unshift() | Ajouter au début | array_unshift($arr, « x ») |
| in_array() | Vérifier l'existence | in_array(« x », $arr, true) |
| array_key_exists() | Clé existe ? | array_key_exists(« nom », $arr) |
| array_merge() | Fusionner | array_merge($a, $b) |
| array_keys() | Toutes les clés | array_keys($arr) |
| array_values() | Toutes les valeurs | array_values($arr) |
| sort() | Trier (réindexe) | sort($arr) |
| array_slice() | Extraire une portion | array_slice($arr, 0, 3) |
| array_unique() | Dédupliquer | array_unique($arr) |
// array_map — transforme chaque élément
$doubles = array_map(fn($n) => $n * 2, $nombres);
// [2, 4, 6, 8, 10]
// array_filter — garde ceux qui passent le test
$pairs = array_filter($nombres, fn($n) => $n % 2 === 0);
// [2, 4]
// array_reduce — accumule en une valeur
$somme = array_reduce($nombres, fn($acc, $n) => $acc + $n, 0);
// 15
// Destructurer (PHP 7.1+)[$a, $b, $c] = [1, 2, 3];[« nom » => $nom, « age » => $age] = $user;
Fonctions
function saluer(string $nom): string
// Paramètre optionnel avec valeur par défaut
function puissance(float $base, int $exp = 2): float
// Nullable (?type)
function trouver(int $id): ?string
// Union types (PHP 8+)
function format(string|int $value): string
// void — ne retourne rien
function log(string $msg): void
$double = fn(int $n): int => $n * 2;
// Closure classique (accès au scope parent via use)
$facteur = 3;
$multiply = function(int $n) use ($facteur): int ;
// Arguments nommés (PHP 8+)
function createUser(string $nom, int $age, string $role = « user »): array
createUser(nom: « Alice », age: 25);
createUser(age: 30, nom: « Bob »); // L'ordre n'importe plus
// Variadic (…args)
function somme(int …$nombres): int
somme(1, 2, 3); // 6
use ($var) pour accéder aux variables parentes.POO : Classes et objets
$alice = new User(« Alice », 25, 1);
echo $alice->saluer();
class User {
public function __construct(
private string $nom,
private int $age,
public readonly int $id,
)
public function getNom(): string { return $this->nom; }
}
// 3 lignes au lieu de 15 — même résultat
Constructor promotion = la meilleure feature de PHP 8 pour réduire le boilerplate. Ajoutez le modificateur d'accès devant le paramètre et PHP crée la propriété automatiquement.
| Modificateur | Classe | Enfant | Extérieur |
|---|---|---|---|
| public | ✅ | ✅ | ✅ |
| protected | ✅ | ✅ | ❌ |
| private | ✅ | ❌ | ❌ |
Héritage et interfaces
// Interface
interface Serializable
class Product implements Serializable {
public function __construct(
private string $name,
private float $price,
)
public function toArray(): array {
return ['name' => $this->name, 'price' => $this->price];
}
public function toJson(): string {
return json_encode($this->toArray());
}
}
trait Timestampable
class Post
// Classe abstraite
abstract class Shape
// Enum (PHP 8.1+)
enum Status: string
$s = Status::Active;
$s->value; // « active »
$s->label(); // « Actif »
Bases de données (PDO)
$pdo->query(« SELECT * FROM users WHERE id = $id »);
// ✅ TOUJOURS — requête préparée
$stmt = $pdo->prepare(« SELECT * FROM users WHERE id = :id »);
$stmt->execute([':id' => $id]);
$user = $stmt->fetch();
// INSERT
$stmt = $pdo->prepare(« INSERT INTO users (nom, email) VALUES (:nom, :email) »);
$stmt->execute([':nom' => $nom, ':email' => $email]);
$newId = $pdo->lastInsertId();
// UPDATE
$stmt = $pdo->prepare(« UPDATE users SET nom = :nom WHERE id = :id »);
$stmt->execute([':nom' => $nom, ':id' => $id]);
// DELETE
$stmt = $pdo->prepare(« DELETE FROM users WHERE id = :id »);
$stmt->execute([':id' => $id]);
// Récupérer plusieurs résultats
$users = $stmt->fetchAll();
JAMAIS de variables directement dans une requête SQL. Utilisez TOUJOURS des requêtes préparées (prepare + execute). C'est la protection n°1 contre les injections SQL.
Formulaires et sécurité
$_GET['param'] // Paramètres d'URL (?param=value)
$_POST['champ'] // Données de formulaire POST
$_REQUEST // GET + POST (à éviter — ambigu)
$_FILES // Fichiers uploadés
$_SESSION // Données de session
$_COOKIE // Cookies
$_SERVER // Infos serveur
// Traitement sécurisé d'un formulaire
if ($_SERVER['REQUEST_METHOD'] === 'POST')
echo htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8');
// 2. SQL Injection — requêtes préparées (chapitre 10)
$stmt = $pdo->prepare(« SELECT * FROM users WHERE id = ? »);
// 3. CSRF — token dans les formulaires
session_start();
$_SESSION['csrf'] = bin2hex(random_bytes(32));
// Dans le form :
// 4. Mots de passe — TOUJOURS hasher
$hash = password_hash($password, PASSWORD_DEFAULT);
$ok = password_verify($password, $hash); // true/false
// 5. Validation
filter_var($email, FILTER_VALIDATE_EMAIL);
filter_var($url, FILTER_VALIDATE_URL);
filter_var($ip, FILTER_VALIDATE_IP);
Les 3 règles de sécurité PHP : 1. htmlspecialchars() pour tout affichage. 2. Requêtes préparées pour toute requête SQL. 3. password_hash() pour les mots de passe. Sans exception.
// Stocker
$_SESSION['user_id'] = 42;
$_SESSION['role'] = 'admin';
// Lire
$userId = $_SESSION['user_id'] ?? null;
// Détruire
session_destroy();
PHP 8+ et bonnes pratiques
| Feature | Version | Exemple |
|---|---|---|
| match | 8.0 | Switch strict qui retourne une valeur |
| Named arguments | 8.0 | fn(age: 25, nom: « A ») |
| Nullsafe ?-> | 8.0 | $user?->getAddress()?->city |
| Union types | 8.0 | string|int $value |
| Constructor promotion | 8.0 | public function __construct(private string $nom) |
| str_contains/starts_with | 8.0 | str_contains(« abc », « b ») |
| Enums | 8.1 | enum Status: string |
| readonly properties | 8.1 | public readonly string $nom |
| Fibers | 8.1 | Concurrence légère |
| readonly classes | 8.2 | readonly class Config |
| Intersection types | 8.2 | Iterator&Countable $col |
| json_validate() | 8.3 | Vérifie si un string est du JSON valide |
| #[Override] | 8.3 | Vérifie qu'une méthode surcharge le parent |
| Typed constants | 8.3 | const string NAME = 'App'; |
// Installer les dépendances
composer install
// Utiliser l'autoloader
require 'vendor/autoload.php';
// Namespaces
namespace App\Models;
class User
// Dans un autre fichier
use App\Models\User;
$user = new User();
✅ À FAIRE
• Toujours === (strict)
• Type hints partout (params + retour)
• Constructor promotion (PHP 8)
• match au lieu de switch
• PDO + prepare() pour la BDD
• htmlspecialchars() pour l'affichage
• password_hash() pour les mdp
• Composer + autoloading PSR-4
• declare(strict_types=1) en haut de fichier
❌ À ÉVITER
• == (comparaison loose)
• Variables dans les requêtes SQL
• mysql_* fonctions (supprimées)
• extract() et $$var
• eval()
• global $var
• echo directement du HTML non échappé
• Pas de tag de fermeture ?> (fichiers PHP purs)
• @ pour masquer les erreurs
declare(strict_types=1); // TOUJOURS en première ligne
function add(int $a, int $b): int
add(« 5 », 3); // ❌ TypeError ! (sans strict_types, ça aurait marché)
strict_types désactive la conversion automatique des types dans les appels de fonctions. C'est la première ligne à écrire dans tout fichier PHP sérieux. Utilisez-la systématiquement.
int et reçoit une string, PHP lance un TypeError au lieu de convertir silencieusement.Cours PHP Complet — Des bases à PHP 8.3+
Référence : PHP Manual | PHP The Right Way

