Tutoriel PHP

← Retour aux tutoriels

Parcours d'apprentissage (novice vers expert)

Objectif: apprendre la syntaxe PHP puis savoir l'appliquer dans un projet web réel.

Fonctionnement: lis une section, exécute un extrait, valide le résultat, puis passe à la section suivante.

1. Structures conditionnelles

If / Else / Elseif

// Syntaxe classique
if ($age >= 18) {
    echo "Majeur";
} elseif ($age >= 16) {
    echo "Mineur avec permis";
} else {
    echo "Mineur";
}

// Opérateur ternaire
$statut = $age >= 18 ? "Majeur" : "Mineur";

// Null coalescing (PHP 7+)
$nom = $_GET['nom'] ?? 'Anonyme';

// Null coalescing assignment (PHP 7.4+)
$config ??= getDefaultConfig();

Switch

switch ($action) {
    case 'create':
        createRecord();
        break;
    case 'update':
        updateRecord();
        break;
    case 'delete':
        deleteRecord();
        break;
    default:
        showError();
}

// Match expression (PHP 8+)
$result = match($status) {
    200, 201 => 'Success',
    404 => 'Not Found',
    500 => 'Server Error',
    default => 'Unknown'
};

2. Boucles

For

for ($i = 0; $i < 10; $i++) {
    echo $i;
}

// Syntaxe alternative
for ($i = 0; $i < 10; $i++):
    echo $i;
endfor;

While / Do-While

while ($row = $stmt->fetch()) {
    echo $row['name'];
}

do {
    $input = readline("Entrez une valeur: ");
} while ($input !== 'quit');

Foreach

// Tableau indexé
foreach ($users as $user) {
    echo $user;
}

// Tableau associatif
foreach ($config as $key => $value) {
    echo "$key: $value";
}

// Par référence
foreach ($items as &$item) {
    $item *= 2;  // Modifie le tableau original
}
unset($item);  // Important : détruire la référence

3. Opérateurs

Opérateurs de comparaison

// Égalité (conversion de type)
$a == $b

// Égalité stricte (type + valeur)
$a === $b

// Spaceship operator (PHP 7+)
$a <=> $b  // Retourne -1, 0, ou 1

// Comparaison combinée
if ($a > 0 && $b < 100) { }
if ($a === null || $b === false) { }

Opérateurs logiques

// AND : && ou and
// OR  : || ou or
// NOT : !

// Short-circuit evaluation
$user && $user->isActive()  // Si $user est null, pas d'erreur

// Null-safe operator (PHP 8+)
$country = $user?->getAddress()?->getCountry();

4. Fonctions

Déclaration et types

// Fonction simple
function add($a, $b) {
    return $a + $b;
}

// Avec typage strict (PHP 7+)
declare(strict_types=1);

function divide(int $a, int $b): float {
    if ($b === 0) {
        throw new DivisionByZeroError();
    }
    return $a / $b;
}

// Paramètres optionnels
function greet(string $name = "Guest"): string {
    return "Hello, $name!";
}

// Paramètres nommés (PHP 8+)
function createUser(string $name, string $email, bool $active = true) {
    // ...
}
createUser(name: "John", email: "john@example.com");

Fonctions variables et anonymes

// Fonction anonyme (closure)
$multiply = function($a, $b) {
    return $a * $b;
};
echo $multiply(3, 4);

// Arrow function (PHP 7.4+)
$double = fn($n) => $n * 2;

// Closure avec use
$tax = 0.20;
$calcPrice = function($price) use ($tax) {
    return $price * (1 + $tax);
};

Fonctions variadiques

// Arguments variables
function sum(...$numbers): int {
    return array_sum($numbers);
}
echo sum(1, 2, 3, 4, 5);  // 15

// Spread operator
$arr = [1, 2, 3];
sum(...$arr);

5. Programmation Orientée Objet

Classes et propriétés

class User {
    // Propriétés typées (PHP 7.4+)
    private int $id;
    private string $name;
    private ?string $email = null;
    
    // Constructor property promotion (PHP 8+)
    public function __construct(
        private string $username,
        private string $password
    ) {
        $this->id = $this->generateId();
    }
    
    // Méthodes
    public function getName(): string {
        return $this->name;
    }
    
    public function setName(string $name): void {
        $this->name = $name;
    }
    
    // Méthode statique
    public static function create(array $data): self {
        return new self($data['username'], $data['password']);
    }
    
    private function generateId(): int {
        return random_int(1000, 9999);
    }
}

Héritage et interfaces

interface LoggerInterface {
    public function log(string $message): void;
}

abstract class AbstractUser {
    abstract protected function authenticate(): bool;
    
    public function login(): bool {
        return $this->authenticate();
    }
}

class Admin extends AbstractUser implements LoggerInterface {
    protected function authenticate(): bool {
        // Implémentation
        return true;
    }
    
    public function log(string $message): void {
        error_log($message);
    }
}

// Traits
trait Timestampable {
    private DateTime $createdAt;
    private DateTime $updatedAt;
    
    public function updateTimestamps(): void {
        $this->updatedAt = new DateTime();
    }
}

class Post {
    use Timestampable;
}

6. Gestion des erreurs

Exceptions

// Try-catch
try {
    $result = riskyOperation();
} catch (InvalidArgumentException $e) {
    echo "Argument invalide: " . $e->getMessage();
} catch (RuntimeException $e) {
    echo "Erreur runtime: " . $e->getMessage();
} catch (Exception $e) {
    echo "Erreur générique: " . $e->getMessage();
} finally {
    // Toujours exécuté
    cleanup();
}

// Créer une exception personnalisée
class DatabaseException extends Exception {
    public function __construct(
        string $message,
        private string $query,
        int $code = 0
    ) {
        parent::__construct($message, $code);
    }
    
    public function getQuery(): string {
        return $this->query;
    }
}

// Lancer une exception
throw new DatabaseException("Query failed", $sql);

Gestion d'erreurs

// Gestionnaire d'erreurs personnalisé
set_error_handler(function($errno, $errstr, $errfile, $errline) {
    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
});

// Gestionnaire d'exceptions non capturées
set_exception_handler(function($exception) {
    error_log($exception->getMessage());
    echo "Une erreur est survenue";
});

7. Namespaces et Autoloading

Namespaces

// Déclaration
namespace App\Controllers;

use App\Models\User;
use App\Services\Logger as ServiceLogger;
use function App\Helpers\sanitize;
use const App\Config\DB_HOST;

class UserController {
    public function index() {
        $user = new User();  // App\Models\User
        ServiceLogger::log("User accessed");
        $host = DB_HOST;
        return sanitize($data);
    }
}

Autoloading PSR-4

// composer.json
{
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    }
}

// Utilisation
require 'vendor/autoload.php';

use App\Controllers\UserController;

$controller = new UserController();

8. Tableaux et fonctions utiles

Manipulation de tableaux

// Création
$arr = [1, 2, 3];
$assoc = ['name' => 'John', 'age' => 30];

// Fonctions courantes
array_push($arr, 4);           // Ajouter à la fin
array_pop($arr);               // Retirer de la fin
array_shift($arr);             // Retirer du début
array_unshift($arr, 0);        // Ajouter au début
array_merge($arr1, $arr2);     // Fusionner
array_filter($arr, fn($x) => $x > 2);  // Filtrer
array_map(fn($x) => $x * 2, $arr);     // Transformer
array_reduce($arr, fn($carry, $item) => $carry + $item, 0);

// Spread operator (PHP 7.4+)
$combined = [...$arr1, ...$arr2];

// Array destructuring
[$first, $second] = $arr;
['name' => $name, 'age' => $age] = $assoc;

9. Bases de données (PDO)

// Connexion
$pdo = new PDO(
    'mysql:host=localhost;dbname=mydb;charset=utf8mb4',
    'username',
    'password',
    [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);

// Requête préparée
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email');
$stmt->execute(['email' => $email]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);

// Insertion
$stmt = $pdo->prepare('INSERT INTO users (name, email) VALUES (:name, :email)');
$stmt->execute(['name' => $name, 'email' => $email]);
$userId = $pdo->lastInsertId();

// Transaction
try {
    $pdo->beginTransaction();
    $pdo->exec("UPDATE accounts SET balance = balance - 100 WHERE id = 1");
    $pdo->exec("UPDATE accounts SET balance = balance + 100 WHERE id = 2");
    $pdo->commit();
} catch (Exception $e) {
    $pdo->rollBack();
    throw $e;
}

10. Bonnes pratiques

Enums (PHP 8.1+)

enum Status: string {
    case PENDING = 'pending';
    case ACTIVE = 'active';
    case INACTIVE = 'inactive';
    
    public function label(): string {
        return match($this) {
            self::PENDING => 'En attente',
            self::ACTIVE => 'Actif',
            self::INACTIVE => 'Inactif',
        };
    }
}

Défi progression (vers expert)

Mission: créer une mini API PHP avec validation d'entrées, gestion d'erreurs et connexion base de données.

← Retour aux tutoriels