Programmation fonctionnelle en PHP : niveau avancé
PHP est traditionnellement associé aux styles impératif et orienté objet, mais le langage moderne (notamment depuis la version 7.4 et ultérieures) offre des outils puissants pour appliquer le paradigme fonctionnel. Dans cet article, nous allons explorer les concepts avancés de la programmation fonctionnelle (PF) en PHP, qui vous aideront à écrire un code plus prévisible, testable et expressif.
1. Fonctions pures et immuabilité des données
À la base de la PF se trouvent les fonctions pures — des fonctions qui :
- Dépendent uniquement de leurs arguments (n'utilisent pas de variables globales ou d'état en dehors de leur portée) ;
- Ne provoquent pas d'effets secondaires (ne modifient pas de données externes, n'écrivent pas dans des fichiers, n'envoient pas de requêtes HTTP) ;
- Pour les mêmes données d'entrée, retournent toujours le même résultat.
En PHP, pour garantir la pureté des fonctions, on utilise activement l'immuabilité des données. Au lieu de muter des tableaux ou objets existants, on crée leurs copies avec les modifications.
<?php// Fonction impure (utilise un tableau global)$globalData = [1, 2, 3];function addElementImpure($value) { global $globalData; $globalData[] = $value; // Effet secondaire return $globalData;}
// Fonction pure (retourne un nouveau tableau)function addElementPure(array $data, $value): array { $newData = $data; $newData[] = $value; return $newData;}
$original = [1, 2, 3];$modified = addElementPure($original, 4);// $original reste [1, 2, 3], $modified = [1, 2, 3, 4]?>2. Fermetures (Closures) et capture de variables
Les fermetures en PHP sont des fonctions anonymes qui peuvent capturer des variables de la portée parente via le mot-clé use. C'est la base pour créer des fonctions d'ordre supérieur.
Il est important de distinguer la capture par valeur (par défaut) et par référence (&use). Dans le contexte de la PF, la capture par valeur est préférable pour ne pas violer la pureté.
<?php$multiplier = 3;
// Fermeture capturant $multiplier par valeur$multiply = function ($value) use ($multiplier) { return $value * $multiplier;};
echo $multiply(5); // 15
// Exemple de fonction d'ordre supérieur retournant une fermeturefunction createGreeter(string $greeting): Closure { return function (string $name) use ($greeting) { return "{$greeting}, {$name}!"; };}
$sayHello = createGreeter('Bonjour');echo $sayHello('Monde'); // Bonjour, Monde!?>3. Curryfication (Currying) et application partielle
La curryfication est la transformation d'une fonction prenant plusieurs arguments en une séquence de fonctions, chacune prenant un seul argument. L'application partielle consiste à fixer une partie des arguments pour obtenir une nouvelle fonction avec moins de paramètres.
PHP n'a pas de support natif pour la curryfication, mais on peut l'implémenter à l'aide de fermetures.
<?php// Fonction normalefunction add(int $a, int $b, int $c): int { return $a + $b + $c;}
// Version curryfiée$curriedAdd = function (int $a) { return function (int $b) use ($a) { return function (int $c) use ($a, $b) { return $a + $b + $c; }; };};
echo $curriedAdd(1)(2)(3); // 6
// Application partielle avec une fonction auxiliairefunction partial(callable $fn, ...$fixedArgs): Closure { return function (...$remainingArgs) use ($fn, $fixedArgs) { return $fn(...array_merge($fixedArgs, $remainingArgs)); };}
$addFive = partial('add', 2, 3);echo $addFive(10); // 15 (2 + 3 + 10)?>4. Composition de fonctions et pipelines
La composition de fonctions permet de combiner plusieurs fonctions simples en une seule fonction complexe, en passant le résu