lundi 26 septembre 2016

PHP a 2 types de tableaux

Derrière ce titre racoleur se cache une vérité : PHP gère bien 2 types de tableaux. Une version "standard", avec des clefs numériques, et une version "associative", avec des clefs type string.
Documentation PHP sur array

Comment PHP passe d'un tableau standard à un tableau associatif, sans nous le dire, et sans qu'on puisse le voir même avec un var_dump() ?
Si on ajoute des valeurs dans un tableau qui n'a que des clefs numériques, qui partent de 0, et qui n'ont pas de trou, alors c'est un tableau standard.
Du moment qu'un tableau a des trous dans ses clefs numériques, ou qu'on ajoute une clef type string, alors c'est un tableau associatif.

Un auto-cast en int des clefs est effectué en interne. Ce qui veut dire qu'une clef '0' sera automatiquement transformée en intval('0'), et notre tableau final n'aura pas une clef type string mais bien type int.
Cet auto-cast supprime également les parties décimales des float. Par exemple, une clef 0.5 sera transformée en 0, alors qu'une clef '0.5' restera bien telle quelle.

Quelques exemples pour illustrer cette explication :
// tableau standard $array = [ 'foo', 'bar' ]; // type de tableau non modifié, c'est encore un tableau standard $array[] = 'baz'; // typage transparent en tableau associatif $array[10] = 'tou'; // tableau standard, même si on met une chaine en clef // comme c'est '0', c'est casté en int en interne. la clef '0' devient 0. $array2 = [ '0' => 'foo' ]; // tableau associatif, on n'a pas de clef pour 2 $array3 = [ 0 => 'foo', 1 => 'bar', 3 => 'baz' ]; // tableau standard, l'auto-cast des clefs transforme 1.5 en 1 $array4 = [ 0 => 'foo', 1.5 => 'bar' ]; // tableau associatif, la clef '1.5' conserve son type string $array5 = [ 0 => 'foo', '1.5' => 'bar' ];

La réaction de json_encode() aux 2 types de tableaux


Pour se rendre compte de tout ça, un appel à json_encode($array) peut-être effectué avec les cas de test ci-dessus :
  • Quand le retour est un tableau, c'est un tableau standard
  • Quand le retour est un objet, c'est un tableau associatif
Cette différence est très importante.
Par exemple, pour les cas $array3 et $array5, si on fait un bête json_decode(json_encode($array3)), on n'obtient pas un array, mais un \stdClass !

Aucun commentaire:

Enregistrer un commentaire