Les tableaux

Un tableau en PHP est en fait une carte ordonnée. Une carte est un type qui associe des valeurs en clés. Ce type est optimisé pour différentes utilisations ; il peut être considéré comme un tableau, une liste, une table de hashage, 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 vous trouverez au moins un exemple pour chacun des cas évoqués. Pour plus d'informations, reportez-vous aux différentes explications sur le sujet que l'on trouve sur le web.

Syntaxe

Syntaxe 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, i.e. 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.

Depuis PHP 5.4, vous pouvez également utiliser la syntaxe courte, qui remplace array() par [].

Exemple #1 Un tableau simple

<?php
$array = array(
	"foo" => "bar",
	"bar" => "foo",
);

// depuis PHP 5.4
$array = [
	"foo" => "bar",
	"bar" => "foo",
];
?>

La clé key peut être soit un integer, soit une chaîne de caractères. La valeur value peut être de n'importe quel type.

De plus, les modifications de type pour la clé key peuvent survenir :

  • Les chaînes de caractères contenant un entier valide seront modifiées en un type entier. I.e. la clé "8" sera actuellement stockée comme l'entier 8. D'un autre côté, "08" se 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. I.e. la clé 8.7 sera stockée sous l'entier 8.
  • Les booléens seront modifiés en entier également, i.e. 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, i.e. la clé null sera stockée sous la chaîne de caractère "".
  • Les tableaux et les objets ne peuvent pas être utilisés comme clé. Si vous le tentez, l'alerte suivante sera émise : Illegal offset type.

Si plusieurs éléments dans la déclaration d'un tableau utilise la même clé, seule la dernière sera utilisée, écrasant ainsi toutes les précédentes.

Exemple #2 Exemple sur la modification de type et l'écrasement

<?php
$array = array(
	1	=> "a",
	"1"  => "b",
	1.5  => "c",
	true => "d",
);
var_dump($array);
?>
<?php
$array = array(
	"foo" => "bar",
	"bar" => "foo",
	100   => -100,
	-100  => 100,
);
var_dump($array);
?>
<?php
$array = array("foo", "bar", "hallo", "world");
var_dump($array);
?>
<?php
$array = array(
		 "a",
		 "b",
	6 => "c",
		 "d",
);
var_dump($array);
?>
<?php
$array = array(
	"foo" => "bar",
	42	=> 24,
	"multi" => array(
		 "dimensional" => array(
			 "array" => "foo"
		 )
	)
);

var_dump($array["foo"]);
var_dump($array[42]);
var_dump($array["multi"]["dimensional"]["array"]);
?>
<?php
function getArray() {
	return array(1, 2, 3);
}

// Depuis PHP 5.4
$secondElement = getArray()[1];

// Avant PHP 5.4
$tmp = getArray();
$secondElement = $tmp[1];

// ou
list(, $secondElement) = getArray();
?>

Note:

Une tentative d'accès à une clé d'un tableau qui n'a pas été définie revient à tenter d'accès à une variable non définie : une alerte de niveau E_NOTICE sera émise, et le résultat vaudra NULL.

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é 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 entier ou une chaîne de caractères
// valeur peut être n'importe quel type

Si $arr n'existe pas lors de l'assignation, 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 (i.e. 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 assignement direct.

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.

<?php
$arr = array(5 => 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

unset($arr);	// Ceci efface complètement le tableau
?>

Note:

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).

Notez 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 :

<?php
// Création d'un tableau simple.
$array = array(1, 2, 3, 4, 5);
print_r($array);

// Maintennant, on efface tous les éléments, mais on conserve le tableau :
foreach ($array as $i => $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);
?>

L'exemple ci-dessus va afficher :

Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    [4] => 5
)
Array
(
)
Array
(
    [5] => 6
)
Array
(
    [0] => 6
    [1] => 7
)

Fonctions utiles

Il y a beaucoup de fonctions utiles pour travailler avec les tableaux. Nous vous invitons à lire la section de ce manuel sur les fonctions en rapport avec les tableaux.

Note:

La fonction unset() permet d'effacer les clés d'un tableau. Soyez attentif sur le fait que le tableau ne sera pas ré-indexé. Si vous voulez réaliser un effacement complet et une ré-indexation de votre tableau, vous devez utiliser la fonction array_values().

<?php
$a = array(1 => 'one', 2 => 'two', 3 => 'three');
unset($a[2]);
/* produira un tableau comme ceci
   $a = array(1 => 'one', 3 => 'three');
   et NON un tableau comme ceci
   $a = array(1 => 'one', 2 =>'three');
*/

$b = array_values($a);
// Maintenant, $b vaut array(0 => 'one', 1 =>'three')
?>

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 tableau

Pourquoi $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'ancien script :

<?php
$foo[bar] = 'enemy';
echo $foo[bar];
// etc
?>

C'est incorrect, mais ça fonctionne. La raison est que ce code a une constante indéfinie (bar) plutôt qu'une chaîne ('bar' - noter les guillemets). PHP peut définir plus loin une constante portant le même nom. 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.

Note: Ceci ne signifie pas qu'il faut toujours mettre la clé entre guillemets. N'utilisez pas de guillemets avec les clés qui sont des constantes ou des variables, car cela empêcherait PHP de les interpréter.

<?php
error_reporting(E_ALL);
ini_set('display_errors', true);
ini_set('html_errors', false);
// Tableau simple :
$array = array(1, 2);
$count = count($array);
for ($i = 0; $i < $count; $i++) {
	echo "\nVérification de $i : \n";
	echo "Mauvais : " . $array['$i'] . "\n";
	echo "Bon : " . $array[$i] . "\n";
	echo "Mauvais : {$array['$i']}\n";
	echo "Bon : {$array[$i]}\n";
}
?>

L'exemple ci-dessus va afficher :

Vérification de 0 :
Notice: Undefined index:  $i in /path/to/script.html on line 9
Mauvais :
Bon : 1
Notice: Undefined index:  $i in /path/to/script.html on line 11
Mauvais :
Bon : 1

Vérification de 1 :
Notice: Undefined index:  $i in /path/to/script.html on line 9
Mauvais :
Bon : 2
Notice: Undefined index:  $i in /path/to/script.html on line 11
Mauvais :
Bon : 2

Plus d'exemples pour expliquer ce comportement :

<?php
// Affichons toutes les erreurs
error_reporting(E_ALL);

$arr = array('fruit' => 'apple', 'veggie' => 'carrot');

// Correct
print $arr['fruit'];  // apple
print $arr['veggie']; // carrot

// Incorrect.  Ceci fonctionne mais PHP émettera une erreur de type E_NOTICE car
// on utilise la constante nommée fruit qui est indéfinie
// 
// Notice: Use of undefined constant fruit - assumed 'fruit' in...
print $arr[fruit];	// apple

// 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
print $arr['fruit'];  // apple
print $arr[fruit];	// carrot

// Ce qui squit est correct, car c'est dans une chaîne. Les constantes ne sont pas recherchées
// dans les chaînes, et donc, aucune alerte E_NOTICE ne sera émise
print "Hello $arr[fruit]";	  // Hello apple

// Avec une exception : les parenthèses autour d'un tableau dans une chaîne permettent
// aux constantes d'être interprétées
print "Hello {$arr[fruit]}";	// Hello carrot
print "Hello {$arr['fruit']}";  // Hello apple

// Ceci ne fonctionnera pas, et en résultera une erreur d'analyse, comme ceci :
// Parse error: parse error, expecting T_STRING' or T_VARIABLE' or T_NUM_STRING'
// Ceci arrive lors de l'utilisation d'une supergloables dans les chaînes
print "Hello $arr[ 'fruit']";
print "Hello $_GET[ 'foo']";

// La concaténation est une autre solution
print "Hello " . $arr['fruit']; // Hello apple
?>

Lorsque error_reporting est défini afin de montrer les erreurs de type E_NOTICE (en le définissant à E_ALL, par exemple), une telle pratique devient immédiatement visible. Par défaut, error_reporting n'est pas défini pour afficher toutes les alertes.

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 :

<?php
echo $arr[somefunc($bar)];
?>

C'est un exemple d'utilisation d'une fonction retournant une valeur qui sera la clé du tableau. PHP comprend également les constantes :

<?php
$error_descriptions[E_ERROR]   = "A fatal error has occured";
$error_descriptions[E_WARNING] = "PHP issued a warning";
$error_descriptions[E_NOTICE]  = "This is just an informal notice";
?>

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 :

<?php
$error_descriptions[1] = "A fatal error has occured";
$error_descriptions[2] = "PHP issued a warning";
$error_descriptions[8] = "This is just an informal notice";
?>

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.

Note: Pour être plus clair, dans une chaîne entourée de guillemets doubles, il est valide de ne pas entourer les indexes d'un tableau avec des guillemets, et donc, "$foo[bar]" est valide. Voir les exemples ci-dessous pour plus détails mais aussi la section sur l'analyse des variables dans les chaînes.

Conversion en un tableau

Pour tous les types : entier, nombre décimal, chaîne de caractères, booléen et ressource, le fait de convertir une valeur en un tableau résulte en un tableau contenant un seul élément dont l'indexe 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 inaccessible; 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. Ce comportement peut amener à des résultats inattendus :

<?php

class A {
	private $A; // Ceci devient '\0A\0A'
}

class B extends A {
	private $A; // Ceci devient '\0B\0A'
	public $AA; // Ceci devient 'AA'
}

var_dump((array) new B());
?>

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ésultat 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.

Exemples

Le type tableau en PHP est vraiment versatile. Voici quelques exemples :

<?php
// This
$a = array( 'color' => 'red',
			'taste' => 'sweet',
			'shape' => 'round',
			'name'  => 'apple',
			 4		// la clé sera 0
		  );

// est strictement équivalent à
$a = array();
$a['color'] = 'red';
$a['taste'] = 'sweet';
$a['shape'] = 'round';
$a['name']  = 'apple';
$a[]		= 4;		// la clé sera 0

$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').
?>

Exemple #8 Utilisation de array()

<?php
// Tableau comme carte de propriétés
$map = array( 'version'	=> 4,
			  'OS'		 => 'Linux',
			  'lang'	   => 'english',
			  'short_tags' => true
			);

// clés numériques strictes
$array = array( 7,
				8,
				0,
				156,
				-10
			  );
// est identique à array(0 => 7, 1 => 8, ...)

$switching = array(		 10, // clé = 0
					5	=>  6,
					3	=>  7, 
					'a'  =>  4,
							11, // clé = 6 (l'indice entier maximal est 5)
					'8'  =>  2, // clé = 8 (intier !)
					'02' => 77, // clé = '02'
					0	=> 12  // la valeur 10 sera écrasée par la valeur 12
				  );

// empty array
$empty = array();
?>

Exemple #9 Collection

<?php
$colors = array('rouge', 'bleu', 'verte', 'jaune');

foreach ($colors as $color) {
	echo "Aimez-vous la couleur $color ?\n";
}

?>
<?php
// PHP 5
foreach ($colors as &$color) {
	$color = strtoupper($color);
}
unset($color); /* On s'assure que les écritures suivantes
sur $color ne modifie pas le dernier élément du tableau */

// Astuce pour les anciennes versions
foreach ($colors as $key => $color) {
	$colors[$key] = strtoupper($color);
}

print_r($colors);
?>
<?php
$firstquarter  = array(1 => 'Janvier', 'Février', 'Mars');
print_r($firstquarter);
?>
<?php
// Remplit un tableau avec tous les éléments d'un dossier
$handle = opendir('.');
while (false !== ($file = readdir($handle))) {
	$files[] = $file;
}
closedir($handle); 
?>

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.

Exemple #13 Tri d'un tableau

<?php
sort($files);
print_r($files);
?>

Sachant que la valeur d'une 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.

Exemple #14 Tableaux récursifs et multidimensionnels

<?php
$fruits = array ( "fruits"  => array ( "a" => "orange",
									   "b" => "banana",
									   "c" => "apple"
									 ),
				  "numbers" => array ( 1,
									   2,
									   3,
									   4,
									   5,
									   6
									 ),
				  "holes"   => array (	  "first",
									   5 => "second",
											"third"
									 )
				);

// 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"; 
?>

L'assignation d'un tableau induit toujours la copie des valeurs. Utilisez l'opérateur de référence pour copier un tableau par référence.

<?php
$arr1 = array(2, 3);
$arr2 = $arr1;
$arr2[] = 4; // $arr2 est modifié,
			 // $arr1 vaut toujours array(2, 3)

$arr3 = &$arr1;
$arr3[] = 4; // maintenant, $arr1 et $arr3 sont identiques
?>
LoadingChargement en cours