PHP tableaux
Organiser son code avec des fonctions : des plus simples aux closures et à la récursivité.
- Créer une fonction
- Fonctions natives
- Closures
Bases des Fonctions PHP
Comprendre ce qu'est une fonction, pourquoi les utiliser et comment elles fonctionnent.
🎯 Qu'est-ce qu'une Fonction ?
Concept et Avantages :
🔧 Définition :
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.
✅ Avantages :
- Réutilisabilité du code
- Organisation et structure
- Facilité de maintenance
- Tests plus simples
- Lisibilité améliorée
Anatomie d'une Fonction :
php
// Structure d'une fonction PHP
function nomDeLaFonction($param1, $param2) {
// Corps de la fonction
$resultat = $param1 + $param2;
return $resultat; // Valeur retournée
}
// Appel de la fonction
$somme = nomDeLaFonction(5, 3);
📝 Syntaxe et Premiers Exemples
php
<?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é");
?>
Création de Fonctions Personnalisées
Apprenez à créer vos propres fonctions avec paramètres, types, et gestion d'erreurs.
⚙️ Paramètres et Arguments Avancés
php
<?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();
}
?>
Fonctions Natives PHP Essentielles
Découvrez les fonctions intégrées les plus utiles pour le traitement de chaînes, tableaux et dates.
📝 Fonctions de Chaînes de Caractères
php
<?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
?>
📋 Fonctions de Tableaux
php
<?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']
?>
Fonctions Anonymes et Closures
Explorez les fonctions anonymes, closures et arrow functions pour une programmation moderne.
⚡ Fonctions Anonymes et Closures
php
// 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
Fonctions Récursives
Comprenez la récursivité avec des exemples pratiques et des optimisations.
🔄 Récursivité : Théorie et Pratique
php
<?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();
}
?>
Concepts Avancés
Découvrez les concepts avancés : générateurs, réflexion, et patterns de programmation fonctionnelle.
🚀 Générateurs et Concepts Avancés
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)
?>
Exemples Pratiques à Copier
Fonctions utiles et prêtes à l'emploi pour vos projets PHP.
🛠️ Fonctions Utilitaires Pratiques
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)
?>
PHP maîtrisé
Meilleures Pratiques pour les Fonctions PHP
✅ À FAIRE :
• Utiliser des noms de fonctions descriptifs
• Limiter les fonctions à une seule responsabilité
• Utiliser le typage strict (declare(strict_types=1))
• Documenter avec PHPDoc
• Valider les paramètres d'entrée
• Gérer les erreurs avec des exceptions
• Préférer la composition à l'héritage
❌ À ÉVITER :
• Fonctions trop longues (plus de 20-30 lignes)
• Trop de paramètres (plus de 3-4)
• Effets de bord non documentés
• Variables globales dans les fonctions
• Récursion sans limite de profondeur
• Mélanger logique métier et présentation
• Ignorer les valeurs de retour des fonctions
Fonctions PHP Maîtrisées !
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 !
🎯 Compétences acquises :
Syntaxe Fonctions • Paramètres Avancés • Fonctions Natives • Closures • Récursivité • Générateurs • Concepts Avancés
Fonctions PHP maîtrisées
Paramètres, portée, closures et récursivité : votre code peut enfin se réutiliser.