Maîtrisez les fonctions PHP de A à Z : création, fonctions natives, récursivité, closures et concepts avancés pour structurer votre code efficacement.
Comprendre ce qu'est une fonction, pourquoi les utiliser et comment elles fonctionnent.
Une fonction est un bloc de code réutilisable qui effectue une tâche spécifique. Elle peut recevoir des paramètres en entrée et retourner une valeur.
<?php
// 1. FONCTION SIMPLE SANS PARAMÈTRES
function direBonjour() {
echo "Bonjour tout le monde !";
}
// Appel de la fonction
direBonjour(); // Affiche: Bonjour tout le monde !
// 2. FONCTION AVEC PARAMÈTRES
function saluer($nom) {
echo "Bonjour " . $nom . " !";
}
saluer("Marie"); // Affiche: Bonjour Marie !
// 3. FONCTION AVEC VALEUR DE RETOUR
function additionner($a, $b) {
return $a + $b;
}
$resultat = additionner(5, 3);
echo $resultat; // Affiche: 8
// 4. FONCTION AVEC PLUSIEURS PARAMÈTRES
function calculerAire($longueur, $largeur) {
$aire = $longueur * $largeur;
return $aire;
}
$surface = calculerAire(10, 5);
echo "Surface: " . $surface . " m²"; // Affiche: Surface: 50 m²
// 5. FONCTION AVEC PARAMÈTRES PAR DÉFAUT
function saluerAvecTitre($nom, $titre = "Monsieur") {
return $titre . " " . $nom;
}
echo saluerAvecTitre("Dupont"); // Affiche: Monsieur Dupont
echo saluerAvecTitre("Martin", "Madame"); // Affiche: Madame Martin
// 6. FONCTION AVEC TYPE DE RETOUR SPÉCIFIÉ (PHP 7+)
function diviser(float $a, float $b): float {
if ($b == 0) {
throw new InvalidArgumentException("Division par zéro impossible");
}
return $a / $b;
}
echo diviser(10, 2); // Affiche: 5
// 7. FONCTION SANS VALEUR DE RETOUR (void)
function afficherMessage(string $message): void {
echo "<p>" . htmlspecialchars($message) . "</p>";
}
afficherMessage("Ceci est un message sécurisé");
?>
Apprenez à créer vos propres fonctions avec paramètres, types, et gestion d'erreurs.
<?php
// 1. FONCTION AVEC NOMBRE VARIABLE D'ARGUMENTS
function somme(...$nombres) {
$total = 0;
foreach ($nombres as $nombre) {
$total += $nombre;
}
return $total;
}
echo somme(1, 2, 3); // Affiche: 6
echo somme(1, 2, 3, 4, 5); // Affiche: 15
// 2. FONCTION AVEC TYPES STRICTS
declare(strict_types=1);
function multiplier(int $a, int $b): int {
return $a * $b;
}
echo multiplier(5, 3); // Affiche: 15
// multiplier(5.5, 3); // ERREUR avec strict_types
// 3. FONCTION AVEC PARAMÈTRES NOMMÉS (PHP 8+)
function creerUtilisateur(
string $nom,
string $email,
int $age = 18,
bool $actif = true
) {
return [
'nom' => $nom,
'email' => $email,
'age' => $age,
'actif' => $actif
];
}
// Appel avec paramètres nommés
$user = creerUtilisateur(
nom: "Dupont",
email: "dupont@example.com",
actif: false
);
// 4. FONCTION AVEC RÉFÉRENCE (PASSAGE PAR RÉFÉRENCE)
function incrementer(&$valeur) {
$valeur++;
}
$nombre = 5;
incrementer($nombre);
echo $nombre; // Affiche: 6 (modifié par référence)
// 5. FONCTION AVEC VALEURS PAR DÉFAUT COMPLEXES
function genererRapport(
array $donnees,
string $format = 'html',
array $options = ['titre' => 'Rapport', 'date' => null]
) {
if ($options['date'] === null) {
$options['date'] = date('Y-m-d');
}
return "Rapport {$options['titre']} du {$options['date']} en format $format";
}
echo genererRapport(['data1', 'data2']);
// 6. FONCTION AVEC UNION TYPES (PHP 8+)
function traiterDonnee(int|string|array $donnee): string {
if (is_int($donnee)) {
return "Nombre: " . $donnee;
} elseif (is_string($donnee)) {
return "Texte: " . $donnee;
} elseif (is_array($donnee)) {
return "Tableau: " . implode(', ', $donnee);
}
}
echo traiterDonnee(42); // Nombre: 42
echo traiterDonnee("Hello"); // Texte: Hello
echo traiterDonnee([1, 2, 3]); // Tableau: 1, 2, 3
// 7. FONCTION AVEC NULLABLE TYPES
function obtenirUtilisateur(int $id): ?array {
// Simule une recherche en base de données
if ($id === 1) {
return ['id' => 1, 'nom' => 'Admin'];
}
return null; // Utilisateur non trouvé
}
$user = obtenirUtilisateur(1);
if ($user !== null) {
echo "Utilisateur trouvé: " . $user['nom'];
} else {
echo "Utilisateur non trouvé";
}
// 8. FONCTION AVEC VALIDATION DES PARAMÈTRES
function calculerPourcentage(float $valeur, float $total): float {
if ($total <= 0) {
throw new InvalidArgumentException("Le total doit être positif");
}
if ($valeur < 0) {
throw new InvalidArgumentException("La valeur ne peut pas être négative");
}
return ($valeur / $total) * 100;
}
try {
echo calculerPourcentage(25, 100); // Affiche: 25
} catch (InvalidArgumentException $e) {
echo "Erreur: " . $e->getMessage();
}
?>
Découvrez les fonctions intégrées les plus utiles pour le traitement de chaînes, tableaux et dates.
<?php
// FONCTIONS DE CHAÎNES LES PLUS UTILISÉES
$texte = " Bonjour le Monde! ";
$email = "utilisateur@exemple.com";
$phrase = "PHP est un langage formidable";
// 1. LONGUEUR ET MANIPULATION DE BASE
echo strlen($texte); // Longueur: 19
echo trim($texte); // Supprime espaces: "Bonjour le Monde!"
echo strtoupper($texte); // Majuscules: " BONJOUR LE MONDE! "
echo strtolower($texte); // Minuscules: " bonjour le monde! "
echo ucfirst(trim($texte)); // 1ère lettre maj: "Bonjour le monde!"
echo ucwords(trim($texte)); // Chaque mot maj: "Bonjour Le Monde!"
// 2. RECHERCHE ET REMPLACEMENT
echo strpos($phrase, "PHP"); // Position: 0
echo str_replace("PHP", "JavaScript", $phrase); // Remplacement
echo str_ireplace("php", "Python", $phrase); // Remplacement insensible à la casse
// 3. EXTRACTION ET DÉCOUPAGE
echo substr($phrase, 0, 3); // Extrait: "PHP"
echo substr($phrase, -10); // 10 derniers: "formidable"
$mots = explode(" ", $phrase); // Découpe en tableau
print_r($mots);
// 4. VALIDATION ET TESTS
if (str_contains($email, "@")) {
echo "Email valide";
}
if (str_starts_with($phrase, "PHP")) {
echo "Commence par PHP";
}
if (str_ends_with($phrase, "formidable")) {
echo "Se termine par formidable";
}
// 5. FORMATAGE AVANCÉ
$nom = "Jean";
$age = 25;
// sprintf pour formater
$message = sprintf("Bonjour %s, vous avez %d ans", $nom, $age);
echo $message;
// number_format pour les nombres
$prix = 1234.56;
echo number_format($prix, 2, ',', ' '); // 1 234,56
// 6. FONCTIONS UTILES POUR LA SÉCURITÉ
$input = "<script>alert('XSS')</script>";
echo htmlspecialchars($input); // Échapper HTML
echo strip_tags($input); // Supprimer tags HTML
// 7. EXPRESSIONS RÉGULIÈRES SIMPLES
$telephone = "+33-1-23-45-67-89";
if (preg_match('/^\+33-\d-\d{2}-\d{2}-\d{2}-\d{2}$/', $telephone)) {
echo "Numéro français valide";
}
// Extraire tous les nombres d'une chaîne
$texteAvecNombres = "J'ai 25 ans et 3 chats";
preg_match_all('/\d+/', $texteAvecNombres, $matches);
print_r($matches[0]); // [25, 3]
// 8. FONCTIONS PRATIQUES AVANCÉES
function nettoyer($texte) {
$texte = trim($texte);
$texte = htmlspecialchars($texte);
$texte = stripslashes($texte);
return $texte;
}
function genererSlug($titre) {
$slug = strtolower($titre);
$slug = preg_replace('/[^a-z0-9]+/', '-', $slug);
$slug = trim($slug, '-');
return $slug;
}
echo genererSlug("Mon Premier Article!"); // mon-premier-article
// 9. CHIFFREMENT SIMPLE
$motDePasse = "monMotDePasse123";
$hash = password_hash($motDePasse, PASSWORD_DEFAULT);
echo $hash;
// Vérification
if (password_verify($motDePasse, $hash)) {
echo "Mot de passe correct";
}
// 10. FONCTIONS MULTI-BYTES (UTF-8)
$texteUtf8 = "Café, naïve, 北京";
echo mb_strlen($texteUtf8); // Longueur correcte en UTF-8
echo mb_substr($texteUtf8, 0, 4); // Extraction UTF-8
echo mb_strtoupper($texteUtf8); // Majuscules UTF-8
?>
<?php
// FONCTIONS DE TABLEAUX ESSENTIELLES
$fruits = ['pomme', 'banane', 'orange', 'kiwi'];
$notes = [12, 15, 8, 20, 14];
$personne = ['nom' => 'Dupont', 'age' => 30, 'ville' => 'Paris'];
// 1. INFORMATIONS SUR LE TABLEAU
echo count($fruits); // Nombre d'éléments: 4
echo sizeof($notes); // Alias de count()
var_dump(is_array($fruits)); // Vérifie si c'est un tableau: true
var_dump(empty($fruits)); // Vérifie si vide: false
// 2. AJOUT ET SUPPRESSION D'ÉLÉMENTS
array_push($fruits, 'mangue'); // Ajoute à la fin
array_unshift($fruits, 'fraise'); // Ajoute au début
$dernierFruit = array_pop($fruits); // Retire et retourne le dernier
$premierFruit = array_shift($fruits); // Retire et retourne le premier
// 3. RECHERCHE ET VÉRIFICATION
if (in_array('pomme', $fruits)) {
echo "Pomme trouvée";
}
$position = array_search('banane', $fruits);
if ($position !== false) {
echo "Banane trouvée à la position: $position";
}
if (array_key_exists('nom', $personne)) {
echo "Clé 'nom' existe";
}
// 4. TRANSFORMATION ET FILTRAGE
$notesPlusUn = array_map(function($note) {
return $note + 1;
}, $notes);
$bonnesNotes = array_filter($notes, function($note) {
return $note >= 15;
});
$total = array_reduce($notes, function($carry, $note) {
return $carry + $note;
}, 0);
// 5. TRI ET ORDRE
$nombresDesordres = [3, 1, 4, 1, 5, 9, 2, 6];
sort($nombresDesordres); // Tri croissant (réindexe)
rsort($nombresDesordres); // Tri décroissant (réindexe)
$personnesTri = [
['nom' => 'Alice', 'age' => 25],
['nom' => 'Bob', 'age' => 30],
['nom' => 'Charlie', 'age' => 20]
];
// Tri par âge
usort($personnesTri, function($a, $b) {
return $a['age'] <=> $b['age'];
});
// 6. FUSION ET COMBINAISON
$fruits1 = ['pomme', 'banane'];
$fruits2 = ['orange', 'kiwi'];
$tousFruits = array_merge($fruits1, $fruits2);
$cles = ['nom', 'age', 'ville'];
$valeurs = ['Martin', 28, 'Lyon'];
$utilisateur = array_combine($cles, $valeurs);
// 7. EXTRACTION ET DÉCOUPAGE
$prendsDeuxPremiers = array_slice($fruits, 0, 2);
$prendsDeuxDerniers = array_slice($fruits, -2);
$morceau = array_splice($fruits, 1, 2); // Retire et retourne 2 éléments à partir de l'index 1
// 8. FONCTIONS MATHÉMATIQUES
echo max($notes); // Plus grande valeur: 20
echo min($notes); // Plus petite valeur: 8
echo array_sum($notes); // Somme: 69
echo array_product([2, 3, 4]); // Produit: 24
// 9. FONCTIONS AVANCÉES PRATIQUES
function obtenirStatsTableau(array $nombres): array {
return [
'count' => count($nombres),
'sum' => array_sum($nombres),
'average' => array_sum($nombres) / count($nombres),
'min' => min($nombres),
'max' => max($nombres)
];
}
$stats = obtenirStatsTableau($notes);
print_r($stats);
// 10. MANIPULATION DE TABLEAUX MULTIDIMENSIONNELS
$etudiants = [
['nom' => 'Alice', 'notes' => [15, 17, 12]],
['nom' => 'Bob', 'notes' => [18, 16, 14]],
['nom' => 'Charlie', 'notes' => [13, 15, 16]]
];
// Extraire tous les noms
$noms = array_column($etudiants, 'nom');
print_r($noms);
// Calculer moyenne pour chaque étudiant
$etudiantsAvecMoyenne = array_map(function($etudiant) {
$etudiant['moyenne'] = array_sum($etudiant['notes']) / count($etudiant['notes']);
return $etudiant;
}, $etudiants);
// 11. FONCTIONS DE CLÉS ET VALEURS
$cles = array_keys($personne); // ['nom', 'age', 'ville']
$valeurs = array_values($personne); // ['Dupont', 30, 'Paris']
$inverse = array_flip(['a' => 1, 'b' => 2]); // [1 => 'a', 2 => 'b']
// 12. TABLEAUX UNIQUES ET DIFFÉRENCES
$nombres = [1, 2, 2, 3, 3, 4];
$nombresUniques = array_unique($nombres); // [1, 2, 3, 4]
$groupe1 = ['Alice', 'Bob', 'Charlie'];
$groupe2 = ['Bob', 'David', 'Eve'];
$seulement1 = array_diff($groupe1, $groupe2); // ['Alice', 'Charlie']
$communs = array_intersect($groupe1, $groupe2); // ['Bob']
?>
Explorez les fonctions anonymes, closures et arrow functions pour une programmation moderne.
// FONCTIONS ANONYMES ET CLOSURES
// 1. FONCTION ANONYME SIMPLE
$saluer = function($nom) {
return "Bonjour " . $nom;
};
echo $saluer("Marie"); // Bonjour Marie
// 2. FONCTION ANONYME AVEC USE (CLOSURE)
$multiplicateur = 3;
$multiplier = function($nombre) use ($multiplicateur) {
return $nombre * $multiplicateur;
};
echo $multiplier(5); // 15
// 3. CLOSURE AVEC RÉFÉRENCE
$compteur = 0;
$incrementer = function() use (&$compteur) {
$compteur++;
return $compteur;
};
echo $incrementer(); // 1
echo $incrementer(); // 2
echo $compteur; // 2 (modifié par référence)
// 4. ARROW FUNCTIONS (PHP 7.4+)
$nombres = [1, 2, 3, 4, 5];
// Fonction classique
$carres1 = array_map(function($n) {
return $n * $n;
}, $nombres);
// Arrow function (plus concise)
$carres2 = array_map(fn($n) => $n * $n, $nombres);
// 5. FONCTION QUI RETOURNE UNE FONCTION
function creerMultiplicateur($facteur) {
return function($nombre) use ($facteur) {
return $nombre * $facteur;
};
}
$double = creerMultiplicateur(2);
$triple = creerMultiplicateur(3);
echo $double(5); // 10
echo $triple(5); // 15
// 6. CALLBACK FUNCTIONS
function traiterTableau(array $tableau, callable $callback) {
$resultat = [];
foreach ($tableau as $element) {
$resultat[] = $callback($element);
}
return $resultat;
}
$nombres = [1, 2, 3, 4];
// Avec fonction anonyme
$doubles = traiterTableau($nombres, function($n) {
return $n * 2;
});
// Avec arrow function
$carres = traiterTableau($nombres, fn($n) => $n ** 2);
// 7. FONCTIONS D'ORDRE SUPÉRIEUR
function compose(callable $f, callable $g) {
return function($x) use ($f, $g) {
return $f($g($x));
};
}
$addOne = fn($x) => $x + 1;
$double = fn($x) => $x * 2;
$addOneThenDouble = compose($double, $addOne);
echo $addOneThenDouble(5); // (5 + 1) * 2 = 12
// 8. MEMOIZATION AVEC CLOSURES
function memoize(callable $func) {
$cache = [];
return function(...$args) use ($func, &$cache) {
$key = serialize($args);
if (!isset($cache[$key])) {
$cache[$key] = $func(...$args);
}
return $cache[$key];
};
}
// Fibonacci avec memoization
$fibonacci = memoize(function($n) use (&$fibonacci) {
if ($n <= 1) return $n;
return $fibonacci($n - 1) + $fibonacci($n - 2);
});
echo $fibonacci(40); // Très rapide grâce au cache
// 9. EVENT LISTENERS AVEC CLOSURES
class EventEmitter {
private $listeners = [];
public function on($event, callable $callback) {
$this->listeners[$event][] = $callback;
}
public function emit($event, ...$args) {
if (isset($this->listeners[$event])) {
foreach ($this->listeners[$event] as $callback) {
$callback(...$args);
}
}
}
}
$emitter = new EventEmitter();
// Ajout d'listeners avec closures
$emitter->on('user.login', function($user) {
echo "Utilisateur connecté: " . $user['nom'];
});
$emitter->on('user.login', function($user) {
// Log dans un fichier
file_put_contents('login.log', date('Y-m-d H:i:s') . " - " . $user['nom'] . "\n", FILE_APPEND);
});
$emitter->emit('user.login', ['nom' => 'Alice']);
// 10. FACTORY PATTERN AVEC CLOSURES
function createValidator() {
$rules = [];
return [
'addRule' => function($field, callable $rule) use (&$rules) {
$rules[$field][] = $rule;
},
'validate' => function($data) use (&$rules) {
$errors = [];
foreach ($rules as $field => $fieldRules) {
if (isset($data[$field])) {
foreach ($fieldRules as $rule) {
$result = $rule($data[$field]);
if ($result !== true) {
$errors[$field][] = $result;
}
}
}
}
return $errors;
}
];
}
$validator = createValidator();
$validator['addRule']('email', function($value) {
return filter_var($value, FILTER_VALIDATE_EMAIL) ? true : 'Email invalide';
});
$validator['addRule']('age', function($value) {
return ($value >= 18) ? true : 'Doit être majeur';
});
$errors = $validator['validate']([
'email' => 'invalid-email',
'age' => 16
]);
print_r($errors);
// 11. CURRYING (FONCTIONS PARTIELLES)
function curry(callable $func, int $arity = null) {
$arity = $arity ?? (new ReflectionFunction($func))->getNumberOfParameters();
return function(...$args) use ($func, $arity) {
if (count($args) >= $arity) {
return $func(...$args);
}
return curry(function(...$nextArgs) use ($func, $args) {
return $func(...array_merge($args, $nextArgs));
}, $arity - count($args));
};
}
$add = curry(function($a, $b, $c) {
return $a + $b + $c;
});
$add5 = $add(5);
$add5and3 = $add5(3);
echo $add5and3(2); // 10
Comprenez la récursivité avec des exemples pratiques et des optimisations.
<?php
// FONCTIONS RÉCURSIVES : EXEMPLES ET OPTIMISATIONS
// 1. FACTORIELLE (EXEMPLE CLASSIQUE)
function factorielle($n) {
// Cas de base (condition d'arrêt)
if ($n <= 1) {
return 1;
}
// Appel récursif
return $n * factorielle($n - 1);
}
echo factorielle(5); // 120 (5 * 4 * 3 * 2 * 1)
// 2. FIBONACCI (VERSION NAÏVE)
function fibonacci($n) {
if ($n <= 1) {
return $n;
}
return fibonacci($n - 1) + fibonacci($n - 2);
}
echo fibonacci(10); // 55 (mais très lent pour grandes valeurs)
// 3. FIBONACCI OPTIMISÉ AVEC MEMOIZATION
function fibonacciMemo($n, &$cache = []) {
if ($n <= 1) {
return $n;
}
if (isset($cache[$n])) {
return $cache[$n];
}
$cache[$n] = fibonacciMemo($n - 1, $cache) + fibonacciMemo($n - 2, $cache);
return $cache[$n];
}
echo fibonacciMemo(50); // Beaucoup plus rapide !
// 4. PARCOURS D'ARBORESCENCE
function parcourirDossier($chemin, $niveau = 0) {
$resultat = [];
$indentation = str_repeat(" ", $niveau);
if (is_dir($chemin)) {
$resultat[] = $indentation . "📁 " . basename($chemin);
$fichiers = scandir($chemin);
foreach ($fichiers as $fichier) {
if ($fichier !== '.' && $fichier !== '..') {
$cheminComplet = $chemin . DIRECTORY_SEPARATOR . $fichier;
if (is_dir($cheminComplet)) {
// Appel récursif pour les sous-dossiers
$resultat = array_merge($resultat, parcourirDossier($cheminComplet, $niveau + 1));
} else {
$resultat[] = $indentation . " 📄 " . $fichier;
}
}
}
}
return $resultat;
}
// Utilisation
$arborescence = parcourirDossier('/chemin/vers/dossier');
foreach ($arborescence as $element) {
echo $element . "\n";
}
// 5. CALCUL DE PUISSANCE
function puissance($base, $exposant) {
// Cas de base
if ($exposant === 0) {
return 1;
}
if ($exposant === 1) {
return $base;
}
// Optimisation : division de l'exposant par 2
if ($exposant % 2 === 0) {
$temp = puissance($base, $exposant / 2);
return $temp * $temp;
} else {
return $base * puissance($base, $exposant - 1);
}
}
echo puissance(2, 10); // 1024
// 6. RECHERCHE BINAIRE RÉCURSIVE
function rechercheBinaire($tableau, $valeur, $debut = 0, $fin = null) {
if ($fin === null) {
$fin = count($tableau) - 1;
}
// Cas de base : élément non trouvé
if ($debut > $fin) {
return -1;
}
$milieu = intval(($debut + $fin) / 2);
// Cas de base : élément trouvé
if ($tableau[$milieu] === $valeur) {
return $milieu;
}
// Récursion sur la moitié appropriée
if ($tableau[$milieu] > $valeur) {
return rechercheBinaire($tableau, $valeur, $debut, $milieu - 1);
} else {
return rechercheBinaire($tableau, $valeur, $milieu + 1, $fin);
}
}
$tableauTrie = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19];
echo rechercheBinaire($tableauTrie, 7); // Position 3
// 7. GÉNÉRATION DE PERMUTATIONS
function genererPermutations($elements) {
// Cas de base
if (count($elements) <= 1) {
return [$elements];
}
$permutations = [];
for ($i = 0; $i < count($elements); $i++) {
// Élément actuel
$elementActuel = $elements[$i];
// Éléments restants
$elementsRestants = array_merge(
array_slice($elements, 0, $i),
array_slice($elements, $i + 1)
);
// Générer permutations pour les éléments restants
$permutationsRestantes = genererPermutations($elementsRestants);
// Ajouter l'élément actuel à chaque permutation
foreach ($permutationsRestantes as $permutation) {
$permutations[] = array_merge([$elementActuel], $permutation);
}
}
return $permutations;
}
$permutations = genererPermutations(['A', 'B', 'C']);
foreach ($permutations as $perm) {
echo implode('', $perm) . " ";
}
// Affiche: ABC ACB BAC BCA CAB CBA
// 8. ALGORITHME DU TRI RAPIDE (QUICKSORT)
function triRapide($tableau) {
$longueur = count($tableau);
// Cas de base
if ($longueur <= 1) {
return $tableau;
}
// Choisir un pivot (ici le premier élément)
$pivot = $tableau[0];
$gauche = [];
$droite = [];
// Partitionner autour du pivot
for ($i = 1; $i < $longueur; $i++) {
if ($tableau[$i] <= $pivot) {
$gauche[] = $tableau[$i];
} else {
$droite[] = $tableau[$i];
}
}
// Récursion et combinaison
return array_merge(
triRapide($gauche),
[$pivot],
triRapide($droite)
);
}
$tableauDesordonne = [64, 34, 25, 12, 22, 11, 90];
$tableauTrie = triRapide($tableauDesordonne);
print_r($tableauTrie);
// 9. VALIDATION D'EXPRESSION PARENTHÉSÉE
function validerParentheses($expression, $index = 0, $compteur = 0) {
// Cas de base : fin de chaîne
if ($index >= strlen($expression)) {
return $compteur === 0;
}
$caractere = $expression[$index];
if ($caractere === '(') {
$compteur++;
} elseif ($caractere === ')') {
$compteur--;
// Si compteur négatif, parenthèse fermante sans ouvrante
if ($compteur < 0) {
return false;
}
}
// Récursion pour le caractère suivant
return validerParentheses($expression, $index + 1, $compteur);
}
echo validerParentheses("((()))") ? "Valide" : "Invalide"; // Valide
echo validerParentheses("((())") ? "Valide" : "Invalide"; // Invalide
// 10. CONVERSION D'ITERATION EN RÉCURSION
class RecursionHelper {
// Version itérative de la somme
public static function sommeIterative($n) {
$somme = 0;
for ($i = 1; $i <= $n; $i++) {
$somme += $i;
}
return $somme;
}
// Version récursive de la somme
public static function sommeRecursive($n) {
if ($n <= 0) {
return 0;
}
return $n + self::sommeRecursive($n - 1);
}
// Optimisation avec récursion terminale
public static function sommeRecursiveOptimisee($n, $accumulator = 0) {
if ($n <= 0) {
return $accumulator;
}
return self::sommeRecursiveOptimisee($n - 1, $accumulator + $n);
}
}
echo RecursionHelper::sommeIterative(100); // 5050
echo RecursionHelper::sommeRecursive(100); // 5050
echo RecursionHelper::sommeRecursiveOptimisee(100); // 5050 (plus efficace)
// 11. GESTION DES ERREURS EN RÉCURSION
function factorielleSecurisee($n, $maxDepth = 100, $currentDepth = 0) {
// Vérification de la profondeur pour éviter stack overflow
if ($currentDepth > $maxDepth) {
throw new RuntimeException("Profondeur de récursion dépassée");
}
// Validation des paramètres
if (!is_int($n) || $n < 0) {
throw new InvalidArgumentException("Doit être un entier positif");
}
// Cas de base
if ($n <= 1) {
return 1;
}
// Récursion avec compteur de profondeur
return $n * factorielleSecurisee($n - 1, $maxDepth, $currentDepth + 1);
}
try {
echo factorielleSecurisee(5); // 120
echo factorielleSecurisee(-1); // Exception
} catch (Exception $e) {
echo "Erreur: " . $e->getMessage();
}
?>
Découvrez les concepts avancés : générateurs, réflexion, et patterns de programmation fonctionnelle.
<?php
// CONCEPTS AVANCÉS DES FONCTIONS PHP
// 1. GÉNÉRATEURS (YIELD)
function genererNombres($max) {
for ($i = 1; $i <= $max; $i++) {
yield $i; // Génère une valeur à la demande
}
}
// Utilisation : économise la mémoire
foreach (genererNombres(1000000) as $nombre) {
if ($nombre > 5) break;
echo $nombre . " ";
}
// 2. GÉNÉRATEUR AVEC CLÉS
function genererPaires() {
yield 'nom' => 'Alice';
yield 'age' => 25;
yield 'ville' => 'Paris';
}
foreach (genererPaires() as $cle => $valeur) {
echo "$cle: $valeur\n";
}
// 3. RÉFLEXION SUR LES FONCTIONS
function exempleFunction($param1, $param2 = 'default') {
return $param1 . $param2;
}
$reflection = new ReflectionFunction('exempleFunction');
echo "Nom: " . $reflection->getName();
echo "Nombre de paramètres: " . $reflection->getNumberOfParameters();
echo "Fichier: " . $reflection->getFileName();
foreach ($reflection->getParameters() as $param) {
echo "Paramètre: " . $param->getName();
if ($param->isDefaultValueAvailable()) {
echo " (défaut: " . $param->getDefaultValue() . ")";
}
}
// 4. FONCTIONS VARIABLES
$nomFonction = 'strlen';
echo $nomFonction('Hello'); // Appelle strlen('Hello')
// Avec vérification
if (function_exists($nomFonction)) {
echo $nomFonction('World');
}
// 5. CALL_USER_FUNC ET VARIANTES
call_user_func('phpinfo'); // Appelle phpinfo()
call_user_func_array('array_merge', [['a'], ['b']]); // array_merge(['a'], ['b'])
// Avec objets
class Calculator {
public function add($a, $b) {
return $a + $b;
}
}
$calc = new Calculator();
echo call_user_func([$calc, 'add'], 5, 3); // 8
// 6. DESIGN PATTERN: STRATEGY AVEC FUNCTIONS
class PaymentProcessor {
private $strategies = [];
public function addStrategy($name, callable $strategy) {
$this->strategies[$name] = $strategy;
}
public function process($method, $amount) {
if (!isset($this->strategies[$method])) {
throw new InvalidArgumentException("Méthode de paiement inconnue");
}
return $this->strategies[$method]($amount);
}
}
$processor = new PaymentProcessor();
$processor->addStrategy('carte', function($amount) {
return "Paiement de {$amount}€ par carte (commission: 2%)";
});
$processor->addStrategy('paypal', function($amount) {
return "Paiement de {$amount}€ via PayPal (commission: 3%)";
});
echo $processor->process('carte', 100);
// 7. MIDDLEWARE PATTERN
class MiddlewareStack {
private $middlewares = [];
public function add(callable $middleware) {
$this->middlewares[] = $middleware;
}
public function execute($request) {
$response = $request;
foreach ($this->middlewares as $middleware) {
$response = $middleware($response);
}
return $response;
}
}
$stack = new MiddlewareStack();
$stack->add(function($request) {
$request['timestamp'] = time();
return $request;
});
$stack->add(function($request) {
$request['processed'] = true;
return $request;
});
$result = $stack->execute(['data' => 'test']);
print_r($result);
// 8. FUNCTION COMPOSITION AVANCÉE
function pipe(...$functions) {
return function($value) use ($functions) {
return array_reduce($functions, function($carry, $func) {
return $func($carry);
}, $value);
};
}
$pipeline = pipe(
fn($x) => $x * 2,
fn($x) => $x + 10,
fn($x) => $x / 3
);
echo $pipeline(5); // ((5 * 2) + 10) / 3 = 6.67
// 9. LAZY EVALUATION
class LazyValue {
private $computed = false;
private $value;
private $computation;
public function __construct(callable $computation) {
$this->computation = $computation;
}
public function get() {
if (!$this->computed) {
$this->value = ($this->computation)();
$this->computed = true;
}
return $this->value;
}
}
$lazy = new LazyValue(function() {
echo "Calcul coûteux exécuté\n";
return array_sum(range(1, 1000000));
});
// Le calcul n'est pas encore exécuté
echo "Avant get()\n";
echo $lazy->get(); // Maintenant le calcul s'exécute
echo $lazy->get(); // Utilise la valeur mise en cache
// 10. FUNCTION DECORATORS
function benchmark(callable $func) {
return function(...$args) use ($func) {
$start = microtime(true);
$result = $func(...$args);
$end = microtime(true);
echo "Execution time: " . ($end - $start) . " seconds\n";
return $result;
};
}
function cache(callable $func) {
$cache = [];
return function(...$args) use ($func, &$cache) {
$key = serialize($args);
if (!isset($cache[$key])) {
$cache[$key] = $func(...$args);
}
return $cache[$key];
};
}
// Décorer une fonction
$slowFunction = function($n) {
usleep(100000); // Simule une opération lente
return $n * $n;
};
$cachedFunction = cache($slowFunction);
$benchmarkedFunction = benchmark($cachedFunction);
echo $benchmarkedFunction(5); // Lent la première fois
echo $benchmarkedFunction(5); // Rapide la deuxième fois (cache)
?>
Fonctions utiles et prêtes à l'emploi pour vos projets PHP.
<?php
// CONCEPTS AVANCÉS DES FONCTIONS PHP
// 1. GÉNÉRATEURS (YIELD)
function genererNombres($max) {
for ($i = 1; $i <= $max; $i++) {
yield $i; // Génère une valeur à la demande
}
}
// Utilisation : économise la mémoire
foreach (genererNombres(1000000) as $nombre) {
if ($nombre > 5) break;
echo $nombre . " ";
}
// 2. GÉNÉRATEUR AVEC CLÉS
function genererPaires() {
yield 'nom' => 'Alice';
yield 'age' => 25;
yield 'ville' => 'Paris';
}
foreach (genererPaires() as $cle => $valeur) {
echo "$cle: $valeur\n";
}
// 3. RÉFLEXION SUR LES FONCTIONS
function exempleFunction($param1, $param2 = 'default') {
return $param1 . $param2;
}
$reflection = new ReflectionFunction('exempleFunction');
echo "Nom: " . $reflection->getName();
echo "Nombre de paramètres: " . $reflection->getNumberOfParameters();
echo "Fichier: " . $reflection->getFileName();
foreach ($reflection->getParameters() as $param) {
echo "Paramètre: " . $param->getName();
if ($param->isDefaultValueAvailable()) {
echo " (défaut: " . $param->getDefaultValue() . ")";
}
}
// 4. FONCTIONS VARIABLES
$nomFonction = 'strlen';
echo $nomFonction('Hello'); // Appelle strlen('Hello')
// Avec vérification
if (function_exists($nomFonction)) {
echo $nomFonction('World');
}
// 5. CALL_USER_FUNC ET VARIANTES
call_user_func('phpinfo'); // Appelle phpinfo()
call_user_func_array('array_merge', [['a'], ['b']]); // array_merge(['a'], ['b'])
// Avec objets
class Calculator {
public function add($a, $b) {
return $a + $b;
}
}
$calc = new Calculator();
echo call_user_func([$calc, 'add'], 5, 3); // 8
// 6. DESIGN PATTERN: STRATEGY AVEC FUNCTIONS
class PaymentProcessor {
private $strategies = [];
public function addStrategy($name, callable $strategy) {
$this->strategies[$name] = $strategy;
}
public function process($method, $amount) {
if (!isset($this->strategies[$method])) {
throw new InvalidArgumentException("Méthode de paiement inconnue");
}
return $this->strategies[$method]($amount);
}
}
$processor = new PaymentProcessor();
$processor->addStrategy('carte', function($amount) {
return "Paiement de {$amount}€ par carte (commission: 2%)";
});
$processor->addStrategy('paypal', function($amount) {
return "Paiement de {$amount}€ via PayPal (commission: 3%)";
});
echo $processor->process('carte', 100);
// 7. MIDDLEWARE PATTERN
class MiddlewareStack {
private $middlewares = [];
public function add(callable $middleware) {
$this->middlewares[] = $middleware;
}
public function execute($request) {
$response = $request;
foreach ($this->middlewares as $middleware) {
$response = $middleware($response);
}
return $response;
}
}
$stack = new MiddlewareStack();
$stack->add(function($request) {
$request['timestamp'] = time();
return $request;
});
$stack->add(function($request) {
$request['processed'] = true;
return $request;
});
$result = $stack->execute(['data' => 'test']);
print_r($result);
// 8. FUNCTION COMPOSITION AVANCÉE
function pipe(...$functions) {
return function($value) use ($functions) {
return array_reduce($functions, function($carry, $func) {
return $func($carry);
}, $value);
};
}
$pipeline = pipe(
fn($x) => $x * 2,
fn($x) => $x + 10,
fn($x) => $x / 3
);
echo $pipeline(5); // ((5 * 2) + 10) / 3 = 6.67
// 9. LAZY EVALUATION
class LazyValue {
private $computed = false;
private $value;
private $computation;
public function __construct(callable $computation) {
$this->computation = $computation;
}
public function get() {
if (!$this->computed) {
$this->value = ($this->computation)();
$this->computed = true;
}
return $this->value;
}
}
$lazy = new LazyValue(function() {
echo "Calcul coûteux exécuté\n";
return array_sum(range(1, 1000000));
});
// Le calcul n'est pas encore exécuté
echo "Avant get()\n";
echo $lazy->get(); // Maintenant le calcul s'exécute
echo $lazy->get(); // Utilise la valeur mise en cache
// 10. FUNCTION DECORATORS
function benchmark(callable $func) {
return function(...$args) use ($func) {
$start = microtime(true);
$result = $func(...$args);
$end = microtime(true);
echo "Execution time: " . ($end - $start) . " seconds\n";
return $result;
};
}
function cache(callable $func) {
$cache = [];
return function(...$args) use ($func, &$cache) {
$key = serialize($args);
if (!isset($cache[$key])) {
$cache[$key] = $func(...$args);
}
return $cache[$key];
};
}
// Décorer une fonction
$slowFunction = function($n) {
usleep(100000); // Simule une opération lente
return $n * $n;
};
$cachedFunction = cache($slowFunction);
$benchmarkedFunction = benchmark($cachedFunction);
echo $benchmarkedFunction(5); // Lent la première fois
echo $benchmarkedFunction(5); // Rapide la deuxième fois (cache)
?>
Vous maîtrisez maintenant tous les aspects des fonctions PHP : création, natives, récursivité, closures et concepts avancés. Passez au niveau supérieur !
Syntaxe Fonctions • Paramètres Avancés • Fonctions Natives • Closures • Récursivité • Générateurs • Concepts Avancés