Les tableaux
Pour une liste de toutes les fonctions de tableau, voir le chapitre fonctions de tableau dans la documentation.
Un tableau en PHP est en fait une carte ordonnée. Une carte est un type
qui associe des valeurs à des clés.
Ce type est optimisé pour différentes utilisations ; il peut être considéré
comme un tableau, une liste, une table de hachage, un dictionnaire, une
collection, une pile, une file d'attente et probablement plus. On peut avoir,
comme valeur d'un tableau, d'autres tableaux, multidimensionnels ou non.
La structure de ces données dépasse l'objet de ce manuel, mais au moins
un exemple est fourni pour chacun des cas évoqués. Pour plus d'informations,
se reporter aux différentes explications sur le sujet que l'on trouve
sur le web.
SyntaxeSyntaxe d'un tableau
Un tableau peut être créé en utilisant la structure de langage
array. Il prend un nombre illimité de paramètres,
chacun séparé par une virgule, sous la forme d'une paire
key =>
value.
array(
key => value,
key2 => value2,
key3 => value3,
...
)
La virgule après le dernier élément d'un tableau
est optionnelle et peut ne pas être ajoutée. C'est généralement ce qui
est fait pour les tableaux sur une seule ligne, c.-à-d.
array(1, 2) est préféré à array(1, 2, ).
Pour les tableaux sur plusieurs lignes, la virgule finale est généralement
utilisée, car elle permet d'ajouter plus facilement de nouveaux éléments à
la fin.
Une syntaxe de tableau courte existe qui remplace
array() par [].
Un tableau simple
"bar",
"bar" => "foo",
);
// Utilisant la syntaxe de tableau courte
$array2 = [
"foo" => "bar",
"bar" => "foo",
];
var_dump($array1, $array2);
?>
]]>
La clé key peut être soit un int,
soit une &string;. La valeur value peut être
de n'importe quel type.
De plus, les modifications de type suivantes surviendront pour la clé key :
Les chaînes de caractères contenant un entier valide, sauf si le nombre
est précédé d'un signe + seront modifiées en un type
entier. C.-à-d. la clé "8" sera effectivement stockée comme
l'entier 8. D'un autre côté, "08" ne sera
pas modifié, sachant que ce n'est pas un entier décimal valide.
Les nombres à virgule flottante seront aussi modifiés en entier, ce qui signifie
que la partie après la virgule sera tronquée. C.-à-d. la clé 8.7
sera stockée sous l'entier 8.
Les booléens seront modifiés en entier également, c.-à-d. la clé
&true; sera stockée sous l'entier 1
et la clé &false; sous l'entier 0.
La valeur Null sera modifiée en une chaîne vide, c.-à-d. la clé
null sera stockée sous la chaîne de caractères "".
Les tableaux et les objets ne peuvent pas être utilisés comme clé.
Toute tentative en ce sens émettra l'alerte suivante : Illegal offset type.
Si plusieurs éléments dans la déclaration d'un tableau utilisent la même clé,
seule la dernière sera utilisée, écrasant ainsi toutes les précédentes.
Exemple sur la modification de type et l'écrasement
"a",
"1" => "b",
1.5 => "c",
true => "d",
);
var_dump($array);
?>
]]>
&example.outputs;
string(1) "d"
}
]]>
Vu que toutes les clés de l'exemple ci-dessus sont modifiées en l'entier
1, la valeur sera écrasée sur chaque nouvel élément,
et seul le dernier dont la valeur assignée est "d" sera
conservé.
Les tableaux PHP peuvent contenir des clés de type
int et string en même temps,
vu que PHP ne distingue pas les tableaux indexés et les tableaux associatifs.
Exemple avec des clés de type int et string
"bar",
"bar" => "foo",
100 => -100,
-100 => 100,
);
var_dump($array);
?>
]]>
&example.outputs;
string(3) "bar"
["bar"]=>
string(3) "foo"
[100]=>
int(-100)
[-100]=>
int(100)
}
]]>
La clé key est optionnelle. Si elle n'est
pas spécifiée, PHP utilisera un incrément de la dernière clé entière utilisée.
Tableaux indexés sans clé
]]>
&example.outputs;
string(3) "foo"
[1]=>
string(3) "bar"
[2]=>
string(5) "hello"
[3]=>
string(5) "world"
}
]]>
Il est possible de spécifier la clé seulement pour quelques éléments
et ne pas la fournir pour d'autres :
Exemple avec des clés seulement pour quelques éléments
"c",
"d",
);
var_dump($array);
?>
]]>
&example.outputs;
string(1) "a"
[1]=>
string(1) "b"
[6]=>
string(1) "c"
[7]=>
string(1) "d"
}
]]>
Comme on peut le voir, la dernière valeur "d"
a été assignée à la clé 7. Ceci est dû au fait que
la dernière clé entière la plus grande utilisée auparavant était 6.
Exemple complexe sur la modification de type et l'écrasement
Cet exemple inclut toutes les variations de modification de type de clés
et écrasements des éléments.
'a',
'1' => 'b', // la valeur "a" sera écrasée par "b"
1.5 => 'c', // la valeur "b" sera écrasée par "c"
-1 => 'd',
'01' => 'e', // comme ceci n'est pas une chaîne de caractères entière elle n'écrasera PAS la clé pour 1
'1.5' => 'f', // comme ceci n'est pas une chaîne de caractères entière elle n'écrasera pas la clé pour 1
true => 'g', // la valeur "c" sera écrasée par "g"
false => 'h',
'' => 'i',
null => 'j', // la valeur "i" sera écrasée par "j"
'k', // la valeur "k" est assignée à la clé 2. Ceci est dû au fait que la dernière clé entière la plus grande utilisée auparavant était 1
2 => 'l', // la valeur "k" sera écrasée par "l"
);
var_dump($array);
?>
]]>
&example.outputs;
string(1) "g"
[-1]=>
string(1) "d"
["01"]=>
string(1) "e"
["1.5"]=>
string(1) "f"
[0]=>
string(1) "h"
[""]=>
string(1) "j"
[2]=>
string(1) "l"
}
]]>
Exemple d'index négatif
Lorsqu'une clé entière négative n est assignée, PHP prendra soin
d'assigner la clé suivante à n+1.
]]>
&example.outputs;
int(1)
[-4]=>
int(2)
}
]]>
Avant PHP 8.3.0, l'assignation d'une clé entière négative n
assignait la clé suivante à 0. L'exemple précédent aurait
donc produit :
int(1)
[0]=>
int(2)
}
]]>
Accès aux éléments d'un tableau en utilisant la syntaxe à base
de crochets
Les éléments d'un tableau peuvent être accédés en utilisant
la syntaxe array[key].
Accès aux éléments d'un tableau
"bar",
42 => 24,
"multi" => array(
"dimensional" => array(
"array" => "foo"
)
)
);
var_dump($array["foo"]);
var_dump($array[42]);
var_dump($array["multi"]["dimensional"]["array"]);
?>
]]>
&example.outputs;
Avant PHP 8.0.0, les crochets et accolades pouvaient être utilisés de
façon interchangeable pour accéder aux éléments d'un tableau (e.g.
$array[42] et $array{42} feraient
tous deux la même chose dans l'exemple ci-dessus).
La syntaxe avec les accolades a été rendue obsolète en PHP 7.4.0 et n'est
plus supportée à partir de PHP 8.0.0.
Faire référence à un tableau à la sortie d'une fonction ou d'une méthode
]]>
Une tentative d'accès à une clé d'un tableau qui n'a pas été définie
revient à tenter d'accéder à une variable non définie : une alerte de
niveau E_WARNING sera émise (E_NOTICE avant PHP 8.0.0),
et le résultat vaudra &null;.
Faire référence à un tableau à la sortie d'une fonction ou d'une méthode
d'une valeur scalaire qui n'est pas une &string; génère &null;.
Avant PHP 7.4.0, ceci ne générait pas de message d'erreur.
À partir de PHP 7.4.0, ceci émet une E_NOTICE ;
À partir de PHP 8.0.0, ceci émet une E_WARNING.
Création/modification avec des crochets
Un tableau existant peut être modifié en y assignant explicitement des valeurs.
L'assignation d'une valeur dans un tableau est effectuée en spécifiant
la clé, entre crochets. La clé peut également ne pas être renseignée, sous
la forme : [].
$arr[clé] = valeur;
$arr[] = valeur;
// clé peut être un &integer; ou une &string;
// valeur peut être n'importe quel type
Si lors de l'assignation $arr n'existe pas ou est défini
à &null; ou &false;, il sera créé ; c'est ainsi une façon détournée de créer un tableau.
Cette pratique est cependant découragée car si $arr
contient déjà quelques valeurs (c.-à-d. string depuis la variable demandée)
alors cette valeur restera en place et [] peut attendre
un opérateur d'accès
sur une chaîne. C'est toujours un meilleur choix que d'initialiser
une variable par affectation directe.
À partir de PHP 7.1.0, l'application de l'opérateur d'index vide sur une
chaîne lève une erreur fatale. Auparavant, la chaîne aurait été convertie
silencieusement en tableau.
À partir de PHP 8.1.0, créer un nouveau tableau à partir de &false; est obsolète.
Créer un nouveau tableau depuis &null; et les valeurs indéfinies est toujours autorisé.
Pour modifier une valeur en particulier, il convient d'assigner une valeur en spécifiant
sa clé. Pour effacer une paire clé/valeur, il convient d'appeler la fonction
unset sur la clé désirée.
Utilisation des crochets avec les tableaux
1, 12 => 2);
$arr[] = 56; // Identique à $arr[13] = 56;
// à cet endroit du script
$arr["x"] = 42; // Ceci ajoute un nouvel élément au
// tableau avec la clé "x"
unset($arr[5]); // Ceci efface l'élément du tableau
var_dump($arr);
unset($arr); // Ceci efface complètement le tableau
var_dump($arr);
?>
]]>
Comme dit plus haut, si aucune clé n'est spécifiée, l'indice maximal
existant est repris, et la nouvelle clé sera ce nombre, plus 1 (mais au moins 0).
Si aucun indice entier n'existe, la clé sera 0 (zéro).
Il est à noter que la clé entière maximale pour cette opération n'a
pas besoin d'exister dans le tableau au moment de la manipulation.
Elle doit seulement avoir existé dans le tableau à un moment ou un autre
depuis la dernière fois où le tableau a été ré-indexé.
Voici un exemple qui illustre ce principe :
$value) {
unset($array[$i]);
}
print_r($array);
// Ajout d'un élément (notez que la nouvelle clé est 5, et non 0).
$array[] = 6;
print_r($array);
// Ré-indexation :
$array = array_values($array);
$array[] = 7;
print_r($array);
?>
]]>
&example.outputs;
1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
)
Array
(
)
Array
(
[5] => 6
)
Array
(
[0] => 6
[1] => 7
)
]]>
Déstructuration de tableau
Les tableaux peuvent être déstructurés en utilisant []
(à partir de PHP 7.1.0) ou list.
Ces constructions peuvent être utilisées pour déstructurer un tableau en variables distinctes.
Déstructuration de tableau
]]>
La déstructuration de tableau peut être utilisée dans un &foreach;
pour déstructurer un tableau multidimensionnel tout en itérant sur celui-ci.
Déstructuration de tableau dans un foreach
]]>
Les éléments du tableau seront ignorés si la variable n'est pas fournie.
Le tableau commence toujours à l'index 0.
Ignorer des éléments
]]>
À partir de PHP 7.1.0, les tableaux associatifs peuvent aussi être déstructurés.
Cela permet de sélectionner plus facilement le bon élément dans les tableaux
à indexation numérique, car l'index peut être explicitement spécifié.
Déstructuration de tableau associatif
1, 'bar' => 2, 'baz' => 3];
// Assigne l'élément situé à l'indice 'baz' à la variable $three
['baz' => $three] = $tableau_source;
echo $three, PHP_EOL; // Affiche "3"
$tableau_source = ['foo', 'bar', 'baz'];
// Assigne l'élément situé à l'indice 2 à la variable $baz
[2 => $baz] = $tableau_source;
echo $baz, PHP_EOL; // Affiche "baz"
?>
]]>
La déstructuration de tableau peut être utilisée pour permuter facilement
deux variables.
Permuter deux variables
]]>
L'opérateur de décomposition (...) n'est pas
supporté dans les assignations.
Une tentative d'accès à une clé d'un tableau qui n'a pas été définie
revient à tenter d'accéder à une variable non définie : une alerte de
niveau E_WARNING sera émise (E_NOTICE avant PHP 8.0.0),
et le résultat vaudra &null;.
La déstructuration d’une valeur scalaire affecte &null; à toutes les variables.
Fonctions utiles
Il y a beaucoup de fonctions utiles pour travailler avec les tableaux.
Il est recommandé de lire la section de ce manuel sur les
fonctions en rapport avec les tableaux.
La fonction unset permet d'effacer les clés d'un tableau.
Il est à noter que le tableau ne sera pas
ré-indexé. Pour réaliser un effacement complet et une ré-indexation
du tableau, il faut utiliser la fonction
array_values.
Effacer des éléments intermédiaires
'one', 2 => 'two', 3 => 'three');
/* produira un tableau comme ceci
$a = array(1 => 'one', 3 => 'three');
et NON un tableau comme ceci
$a = array(1 => 'one', 2 =>'three');
*/
unset($a[2]);
var_dump($a);
$b = array_values($a);
// Maintenant, $b vaut array(0 => 'one', 1 =>'three')
var_dump($b);
?>
]]>
La structure de contrôle &foreach; existe tout spécialement
pour les tableaux. Elle fournit une manière pratique
de parcourir un tableau.
Ce qu'il est possible de faire ou non avec un tableauPourquoi $foo[bar] est incorrect ?
Utiliser toujours des guillemets autour d'un index littéral. Par exemple,
$foo['bar'] est correct, alors que
$foo[bar] ne l'est pas. Mais pourquoi ? il est courant
de rencontrer ce genre de syntaxe dans d'anciens scripts :
]]>
C'est incorrect, mais ça fonctionne. La raison est que ce code a une constante
indéfinie (bar) plutôt qu'une &string;
('bar' - notez les guillemets).
Cela fonctionne car PHP convertit automatiquement une chaîne nue
(une chaîne sans guillemets qui ne correspond à aucun symbole connu) en une chaîne
qui la contient. Actuellement, s'il n'y a aucune constante nommée bar,
alors PHP substituera 'bar' dans la chaîne et l'utilisera.
La solution de recours qui considère une constante non-définie comme une
chaîne de caractères nue est une erreur de niveau E_NOTICE.
Ceci est obsolète à partir de PHP 7.2.0, et émet une erreur de niveau
E_WARNING.
À partir de PHP 8.0.0, ceci a été retiré et lance une exception
Error.
Ceci ne signifie pas qu'il faut toujours mettre la clé entre guillemets.
Ne pas utiliser de guillemets avec les clés qui sont des
constantes ou des
variables, car cela empêcherait PHP de
les interpréter.
Clé entre guillemets
]]>
&example.outputs;
Plus d'exemples pour expliquer ce comportement :
Plus d'exemples
'apple', 'veggie' => 'carrot');
// Correct
echo $arr['fruit'], PHP_EOL; // apple
echo $arr['veggie'], PHP_EOL; // carrot
// Incorrect. Ceci ne fonctionne pas et lance une erreur PHP
// on utilise la constante nommée fruit qui est indéfinie
//
// Error: Undefined constant "fruit"
try {
echo $arr[fruit];
} catch (Error $e) {
echo get_class($e), ': ', $e->getMessage(), PHP_EOL;
}
// Ceci définit une constante pour expliquer ce qu'il ne va pas. La valeur 'veggie'
// est assignée à la constante nommée fruit.
define('fruit', 'veggie');
// Noter la différence maintenant
echo $arr['fruit'], PHP_EOL; // apple
echo $arr[fruit], PHP_EOL; // carrot
// Ce qui suit est correct, car c'est dans une chaîne. Les constantes ne sont pas recherchées
// dans les chaînes, et donc, aucune erreur ne sera émise
echo "Hello $arr[fruit], PHP_EOL"; // Hello apple
// Avec une exception : les parenthèses autour d'un tableau dans une chaîne permettent
// aux constantes d'être interprétées
echo "Hello {$arr[fruit]}", PHP_EOL; // Hello carrot
echo "Hello {$arr['fruit']}", PHP_EOL; // Hello apple
// La concaténation est une autre solution
echo "Hello " . $arr['fruit'], PHP_EOL; // Hello apple
?>
]]>
]]>
Comme vu dans la section "syntaxe",
ce qui se trouve entre crochets ('[' et
']') doit être une expression. Ceci signifie que le code ci-dessous
fonctionne :
]]>
C'est un exemple d'utilisation d'une fonction retournant une valeur qui sera
la clé du tableau. PHP comprend également les constantes :
]]>
Noter que E_ERROR est également un identifiant valide,
tout comme bar dans le premier exemple. Mais le dernier
exemple est finalement le même que celui-ci :
]]>
car E_ERROR vaut 1, etc.
Alors, pourquoi est-ce une mauvaise pratique ?
Dans le futur, les développeurs PHP peuvent vouloir ajouter une autre
constante ou un autre mot clé, ou bien une constante dans une autre partie
du code qui peut interférer. Par exemple, il est toujours incorrect d'utiliser
le mot empty et default, sachant que ce sont
des mots réservés.
Pour être plus clair, dans une chaîne entourée de guillemets doubles,
il est valide de ne pas entourer les index d'un tableau avec des
guillemets, et donc, "$foo[bar]" est valide. Voir
les exemples ci-dessous pour plus de détails mais aussi la section sur
l'analyse des variables
dans les chaînes.
Conversion en un tableau
Pour tous les types &integer;, &float;, &string;, &boolean; et &resource;,
le fait de convertir une valeur en un tableau résulte en un tableau contenant
un seul élément dont l'index vaut zéro et la valeur, une valeur scalaire convertie.
En d'autres termes, (array) $scalarValue est exactement la
même chose que array($scalarValue).
Si un objet est converti en un tableau, le résultat sera un tableau dont les
éléments sont les propriétés de l'objet. Les clés sont les noms des membres,
avec une légère exception : les variables ayant un nom sous forme d'entier sont
inaccessibles ; les variables privées auront le nom de la classe
ajouté au nom de la variable ; les variables protégées auront un '*' ajouté
au nom de la variable.
Ces valeurs préfixées ont des octets NUL des deux côtés.
Les propriétés typées
non-initialisées sont silencieusement écartées.
Conversion en tableau
{1} = null;
}
}
var_export((array) new A());
?>
]]>
&example.outputs;
NULL,
'' . "\0" . '*' . "\0" . 'C' => NULL,
'D' => NULL,
1 => NULL,
)
]]>
Ces octets NUL peuvent amener à des résultats inattendus :
Conversion d'un objet en tableau
]]>
&example.outputs;
NULL
["AA"]=>
NULL
["AA"]=>
NULL
}
]]>
Ici, on pourrait penser qu'il y a 2 clés nommées 'AA', alors qu'une est
actuellement nommée '\0A\0A'.
La conversion de &null; en un tableau résulte en un tableau vide.
Comparaison
Il est possible de comparer plusieurs tableaux avec la fonction
array_diff ainsi qu'avec les
opérateurs de tableaux.
Déballage des tableaux
Un tableau préfixé par ... sera déballé sur place lors de la définition du tableau.
Seuls les tableaux et les objets qui implémentent Traversable peuvent être déballés.
Le déballage de tableau avec ... est disponible à partir de PHP 7.4.0. C'est aussi appelé l'opérateur de décomposition.
Il est possible de déballer plusieurs fois, et d'ajouter des éléments
normaux avant et après l'opérateur ... :
Déballage simple de tableau
'd']; // ['a', 'b', 'c' => 'd']
var_dump($arr1, $arr2, $arr3, $arr4, $arr5, $arr6);
?>
]]>
Déballer un tableau avec l'opérateur ... suit les sémantiques de la fonction array_merge.
C'est-à-dire, que les clés ultérieures écrasent les valeurs antérieures
et les clés numériques sont renumérotées :
Déballage de tableau avec clé dupliquée
1];
$arr2 = ["a" => 2];
$arr3 = ["a" => 0, ...$arr1, ...$arr2];
var_dump($arr3); // ["a" => 2]
// integer key
$arr4 = [1, 2, 3];
$arr5 = [4, 5, 6];
$arr6 = [...$arr4, ...$arr5];
var_dump($arr6); // [1, 2, 3, 4, 5, 6]
// Which is [0 => 1, 1 => 2, 2 => 3, 3 => 4, 4 => 5, 5 => 6]
// where the original integer keys have not been retained.
?>
]]>
Les clés qui ne sont ni des entiers, ni des chaînes lancent une TypeError.
De telles clés peuvent uniquement être générées par un objet Traversable.
Avant PHP 8.1, le déballage de tableau qui avait une clé sous forme de chaîne n'est pas supporté :
4];
$arr3 = [...$arr1, ...$arr2];
// Fatal error: Uncaught Error: Cannot unpack array with string keys in example.php:5
$arr4 = [1, 2, 3];
$arr5 = [4, 5];
$arr6 = [...$arr4, ...$arr5]; // works. [1, 2, 3, 4, 5]
?>
]]>
Exemples
Le type tableau en PHP est vraiment polyvalent. Voici quelques exemples :
Versatilité d'un tableau
'red',
'taste' => 'sweet',
'shape' => 'round',
'name' => 'apple',
4 // la clé sera 0
);
$b = array('a', 'b', 'c');
var_dump($a, $b);
// est strictement équivalent à
$a = array();
$a['color'] = 'red';
$a['taste'] = 'sweet';
$a['shape'] = 'round';
$a['name'] = 'apple';
$a[] = 4; // la clé sera 0
$b = array();
$b[] = 'a';
$b[] = 'b';
$b[] = 'c';
// Après exécution du code ci-dessus, $a sera le tableau
// array('color' => 'red', 'taste' => 'sweet', 'shape' => 'round',
// 'name' => 'apple', 0 => 4), et $b sera le tableau
// array(0 => 'a', 1 => 'b', 2 => 'c'), ou simplement array('a', 'b', 'c').
var_dump($a, $b);
?>
]]>
Utilisation de array()
4,
'OS' => 'Linux',
'lang' => 'english',
'short_tags' => true
);
var_dump($map);
// clés numériques strictes
// est identique à array(0 => 7, 1 => 8, ...)
$array = array( 7,
8,
0,
156,
-10
);
var_dump($array);
$switching = array( 10, // clé = 0
5 => 6,
3 => 7,
'a' => 4,
11, // clé = 6 (l'indice entier maximal est 5)
'8' => 2, // clé = 8 (entier !)
'02' => 77, // clé = '02'
0 => 12 // la valeur 10 sera écrasée par la valeur 12
);
var_dump($switching);
// tableau vide
$empty = array();
var_dump($empty);
?>
]]>
Collection
]]>
&example.outputs;
La modification directe de valeurs d'un array est possible
en le passant par référence.
Modification d'un élément dans la boucle
]]>
&example.outputs;
ROUGE
[1] => BLEU
[2] => VERTE
[3] => JAUNE
)
]]>
Cet exemple crée un tableau, dont l'indexation commence à 1.
Indexation commençant à 1
'Janvier', 'Février', 'Mars');
print_r($firstquarter);
?>
]]>
&example.outputs;
Janvier
[2] => Février
[3] => Mars
)
]]>
Remplissage d'un tableau
]]>
Les tableaux sont ordonnés. L'ordre peut être modifié en utilisant plusieurs
fonctions. Voir la section sur les fonctions sur les
tableaux pour plus d'informations. La fonction count
peut être utilisée pour compter le nombre d'éléments d'un tableau.
Tri d'un tableau
]]>
Sachant que la valeur d'un tableau peut être n'importe quoi, elle peut
aussi être un autre tableau. Ceci permet la création de tableaux récursifs
et de tableaux multidimensionnels.
Tableaux récursifs et multidimensionnels
array ( "a" => "orange",
"b" => "banana",
"c" => "apple"
),
"numbers" => array ( 1,
2,
3,
4,
5,
6
),
"holes" => array ( "first",
5 => "second",
"third"
)
);
var_dump($fruits);
// Quelques exemples pour retrouver les valeurs dans le tableau ci-dessus
echo $fruits["holes"][5]; // affiche "second"
echo $fruits["fruits"]["a"]; // affiche "orange"
unset($fruits["holes"][0]); // efface "first"
// Création d'un tableau multidimensionnel
$juices["apple"]["green"] = "good";
var_dump($juices);
?>
]]>
L'assignation d'un tableau induit toujours la copie des valeurs.
Utiliser l'opérateur de référence
pour copier un tableau par référence.
Copier des tableaux
]]>