MODULE 02

Fonctions & Portée

Type hints, closures, arrow functions, variadiques et fonctions built-in incontournables.

1 Déclaration & appel

Une fonction PHP est déclarée avec function. Elle peut avoir des paramètres avec valeurs par défaut et doit retourner une valeur avec return.

<?php
// Fonction simple
function saluer(string $prenom): string {
    return "Bonjour, $prenom !";
}
echo saluer("Alice"); // Bonjour, Alice !

// Paramètre avec valeur par défaut
function puissance(float $base, int $exp = 2): float {
    return $base ** $exp;
}
echo puissance(3);    // 9.0  (exp par défaut = 2)
echo puissance(3, 3); // 27.0

// Passage par référence — modifie la variable originale
function doubler(float &$n): void {
    $n *= 2; // void = ne retourne rien
}
$x = 5.0;
doubler($x);
echo $x; // 10.0

2 Type hints & return types (PHP 7+)

PHP 7 a introduit le typage strict. Les type hints sont validés à l'exécution et améliorent la lisibilité et la maintenabilité.

<?php
// Types scalaires
function ajouter(int $a, int $b): int { return $a + $b; }

// Type nullable : ?string = string OU null
function trouver(array $tab, string $cle): ?string {
    return $tab[$cle] ?? null;
}

// Union types PHP 8 : int|float
function somme(int|float $a, int|float $b): int|float {
    return $a + $b;
}

// void : la fonction ne retourne rien
function loguer(string $msg): void {
    echo "[LOG] " . htmlspecialchars($msg) . PHP_EOL;
}

// never (PHP 8.1) : la fonction ne retourne JAMAIS (exit ou throw)
function erreurFatale(string $msg): never {
    throw new RuntimeException($msg);
}

// Activer le mode strict (à mettre en tout premier)
// declare(strict_types=1); → PHP refusera les coercitions implicites
💡 Activer declare(strict_types=1); en tête de fichier oblige PHP à refuser les conversions implicites (ex : passer "42" là où un int est attendu).

3 Portée (Scope)

PHP isole les variables locales des fonctions. Contrairement à JavaScript, une variable globale n'est pas accessible dans une fonction sans déclaration explicite.

<?php
$compteur = 0;

function incrementer(): void {
    global $compteur; // déclare l'accès à la variable globale
    $compteur++;
}
incrementer();
echo $compteur; // 1

// Variable statique — conserve sa valeur entre les appels
function compterAppels(): int {
    static $nb = 0; // initialisée UNE SEULE FOIS au premier appel
    return ++$nb;
}
echo compterAppels(); // 1
echo compterAppels(); // 2
echo compterAppels(); // 3
⚠️ L'utilisation de global rend le code difficile à tester. Préférez passer les valeurs en paramètres.

4 Fonctions anonymes & Closures

Une closure est une fonction anonyme qui peut capturer des variables du scope environnant via use.

<?php
// Fonction anonyme assignée à une variable
$multiplier = function(float $x, float $facteur): float {
    return $x * $facteur;
};
echo $multiplier(5, 3); // 15

// Capture par valeur avec use
$tva = 0.20;
$prixTTC = function(float $ht) use ($tva): float {
    return $ht * (1 + $tva);
};
echo $prixTTC(100); // 120

// Capture par référence (la closure peut modifier $tva)
$setTVA = function(float $nouvelleValeur) use (&$tva): void {
    $tva = $nouvelleValeur;
};
$setTVA(0.10);
echo $prixTTC(100); // 110 (tva a changé)

// Retourner une closure (factory)
function createMultiplier(float $facteur): Closure {
    return function(float $n) use ($facteur): float {
        return $n * $facteur;
    };
}
$double = createMultiplier(2);
$triple = createMultiplier(3);
echo $double(5); // 10
echo $triple(5); // 15

5 Arrow functions — PHP 7.4+

Les arrow functions (fn() =>) sont une syntaxe concise pour les closures à expression unique. Elles capturent automatiquement les variables du scope parent (pas besoin de use).

<?php
$facteur = 3;

// Closure classique
$mul = function($n) use ($facteur) { return $n * $facteur; };

// Arrow function équivalente — capture automatique de $facteur
$mul = fn($n) => $n * $facteur;

echo $mul(5); // 15

// Utilisation avec array_map
$prix = [10, 20, 30];
$avecTVA = array_map(fn($p) => $p * 1.2, $prix);
print_r($avecTVA); // [12, 24, 36]

// Imbrication
$addCurried = fn($a) => fn($b) => $a + $b;
echo $addCurried(3)(4); // 7
💡 Les arrow functions ne peuvent contenir qu'une seule expression. Pour plusieurs instructions, utilisez une closure classique avec function() use (...) { ... }.

6 Fonctions variadiques

...$args capture tous les arguments supplémentaires dans un tableau. L'opérateur ... peut aussi "décompresser" un tableau en arguments.

<?php
// Paramètre variadique — reçoit un tableau d'arguments
function somme(float ...$nombres): float {
    return array_sum($nombres);
}
echo somme(1, 2, 3, 4); // 10

// Typage des variadiques
function lister(string $sep, string ...$mots): string {
    return implode($sep, $mots);
}
echo lister(', ', 'PHP', 'MySQL', 'HTML'); // PHP, MySQL, HTML

// Spread operator — décompresse un tableau en arguments
$args = [1, 2, 3];
echo somme(...$args); // 6

// Combiner paramètres normaux et variadiques
function log(string $niveau, string ...$messages): void {
    foreach ($messages as $msg) {
        echo "[$niveau] $msg\n";
    }
}
log('INFO', 'Démarrage', 'Connexion BDD', 'OK');

7 Fonctions built-in incontournables

<?php
// ── Mathématiques ─────────────────────────────────────────
echo abs(-5);           // 5
echo round(3.7);        // 4
echo floor(3.9);        // 3  (arrondi vers le bas)
echo ceil(3.1);         // 4  (arrondi vers le haut)
echo max(1, 5, 3);      // 5
echo min(1, 5, 3);      // 1
echo random_int(1, 100); // entier aléatoire cryptographiquement sûr

// ── Chaînes ───────────────────────────────────────────────
echo strlen("Bonjour");           // 7
echo strtoupper("hello");         // HELLO
echo strtolower("HELLO");         // hello
echo trim("  espaces  ");         // "espaces"
echo str_replace("a", "o", "bar"); // bor
echo substr("Bonjour", 3, 4);     // jour
echo strpos("Bonjour", "jour");   // 3

// ── Tableaux ──────────────────────────────────────────────
$t = [3, 1, 4, 1, 5];
sort($t);                  // trie en place [1,1,3,4,5]
echo count($t);            // 5
echo in_array(4, $t);      // 1 (true)