Maîtrisez les tableaux PHP de A à Z : création, manipulation, fonctions natives, tableaux multidimensionnels et concepts avancés pour structurer vos données efficacement.
Comprendre ce qu'est un tableau, les différents types et leur utilisation.
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.
<?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
?>
Apprenez à créer, modifier et manipuler efficacement vos tableaux 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;
});
?>
Découvrez les fonctions PHP les plus utiles pour manipuler et traiter vos tableaux.
<?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"
?>
<?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);
?>
Maîtrisez les structures de données complexes avec les tableaux à plusieurs dimensions.
<?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);
?>
Explorez les techniques avancées : références, objets itérables, et patterns modernes.
<?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]);
?>
<?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;
}
}
?>
Découvrez des cas d'usage concrets avec CodeIgniter 4 et des applications web modernes.
<?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;
}
}
?>