serialize() ne fonctionne correctement que depuis PHP 4, mais je ne pense pas que vous soyez encore sous une version antérieure… Si c'est le cas, je vous conseille vivement de vous mettre à jour, il en est plus que temps !
Le principe de
serialize() est simple, et bien résumé dans la documentation PHP :
Citation : Documentation PHPserialize() retourne une chaîne contenant une représentation linéaire de value, pour stockage.
C'est une technique pratique pour stocker ou passer des valeurs de PHP entre scripts, sans perdre ni leur structure, ni leur type.
Ah, c'est simple et bien résumé, cela ?
Eh bien mine de rien, oui. Cela signifie simplement qu'on peut « transtyper » une variable, quel que soit son type, en une chaîne de caractères.
Notez les guillemets autour du mot transtyper. En effet, le principe de serialize() n'est pas de faire un transtypage classique, mais bien une linéarisation qui conserve le type (et donc les informations) de la variable originale.
Pour comprendre simplement, testons ce code :
Code : PHP | <?php
$notes = array(7,3,8,9); // Formation d'un array pour la forme
echo serialize($notes); // echo du résultat de serialize() sur cet array
?>
|
Citation : Affichagea:4:{i:0;i:7;i:1;i:3;i:2;i:8;i:3;i:9;}
Un
echo suffit, car
serialize() retourne une chaîne de caractères (en tout cas, s'il n'y a aucune erreur).
Cela nous affichera… quelque chose de peu compréhensible, certes. Mais on arrive à voir que nos valeurs sont toujours là
et dans le même ordre, même si c'est sous une forme différente.
Testons cet autre code, à présent :
Code : PHP | <?php
$notes = array('maths'=>7,'anglais'=>3,'svt'=>8,'algo'=>9);
echo serialize($notes);
?>
|
Citation : Affichagea:4:{s:5:"maths";i:7;s:7:"anglais";i:3;s:3:"svt";i:8;s:4:"algo";i:9;}
Encore quelque chose de peu compréhensible… Mais on retrouve encore nos valeurs, et aussi les clefs !
Mais comment ça marche ?
Pour comprendre, testons ce code :
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 | <?php
$entier = 17;
$bool = TRUE;
$float = 0.75669;
$chaine = "ma chaine";
$array = array(0,4,7,3);
$array2 = array('truc'=>'machin', 'chose'=>8, 9=>'youpie');
echo serialize($entier);
echo '<br />';
echo serialize($bool);
echo '<br />';
echo serialize($float);
echo '<br />';
echo serialize($chaine);
echo '<br />';
echo serialize($array);
echo '<br />';
echo serialize($array2);
?>
|
Citation : Affichagei:17;
b:1;
d:0.75668999999999997374544591366429813206195831298828125;
s:9:"ma chaine";
a:4:{i:0;i:0;i:1;i:4;i:2;i:7;i:3;i:3;}
a:3:{s:4:"truc";s:6:"machin";s:5:"chose";i:8;i:9;s:6:"youpie";}
serialize() prend la variable, et cherche d'abord son type. Cette définition de type sera conservée (
i pour
integer,
b pour
booléen,
d pour
double,
s pour
string et
a pour
array). Selon ce type, il va chercher le nombre d'éléments ou non. Ce nombre d'éléments peut être la longueur d'une chaîne de caractères ou le nombre d'éléments d'un tableau.
Ensuite,
serialize() définit le contenu selon ce type. Dans le cas d'un entier, le contenu ne change pas.
Serializer un entier reviendrait donc à grossir juste la taille (en mémoire) prise par la variable… Oublions donc les entiers.
Pour un booléen,
serialize() traduit la valeur en entier (
TRUE devient
1 et
FALSE devient
0) par transtypage classique. On revient à la même problématique qu'avec les entiers : on évitera de
serializer un booléen.
De même pour une chaîne, à noter que
serialize() place des guillemets autour des chaînes, ce qui peut être intéressant à savoir dans le cas d'un enregistrement en base de données.
Vous remarquerez sûrement que notre nombre décimal est devenu… quelque peu bizarre. Cela est dû à une mauvaise précision de calcul de
serialize() qui n'est réellement pas fait pour traiter des données aussi simples.
La précision de serialize() est indiquée dans le php.ini. Il s'agit de la directive serialize_precision dans PHP Core.
Passons à nos chers arrays !
Il semblerait que
serialize() répète la procédure précédente (déterminer le type, puis le nombre d'éléments, puis la valeur…) pour chaque élément. Une dimension d'un array est délimitée par des accolades.
Et les clefs n'en sont pas exemptes et semblent traitées… comme des valeurs simples !
Mais alors, comment différencier les clefs des valeurs ?
C'est là que joue le nombre d'éléments.
Si l'on a un seul élément, mais qu'on a deux valeurs dans l'array
serializé, c'est qu'il s'agit d'une paire clef/valeur.
De toute façon, tout array est normalement indexé numériquement en interne, par PHP. D'où notre premier affichage.
Et comme on a ainsi une chaîne de caractères (conservant néanmoins parfaitement notre array), on peut facilement la manipuler, pour la transmettre de page en page, l'envoyer en base de données, ou encore l'écrire dans un fichier.
Ah ouais, super… Mais on ne peut rien en faire de cette chaîne de caractères !
Et pof ! Voici
unserialize().
Cette superbe fonction peut se résumer en une phrase : elle fait l'inverse de
serialize().
En partant d'une chaîne de caractères provenant de
serialize(),
unserialize() récupère les données et renvoie… les données originales. Concrètement, cela signifie qu'en testant ceci :
Code : PHP | <?php
$notes = array('maths'=>1,'svt'=>8,'algo'=>6,'philo'=>5); // Un array…
$serialized = serialize($notes); // On serialize et on stocke cette chaîne.
echo '<pre>'; // Les balises « pre » permettent d'afficher lisiblement un array.
print_r(unserialize($serialized)); // On utilise « print_r » pour une bonne raison.
echo '</pre>';
?>
|
Citation : AffichageArray
(
[maths] => 1
[svt] => 8
[algo] => 6
[philo] => 5
)
on récupère notre array, intact.
