JavaScript pour débuter
Indexés, associatifs, imbriqués : le tableau est la structure de données centrale de PHP.
- Indexés et associatifs
- Fonctions natives
- Multidimensionnels
Bases des Tableaux PHP
Comprendre ce qu'est un tableau, les différents types et leur utilisation.
📊 Qu'est-ce qu'un Tableau ?
Concept et Types :
📋 Définition :
Un tableau est une structure de données qui permet de stocker plusieurs valeurs dans une seule variable. PHP propose des tableaux très flexibles.
🏷️ Types de tableaux :
- Indexés : indices numériques (0, 1, 2...)
- Associatifs : clés personnalisées
- Multidimensionnels : tableaux de tableaux
Syntaxes de création :
php
// Syntaxe moderne (PHP 5.4+)
$fruits = ['pomme', 'banane', 'orange'];
// Syntaxe classique
$fruits = array('pomme',
'banane', 'orange');
// Tableau associatif
$personne = [
'nom' => 'Dupont',
'age' => 30
];
🏷️ Types de Tableaux en Détail
php
<?php
// 1. TABLEAUX INDEXÉS (NUMÉRIQUES)
$couleurs = ['rouge', 'vert', 'bleu'];
echo $couleurs[0]; // rouge
echo $couleurs[1]; // vert
// Indices automatiques
$nombres = [];
$nombres[] = 10; // index 0
$nombres[] = 20; // index 1
$nombres[] = 30; // index 2
// Indices explicites
$notes = [
0 => 15,
1 => 12,
2 => 18
];
// 2. TABLEAUX ASSOCIATIFS (CLÉS PERSONNALISÉES)
$utilisateur = [
'nom' => 'Dupont',
'prenom' => 'Jean',
'age' => 25,
'email' => 'jean.dupont@email.com',
'actif' => true
];
echo $utilisateur['nom']; // Dupont
echo $utilisateur['age']; // 25
// Configuration d'application
$config = [
'database' => [
'host' => 'localhost',
'user' => 'root',
'password' => 'secret'
],
'app' => [
'name' => 'Mon App',
'version' => '1.0'
]
];
// 3. TABLEAUX MIXTES (INDICES ET CLÉS)
$mixte = [
0 => 'première valeur',
'nom' => 'John',
1 => 'deuxième valeur',
'age' => 30
];
// 4. TABLEAUX MULTIDIMENSIONNELS
$etudiants = [
[
'nom' => 'Alice',
'notes' => [15, 17, 12]
],
[
'nom' => 'Bob',
'notes' => [18, 16, 14]
]
];
echo $etudiants[0]['nom']; // Alice
echo $etudiants[0]['notes'][1]; // 17
// 5. TABLEAUX D'OBJETS
class Produit {
public function __construct(public $nom, public $prix) {}
}
$produits = [
new Produit('Ordinateur', 999),
new Produit('Souris', 25),
new Produit('Clavier', 75)
];
foreach ($produits as $produit) {
echo $produit->nom . ' : ' . $produit->prix . '€';
}
// 6. TABLEAUX CONSTANTS
const JOURS_SEMAINE = ['Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi'];
define('COULEURS', ['rouge', 'vert', 'bleu']);
// 7. VÉRIFICATION DU TYPE
var_dump(is_array($couleurs)); // true
var_dump(array_is_list($couleurs)); // true (PHP 8.1+)
var_dump(array_is_list($utilisateur)); // false
// 8. INFORMATIONS SUR LES TABLEAUX
echo count($couleurs); // 3
echo sizeof($utilisateur); // 5 (alias de count)
var_dump(empty($couleurs)); // false
// Taille récursive (tableaux multidimensionnels)
echo count($etudiants, COUNT_RECURSIVE); // Compte tous les éléments
// 9. ACCÈS AUX ÉLÉMENTS
// Avec vérification d'existence
$nom = isset($utilisateur['nom']) ? $utilisateur['nom'] : 'Inconnu';
// Opérateur null coalescing (PHP 7+)
$nom = $utilisateur['nom'] ?? 'Inconnu';
// Accès avec clé dynamique
$cle = 'age';
echo $utilisateur[$cle]; // 25
?>
Création et Manipulation
Apprenez à créer, modifier et manipuler efficacement vos tableaux PHP.
🛠️ Techniques de Création Avancées
php
<?php
// 1. CRÉATION AVEC RANGE
$nombres = range(1, 10); // [1, 2, 3, ..., 10]
$lettres = range('a', 'z'); // ['a', 'b', 'c', ..., 'z']
$pairs = range(0, 20, 2); // [0, 2, 4, 6, ..., 20]
// 2. ARRAY_FILL ET ARRAY_FILL_KEYS
$zeros = array_fill(0, 5, 0); // [0, 0, 0, 0, 0]
$defaut = array_fill(10, 3, 'vide'); // [10 => 'vide', 11 => 'vide', 12 => 'vide']
$cles = ['nom', 'email', 'age'];
$formulaire = array_fill_keys($cles, '');
// ['nom' => '', 'email' => '', 'age' => '']
// 3. ARRAY_COMBINE
$prenoms = ['Alice', 'Bob', 'Charlie'];
$ages = [25, 30, 35];
$personnes = array_combine($prenoms, $ages);
// ['Alice' => 25, 'Bob' => 30, 'Charlie' => 35]
// 4. EXPLODE ET IMPLODE
$csv = "pomme,banane,orange,kiwi";
$fruits = explode(',', $csv); // ['pomme', 'banane', 'orange', 'kiwi']
$liste = implode(' | ', $fruits); // "pomme | banane | orange | kiwi"
$json_like = implode(', ', $fruits); // "pomme, banane, orange, kiwi"
// 5. AJOUT ET SUPPRESSION D'ÉLÉMENTS
$stack = ['a', 'b'];
// Ajout à la fin
array_push($stack, 'c', 'd'); // ['a', 'b', 'c', 'd']
$stack[] = 'e'; // Plus rapide pour un élément
// Ajout au début
array_unshift($stack, 'START'); // ['START', 'a', 'b', 'c', 'd', 'e']
// Suppression de la fin
$dernier = array_pop($stack); // 'e'
// Suppression du début
$premier = array_shift($stack); // 'START'
// 6. INSERTION ET SUPPRESSION À UNE POSITION
$arr = ['a', 'b', 'd', 'e'];
// Insérer 'c' à la position 2
array_splice($arr, 2, 0, 'c'); // ['a', 'b', 'c', 'd', 'e']
// Remplacer 1 élément à la position 1
array_splice($arr, 1, 1, ['B', 'BB']); // ['a', 'B', 'BB', 'c', 'd', 'e']
// 7. FUSION DE TABLEAUX
$arr1 = ['a', 'b'];
$arr2 = ['c', 'd'];
$arr3 = ['e', 'f'];
// Fusion simple
$fusion = array_merge($arr1, $arr2, $arr3); // ['a', 'b', 'c', 'd', 'e', 'f']
// Spread operator (PHP 7.4+)
$fusion2 = [...$arr1, ...$arr2, ...$arr3]; // Même résultat, plus rapide
// Fusion récursive pour tableaux associatifs
$config1 = ['db' => ['host' => 'localhost'], 'app' => ['debug' => true]];
$config2 = ['db' => ['port' => 3306], 'app' => ['name' => 'MonApp']];
$config = array_merge_recursive($config1, $config2);
// 8. MODIFICATION PAR RÉFÉRENCE
$original = [1, 2, 3];
$copie = $original; // Copie
$reference = &$original; // Référence
$original[0] = 99;
print_r($copie); // [1, 2, 3] - inchangé
print_r($reference); // [99, 2, 3] - modifié
// 9. CLONAGE DE TABLEAUX MULTIDIMENSIONNELS
function clonageProf($array) {
$clone = [];
foreach ($array as $key => $value) {
if (is_array($value)) {
$clone[$key] = clonageProf($value);
} else {
$clone[$key] = $value;
}
}
return $clone;
}
// Ou avec serialize/unserialize (attention aux objets)
$clone_rapide = unserialize(serialize($tableau_complexe));
// 10. CRÉATION CONDITIONNELLE
$user_data = [];
$user_data['nom'] = $nom ?? 'Anonyme';
$user_data['age'] = $age > 0 ? $age : null;
// Création avec conditions
$options = array_filter([
'debug' => $debug_mode ? true : null,
'cache' => $enable_cache ? 3600 : null,
'log_level' => $log_level ?: null
], function($value) {
return $value !== null;
});
?>
Fonctions Natives Essentielles
Découvrez les fonctions PHP les plus utiles pour manipuler et traiter vos tableaux.
🔍 Recherche et Filtrage
php
<?php
// RECHERCHE ET FILTRAGE DANS LES TABLEAUX
$fruits = ['pomme', 'banane', 'orange', 'kiwi', 'pomme'];
$notes = [12, 15, 8, 20, 14, 18];
$users = [
['nom' => 'Alice', 'age' => 25, 'actif' => true],
['nom' => 'Bob', 'age' => 30, 'actif' => false],
['nom' => 'Charlie', 'age' => 20, 'actif' => true]
];
// 1. IN_ARRAY - Vérifier si une valeur existe
if (in_array('banane', $fruits)) {
echo "Banane trouvée !";
}
// Recherche stricte (type et valeur)
var_dump(in_array(12, $notes)); // true
var_dump(in_array('12', $notes, true)); // false (strict)
// 2. ARRAY_SEARCH - Trouver la clé d'une valeur
$position = array_search('orange', $fruits);
if ($position !== false) {
echo "Orange trouvée à la position: " . $position; // 2
}
// Recherche de toutes les occurrences
$positions_pomme = array_keys($fruits, 'pomme'); // [0, 4]
// 3. ARRAY_KEY_EXISTS - Vérifier si une clé existe
$config = ['debug' => false, 'cache' => null];
if (array_key_exists('debug', $config)) {
echo "Clé 'debug' existe"; // S'exécute même si valeur = false
}
// Différence avec isset()
var_dump(isset($config['cache'])); // false (car null)
var_dump(array_key_exists('cache', $config)); // true
// 4. ARRAY_FILTER - Filtrer les éléments
// Supprimer les valeurs vides/nulles
$data = ['nom', '', 'email', null, 'age', 0];
$clean = array_filter($data); // ['nom', 'email', 'age']
// Filtrer avec fonction personnalisée
$bonnes_notes = array_filter($notes, function($note) {
return $note >= 15;
}); // [15, 20, 18]
// Filtrer avec arrow function (PHP 7.4+)
$adultes = array_filter($users, fn($user) => $user['age'] >= 25);
// Filtrer les clés
$user = ['nom' => 'John', 'password' => 'secret', 'email' => 'john@test.com'];
$public_data = array_filter($user, function($key) {
return $key !== 'password';
}, ARRAY_FILTER_USE_KEY);
// Filtrer avec clé ET valeur
$filtered = array_filter($user, function($value, $key) {
return $key !== 'password' && !empty($value);
}, ARRAY_FILTER_USE_BOTH);
// 5. ARRAY_COLUMN - Extraire une colonne
$noms = array_column($users, 'nom'); // ['Alice', 'Bob', 'Charlie']
// Avec clé d'index
$users_by_name = array_column($users, 'age', 'nom');
// ['Alice' => 25, 'Bob' => 30, 'Charlie' => 20]
// Extraire objets complets avec nouvelle clé
$users_indexed = array_column($users, null, 'nom');
// 6. ARRAY_UNIQUE - Supprimer les doublons
$colors = ['rouge', 'bleu', 'rouge', 'vert', 'bleu'];
$unique_colors = array_unique($colors); // ['rouge', 'bleu', 'vert']
// Préserver les clés originales
print_r($unique_colors); // [0 => 'rouge', 1 => 'bleu', 3 => 'vert']
// Réindexer
$reindexed = array_values(array_unique($colors));
// 7. ARRAY_DIFF ET ARRAY_INTERSECT
$array1 = ['a', 'b', 'c', 'd'];
$array2 = ['b', 'c', 'e', 'f'];
// Différence (éléments de $array1 pas dans $array2)
$diff = array_diff($array1, $array2); // ['a', 'd']
// Intersection (éléments communs)
$intersect = array_intersect($array1, $array2); // ['b', 'c']
// Différence sur les clés
$assoc1 = ['a' => 1, 'b' => 2, 'c' => 3];
$assoc2 = ['b' => 2, 'c' => 4, 'd' => 5];
$diff_keys = array_diff_key($assoc1, $assoc2); // ['a' => 1]
$diff_assoc = array_diff_assoc($assoc1, $assoc2); // ['a' => 1, 'c' => 3]
// 8. FONCTIONS AVANCÉES DE RECHERCHE
function rechercheAvancee($array, $criteres) {
return array_filter($array, function($item) use ($criteres) {
foreach ($criteres as $key => $value) {
if (!isset($item[$key]) || $item[$key] !== $value) {
return false;
}
}
return true;
});
}
$users_actifs = rechercheAvancee($users, ['actif' => true]);
// Recherche floue
function rechercheFloue($array, $terme, $champ = null) {
return array_filter($array, function($item) use ($terme, $champ) {
$texte = $champ ? $item[$champ] : $item;
return stripos($texte, $terme) !== false;
});
}
$resultats = rechercheFloue($users, 'al', 'nom'); // Trouve "Alice" et "Charlie"
?>
🔄 Tri et Transformation
php
<?php
// TRI ET TRANSFORMATION DE TABLEAUX
$nombres = [3, 1, 4, 1, 5, 9, 2];
$fruits = ['banane', 'pomme', 'orange'];
$users = [
['nom' => 'Alice', 'age' => 25, 'score' => 95],
['nom' => 'Bob', 'age' => 30, 'score' => 87],
['nom' => 'Charlie', 'age' => 20, 'score' => 92]
];
// 1. TRI SIMPLE
// sort() - Tri croissant (réindexe les clés)
$nombres_copies = $nombres;
sort($nombres_copies); // [1, 1, 2, 3, 4, 5, 9]
// rsort() - Tri décroissant
$nombres_desc = $nombres;
rsort($nombres_desc); // [9, 5, 4, 3, 2, 1, 1]
// 2. TRI AVEC PRÉSERVATION DES CLÉS
$assoc = ['c' => 3, 'a' => 1, 'b' => 2];
// asort() - Tri par valeurs (garde les clés)
$by_values = $assoc;
asort($by_values); // ['a' => 1, 'b' => 2, 'c' => 3]
// arsort() - Tri décroissant par valeurs
$by_values_desc = $assoc;
arsort($by_values_desc); // ['c' => 3, 'b' => 2, 'a' => 1]
// ksort() - Tri par clés
$by_keys = $assoc;
ksort($by_keys); // ['a' => 1, 'b' => 2, 'c' => 3]
// krsort() - Tri décroissant par clés
$by_keys_desc = $assoc;
krsort($by_keys_desc); // ['c' => 3, 'b' => 2, 'a' => 1]
// 3. TRI PERSONNALISÉ AVEC USORT
// Tri par âge
$users_by_age = $users;
usort($users_by_age, function($a, $b) {
return $a['age'] <=> $b['age'];
});
// Tri par score décroissant avec arrow function
$users_by_score = $users;
usort($users_by_score, fn($a, $b) => $b['score'] <=> $a['score']);
// Tri multicritères
usort($users, function($a, $b) {
// D'abord par score (desc), puis par âge (asc)
$score_cmp = $b['score'] <=> $a['score'];
return $score_cmp !== 0 ? $score_cmp : $a['age'] <=> $b['age'];
});
// 4. TRI NATUREL ET AVEC VERSIONS
$versions = ['1.10', '1.2', '1.1'];
natsort($versions); // Tri naturel: ['1.1', '1.2', '1.10']
$files = ['file10.txt', 'file2.txt', 'file1.txt'];
natsort($files); // ['file1.txt', 'file2.txt', 'file10.txt']
// 5. ARRAY_MAP - Transformation
// Doubler tous les nombres
$doubles = array_map(fn($n) => $n * 2, $nombres);
// Formatter les noms
$noms_formattés = array_map(function($user) {
return strtoupper($user['nom']);
}, $users);
// Mapper plusieurs tableaux
$noms = ['Alice', 'Bob'];
$ages = [25, 30];
$presentations = array_map(function($nom, $age) {
return "$nom ($age ans)";
}, $noms, $ages);
// 6. ARRAY_REDUCE - Réduction
// Somme
$somme = array_reduce($nombres, fn($carry, $item) => $carry + $item, 0);
// Produit
$produit = array_reduce($nombres, fn($carry, $item) => $carry * $item, 1);
// Construire une chaîne
$phrase = array_reduce($fruits, function($carry, $fruit) {
return $carry . ($carry ? ', ' : '') . $fruit;
}, '');
// Trouver le maximum/minimum
$max_age = array_reduce($users, function($carry, $user) {
return max($carry, $user['age']);
}, 0);
// 7. ARRAY_WALK - Modification sur place
$prices = [10, 20, 30];
array_walk($prices, function(&$price, $key) {
$price *= 1.2; // +20% de TVA
});
// Avec paramètre supplémentaire
array_walk($prices, function(&$price, $key, $taux) {
$price *= (1 + $taux);
}, 0.1); // +10%
// 8. ARRAY_FLIP - Inverser clés/valeurs
$couleurs = ['r' => 'rouge', 'v' => 'vert', 'b' => 'bleu'];
$inverse = array_flip($couleurs);
// ['rouge' => 'r', 'vert' => 'v', 'bleu' => 'b']
// 9. ARRAY_REVERSE - Inverser l'ordre
$reversed = array_reverse($fruits); // ['orange', 'pomme', 'banane']
$reversed_keys = array_reverse($fruits, true); // Préserve les clés
// 10. FONCTIONS MATHÉMATIQUES
echo array_sum($nombres); // 25
echo array_product([2, 3, 4]); // 24
echo max($nombres); // 9
echo min($nombres); // 1
// Moyenne
$moyenne = array_sum($nombres) / count($nombres);
?>
Tableaux Multidimensionnels
Maîtrisez les structures de données complexes avec les tableaux à plusieurs dimensions.
📋 Structures Complexes et Parcours
php
<?php
// TABLEAUX MULTIDIMENSIONNELS ET STRUCTURES COMPLEXES
// 1. TABLEAUX 2D - MATRICE
$matrice = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
// Accès aux éléments
echo $matrice[1][2]; // 6 (ligne 1, colonne 2)
// Parcours avec boucles imbriquées
for ($i = 0; $i < count($matrice); $i++) {
for ($j = 0; $j < count($matrice[$i]); $j++) {
echo $matrice[$i][$j] . " ";
}
echo "\n";
}
// 2. BASE DE DONNÉES SIMULÉE
$etudiants = [
[
'id' => 1,
'nom' => 'Dupont',
'prenom' => 'Alice',
'age' => 20,
'notes' => [
'maths' => 15,
'francais' => 17,
'anglais' => 14
],
'adresse' => [
'rue' => '123 rue de la Paix',
'ville' => 'Paris',
'cp' => '75001'
]
],
[
'id' => 2,
'nom' => 'Martin',
'prenom' => 'Bob',
'age' => 22,
'notes' => [
'maths' => 18,
'francais' => 12,
'anglais' => 16
],
'adresse' => [
'rue' => '456 avenue Victor Hugo',
'ville' => 'Lyon',
'cp' => '69000'
]
]
];
// Accès aux données imbriquées
echo $etudiants[0]['notes']['maths']; // 15
echo $etudiants[1]['adresse']['ville']; // Lyon
// 3. PARCOURS RÉCURSIF
function parcourirRecursif($array, $niveau = 0) {
$indentation = str_repeat(" ", $niveau);
foreach ($array as $cle => $valeur) {
if (is_array($valeur)) {
echo $indentation . $cle . ": Array\n";
parcourirRecursif($valeur, $niveau + 1);
} else {
echo $indentation . $cle . ": " . $valeur . "\n";
}
}
}
parcourirRecursif($etudiants[0]);
// 4. RECHERCHE DANS TABLEAUX MULTIDIMENSIONNELS
function rechercherEtudiant($etudiants, $champ, $valeur) {
foreach ($etudiants as $index => $etudiant) {
if (isset($etudiant[$champ]) && $etudiant[$champ] === $valeur) {
return $index;
}
}
return -1;
}
$index_alice = rechercherEtudiant($etudiants, 'prenom', 'Alice');
// Recherche avec array_search sur colonnes extraites
$prenoms = array_column($etudiants, 'prenom');
$index_bob = array_search('Bob', $prenoms);
// 5. CALCULS SUR TABLEAUX MULTIDIMENSIONNELS
function calculerMoyenne($etudiant) {
$notes = $etudiant['notes'];
return array_sum($notes) / count($notes);
}
function ajouterMoyennes($etudiants) {
return array_map(function($etudiant) {
$etudiant['moyenne'] = calculerMoyenne($etudiant);
return $etudiant;
}, $etudiants);
}
$etudiants_avec_moyennes = ajouterMoyennes($etudiants);
// 6. TRI DE TABLEAUX MULTIDIMENSIONNELS
// Tri par moyenne (décroissante)
usort($etudiants_avec_moyennes, function($a, $b) {
return $b['moyenne'] <=> $a['moyenne'];
});
// Tri par nom puis prénom
usort($etudiants, function($a, $b) {
$nom_cmp = $a['nom'] <=> $b['nom'];
return $nom_cmp !== 0 ? $nom_cmp : $a['prenom'] <=> $b['prenom'];
});
// 7. FUSION ET MISE À JOUR PROFONDE
function fusionProfonde($array1, $array2) {
$resultat = $array1;
foreach ($array2 as $cle => $valeur) {
if (is_array($valeur) && isset($resultat[$cle]) && is_array($resultat[$cle])) {
$resultat[$cle] = fusionProfonde($resultat[$cle], $valeur);
} else {
$resultat[$cle] = $valeur;
}
}
return $resultat;
}
// 8. CONVERSION TABLEAU ↔ OBJETS
function arrayToObject($array) {
if (is_array($array)) {
return (object) array_map(__FUNCTION__, $array);
}
return $array;
}
function objectToArray($obj) {
if (is_object($obj)) $obj = (array) $obj;
if (is_array($obj)) {
$new = [];
foreach ($obj as $key => $val) {
$new[$key] = objectToArray($val);
}
} else {
$new = $obj;
}
return $new;
}
// 9. APLANISSEMENT (FLATTEN)
function aplanir($array, $separateur = '.') {
$resultat = [];
foreach ($array as $cle => $valeur) {
if (is_array($valeur)) {
$sous_tableau = aplanir($valeur, $separateur);
foreach ($sous_tableau as $sous_cle => $sous_valeur) {
$resultat[$cle . $separateur . $sous_cle] = $sous_valeur;
}
} else {
$resultat[$cle] = $valeur;
}
}
return $resultat;
}
$etudiant_aplani = aplanir($etudiants[0]);
// ['id' => 1, 'nom' => 'Dupont', 'notes.maths' => 15, 'adresse.ville' => 'Paris', ...]
// 10. VALIDATION RÉCURSIVE
function validerStructure($data, $schema) {
foreach ($schema as $cle => $type) {
if (!isset($data[$cle])) {
return false;
}
if (is_array($type)) {
if (!is_array($data[$cle]) || !validerStructure($data[$cle], $type)) {
return false;
}
} else {
if (gettype($data[$cle]) !== $type) {
return false;
}
}
}
return true;
}
$schema_etudiant = [
'id' => 'integer',
'nom' => 'string',
'notes' => [
'maths' => 'integer',
'francais' => 'integer'
]
];
$valide = validerStructure($etudiants[0], $schema_etudiant);
?>
Concepts Avancés
Explorez les techniques avancées : références, objets itérables, et patterns modernes.
⚡ Références, Performances et Optimisations
php
<?php
// RÉFÉRENCES, PERFORMANCES ET OPTIMISATIONS
// 1. GESTION DES RÉFÉRENCES
$original = [1, 2, 3];
$copie = $original; // Copie par valeur
$reference = &$original; // Référence
// Modification sur référence
function modifierParReference(&$array) {
$array[] = 'nouveau';
}
modifierParReference($original); // Modifie $original directement
// Parcours par référence avec foreach
$nombres = [1, 2, 3, 4, 5];
foreach ($nombres as &$nombre) {
$nombre *= 2; // Double chaque valeur
}
unset($nombre); // Important: détruire la référence
// 2. COPY-ON-WRITE ET OPTIMISATIONS
function demonstrationCOW() {
$big_array = range(1, 1000000);
// Pas de copie réelle ici grâce au COW
$copy1 = $big_array;
$copy2 = $big_array;
echo memory_get_usage() . " bytes\n";
// Modification déclenche la copie
$copy1[0] = 9999;
echo memory_get_usage() . " bytes\n";
}
// 3. GÉNÉRATEURS POUR TABLEAUX MASSIFS
function genererNombres($max) {
for ($i = 1; $i <= $max; $i++) {
yield $i; // Génère une valeur à la fois
}
}
// Utilisation économe en mémoire
foreach (genererNombres(1000000) as $nombre) {
if ($nombre > 10) break; // Traite seulement les 10 premiers
echo $nombre . " ";
}
// 4. POOLING D'OBJETS POUR TABLEAUX
class ArrayPool {
private static $pool = [];
public static function get() {
return array_pop(self::$pool) ?: [];
}
public static function release($array) {
array_splice($array, 0); // Vider le tableau
self::$pool[] = $array;
}
}
// Utilisation
$temp_array = ArrayPool::get();
$temp_array[] = 'données temporaires';
ArrayPool::release($temp_array);
// 5. LAZY LOADING POUR TABLEAUX COMPLEXES
class LazyArray implements ArrayAccess, Countable {
private $loader;
private $cache = [];
private $loaded = [];
public function __construct($loader) {
$this->loader = $loader;
}
public function offsetGet($offset) {
if (!isset($this->loaded[$offset])) {
$this->cache[$offset] = ($this->loader)($offset);
$this->loaded[$offset] = true;
}
return $this->cache[$offset];
}
public function offsetExists($offset) { return true; }
public function offsetSet($offset, $value) { $this->cache[$offset] = $value; }
public function offsetUnset($offset) { unset($this->cache[$offset]); }
public function count() { return count($this->cache); }
}
// 6. BENCHMARK DES OPÉRATIONS
function benchmarkArrayOperations() {
$size = 100000;
$data = range(1, $size);
// Test array_push vs [] =
$start = microtime(true);
$test1 = [];
for ($i = 0; $i < 10000; $i++) {
$test1[] = $i;
}
$time1 = microtime(true) - $start;
$start = microtime(true);
$test2 = [];
for ($i = 0; $i < 10000; $i++) {
array_push($test2, $i);
}
$time2 = microtime(true) - $start;
echo "[] = : " . $time1 . "s\n";
echo "array_push: " . $time2 . "s\n";
}
// 7. SÉRIALISATION OPTIMISÉE
class OptimizedSerializer {
public static function serialize($data) {
// igbinary est plus rapide que serialize() natif
return function_exists('igbinary_serialize')
? igbinary_serialize($data)
: serialize($data);
}
public static function unserialize($data) {
return function_exists('igbinary_unserialize')
? igbinary_unserialize($data)
: unserialize($data);
}
}
// 8. ITERATEURS PERSONNALISÉS
class ChunkedArrayIterator implements Iterator {
private $array;
private $chunkSize;
private $position = 0;
public function __construct($array, $chunkSize = 100) {
$this->array = $array;
$this->chunkSize = $chunkSize;
}
public function current() {
return array_slice(
$this->array,
$this->position * $this->chunkSize,
$this->chunkSize
);
}
public function key() { return $this->position; }
public function next() { ++$this->position; }
public function rewind() { $this->position = 0; }
public function valid() {
return $this->position * $this->chunkSize < count($this->array);
}
}
// Traitement par chunks pour économiser la mémoire
$big_data = range(1, 10000);
foreach (new ChunkedArrayIterator($big_data, 500) as $chunk) {
// Traiter 500 éléments à la fois
echo "Chunk de " . count($chunk) . " éléments\n";
}
// 9. MEMOISATION POUR CALCULS COÛTEUX
class Memoizer {
private static $cache = [];
public static function memoize($func) {
return function(...$args) use ($func) {
$key = serialize($args);
if (!isset(self::$cache[$key])) {
self::$cache[$key] = $func(...$args);
}
return self::$cache[$key];
};
}
}
$expensiveArrayOperation = Memoizer::memoize(function($array) {
// Simulation d'une opération coûteuse
usleep(100000); // 0.1 seconde
return array_sum($array);
});
// Premier appel: lent
$result1 = $expensiveArrayOperation([1, 2, 3]);
// Deuxième appel avec mêmes paramètres: instantané
$result2 = $expensiveArrayOperation([1, 2, 3]);
?>
🎯 Patterns Modernes et Techniques Avancées
php
<?php
// PATTERNS MODERNES ET TECHNIQUES AVANCÉES
// 1. FLUENT INTERFACE POUR TABLEAUX
class FluentArray {
private $data;
public function __construct($data = []) {
$this->data = $data;
}
public function filter($callback) {
$this->data = array_filter($this->data, $callback);
return $this;
}
public function map($callback) {
$this->data = array_map($callback, $this->data);
return $this;
}
public function sort($callback = null) {
$callback ? usort($this->data, $callback) : sort($this->data);
return $this;
}
public function unique() {
$this->data = array_values(array_unique($this->data));
return $this;
}
public function toArray() {
return $this->data;
}
}
// Utilisation fluide
$result = (new FluentArray([1, 2, 2, 3, 4, 5]))
->unique()
->filter(fn($x) => $x > 2)
->map(fn($x) => $x * 10)
->sort()
->toArray();
// 2. PIPELINE DE TRAITEMENT
class ArrayPipeline {
private $steps = [];
public function addStep($callback) {
$this->steps[] = $callback;
return $this;
}
public function process($data) {
return array_reduce($this->steps, function($carry, $step) {
return $step($carry);
}, $data);
}
}
$pipeline = (new ArrayPipeline())
->addStep(fn($arr) => array_filter($arr, fn($x) => $x % 2 === 0))
->addStep(fn($arr) => array_map(fn($x) => $x * 2, $arr))
->addStep(fn($arr) => array_sum($arr));
$result = $pipeline->process([1, 2, 3, 4, 5, 6]); // 24
// 3. OBSERVER PATTERN POUR TABLEAUX
class ObservableArray implements ArrayAccess {
private $data = [];
private $observers = [];
public function addObserver($observer) {
$this->observers[] = $observer;
}
private function notify($event, $key, $value = null) {
foreach ($this->observers as $observer) {
$observer($event, $key, $value);
}
}
public function offsetSet($key, $value) {
$isNew = !isset($this->data[$key]);
$this->data[$key] = $value;
$this->notify($isNew ? 'added' : 'updated', $key, $value);
}
public function offsetGet($key) { return $this->data[$key] ?? null; }
public function offsetExists($key) { return isset($this->data[$key]); }
public function offsetUnset($key) {
unset($this->data[$key]);
$this->notify('removed', $key);
}
}
// 4. COMMAND PATTERN POUR OPÉRATIONS
interface ArrayCommand {
public function execute($array);
public function undo($array);
}
class AddElementCommand implements ArrayCommand {
private $value;
private $key;
public function __construct($value, $key = null) {
$this->value = $value;
$this->key = $key;
}
public function execute($array) {
if ($this->key !== null) {
$array[$this->key] = $this->value;
} else {
$array[] = $this->value;
}
return $array;
}
public function undo($array) {
if ($this->key !== null) {
unset($array[$this->key]);
} else {
array_pop($array);
}
return $array;
}
}
// 5. STRATEGY PATTERN POUR TRI
interface SortStrategy {
public function sort($array);
}
class QuickSortStrategy implements SortStrategy {
public function sort($array) {
if (count($array) < 2) return $array;
$pivot = $array[0];
$left = array_filter(array_slice($array, 1), fn($x) => $x <= $pivot);
$right = array_filter(array_slice($array, 1), fn($x) => $x > $pivot);
return array_merge($this->sort($left), [$pivot], $this->sort($right));
}
}
class ArraySorter {
private $strategy;
public function __construct(SortStrategy $strategy) {
$this->strategy = $strategy;
}
public function sort($array) {
return $this->strategy->sort($array);
}
}
// 6. DECORATOR PATTERN
class ArrayDecorator {
protected $array;
public function __construct($array) {
$this->array = $array;
}
public function getData() { return $this->array; }
}
class ValidatedArrayDecorator extends ArrayDecorator {
private $validator;
public function __construct($array, $validator) {
parent::__construct($array);
$this->validator = $validator;
}
public function getData() {
return array_filter($this->array, $this->validator);
}
}
// 7. IMMUTABLE ARRAYS
class ImmutableArray {
private $data;
public function __construct($data) {
$this->data = $data;
}
public function add($value) {
$newData = $this->data;
$newData[] = $value;
return new self($newData);
}
public function filter($callback) {
return new self(array_filter($this->data, $callback));
}
public function toArray() { return $this->data; }
}
// 8. WEAK REFERENCES POUR CACHES
class WeakArrayCache {
private $cache;
public function __construct() {
$this->cache = new WeakMap();
}
public function get($object) {
return $this->cache[$object] ?? null;
}
public function set($object, $data) {
$this->cache[$object] = $data;
}
}
?>
Exemples Pratiques
Découvrez des cas d'usage concrets avec CodeIgniter 4 et des applications web modernes.
🌐 Applications Web et CodeIgniter 4
php
<?php
// EXEMPLES PRATIQUES AVEC CODEIGNITER 4
// 1. CONTROLLER AVEC GESTION DE TABLEAUX
class ProductController extends BaseController {
public function index() {
$model = new ProductModel();
$products = $model->findAll();
// Traitement avec tableaux
$data = [
'products' => $this->processProducts($products),
'categories' => $this->getCategories($products),
'stats' => $this->calculateStats($products)
];
return view('products/index', $data);
}
private function processProducts($products) {
// Grouper par catégorie
$grouped = [];
foreach ($products as $product) {
$category = $product['category'];
$grouped[$category][] = $product;
}
// Trier chaque groupe par prix
foreach ($grouped as &$group) {
usort($group, fn($a, $b) => $a['price'] <=> $b['price']);
}
return $grouped;
}
private function getCategories($products) {
$categories = array_column($products, 'category');
$unique = array_unique($categories);
sort($unique);
return $unique;
}
private function calculateStats($products) {
$prices = array_column($products, 'price');
return [
'total' => count($products),
'avg_price' => array_sum($prices) / count($prices),
'min_price' => min($prices),
'max_price' => max($prices)
];
}
}
// 2. HELPER POUR TABLEAUX
if (!function_exists('array_pluck')) {
function array_pluck($array, $key) {
return array_map(fn($item) => $item[$key] ?? null, $array);
}
}
if (!function_exists('array_group_by')) {
function array_group_by($array, $key) {
$result = [];
foreach ($array as $item) {
$groupKey = $item[$key] ?? 'unknown';
$result[$groupKey][] = $item;
}
return $result;
}
}
// 3. VALIDATION DE FORMULAIRES
class FormController extends BaseController {
public function create() {
$validation = service('validation');
// Règles de validation sous forme de tableau
$rules = [
'name' => 'required|min_length[3]|max_length[50]',
'email' => 'required|valid_email|is_unique[users.email]',
'skills' => 'required',
'experience' => 'required|integer|greater_than[0]'
];
if (!$this->validate($rules)) {
return view('form', [
'errors' => $validation->getErrors()
]);
}
// Nettoyage et transformation des données
$data = $this->sanitizeData($this->request->getPost());
// Sauvegarde...
}
private function sanitizeData($input) {
$clean = [];
// Nettoyer chaque champ
$cleaners = [
'name' => fn($val) => trim(strip_tags($val)),
'email' => fn($val) => filter_var($val, FILTER_SANITIZE_EMAIL),
'skills' => fn($val) => array_map('trim', explode(',', $val)),
'experience' => fn($val) => (int) $val
];
foreach ($cleaners as $field => $cleaner) {
if (isset($input[$field])) {
$clean[$field] = $cleaner($input[$field]);
}
}
return $clean;
}
}
// 4. CACHE ET SESSION
class CacheService {
public function cacheArray($key, $data, $ttl = 3600) {
$cache = service('cache');
// Compression pour économiser l'espace
$compressed = gzcompress(serialize($data));
return $cache->save($key, $compressed, $ttl);
}
public function getCachedArray($key) {
$cache = service('cache');
$compressed = $cache->get($key);
if ($compressed === null) {
return null;
}
return unserialize(gzuncompress($compressed));
}
}
// 5. API AVEC PAGINATION
class ApiController extends BaseController {
public function getUsers() {
$page = $this->request->getGet('page') ?? 1;
$limit = $this->request->getGet('limit') ?? 10;
$filters = $this->getFilters();
$model = new UserModel();
$users = $model->getFilteredUsers($filters, $page, $limit);
$response = [
'data' => $users,
'pagination' => [
'current_page' => $page,
'per_page' => $limit,
'total' => $model->countFiltered($filters)
],
'filters_applied' => $filters
];
return $this->response->setJSON($response);
}
private function getFilters() {
$allowed = ['name', 'email', 'status', 'role'];
$filters = [];
foreach ($allowed as $field) {
$value = $this->request->getGet($field);
if ($value !== null) {
$filters[$field] = trim($value);
}
}
return $filters;
}
}
// 6. CONFIGURATION DYNAMIQUE
class ConfigHelper {
public static function mergeConfigs($base, $override) {
foreach ($override as $key => $value) {
if (is_array($value) && isset($base[$key]) && is_array($base[$key])) {
$base[$key] = self::mergeConfigs($base[$key], $value);
} else {
$base[$key] = $value;
}
}
return $base;
}
public static function getNestedValue($array, $path, $default = null) {
$keys = explode('.', $path);
$current = $array;
foreach ($keys as $key) {
if (!is_array($current) || !isset($current[$key])) {
return $default;
}
$current = $current[$key];
}
return $current;
}
}
?>
Tableaux PHP maîtrisés
Création, parcours, tri et tableaux imbriqués : la structure de données centrale de PHP n’a plus de secret.