Désérialiser un objet provenant d'une table MySQL

Eléphanteau du PHP | 11 Messages

13 oct. 2007, 16:32

Bonjour à tous,

Je suis vraiment bloqué sur un pb de sérialistation/désérialisation que j'utilise avec des sessions.

1. Lorsque l'utilisateur se loggue, je crée un objet "user" (contenant ses infos pesonnelles).
2. Je sérialise cet objet
3. Je l'enregistre dans un champ de type "blob" de ma table MySQL avec l'id de la session.
4. A l'ouverture d'une seconde page php, je récupére l'id de la session
5. Je cherche l'enregistrement de ma session poru trouver mon objet sérialisé.
6. Je voudrais désérialiser le contenu récupéré:

Pour cela, je fais:
<?php
$db = new PDO('mysql:host=localhost;dbname=sessions', 'root', '', array(PDO::ATTR_PERSISTENT => true)); 
      $getData = $db->prepare("SELECT dataobject FROM sessions AS Session WHERE Session.id = ?");
      $getData->bindParam(1, session_id());
      $getData->execute();    
      $allData = $getData->fetch(PDO::FETCH_ASSOC);
      $donnees = $allData['dataobject'];
      $client = unserialize($donnees);
?>
Je récupere bien dans $donnees je chaine de caractères, mais quand je la passe dans dla fonction unserialize(), je n'ai plus rien, comme si il n'arrivait pas à la décoder.

Pouvez-vous m'aider?
Si vous avez besoin de plus de détails pour m'aider, n'hésitez pas à me demander.

Merci !

Eléphant du PHP | 443 Messages

13 oct. 2007, 17:37

Regarde cette exemple de la doc:
<?php
$db = new PDO('odbc:SAMPLE', 'db2inst1', 'ibmdb2');
$stmt = $db->prepare("select contenttype, imagedata from images where id=?");
$stmt->execute(array($_GET['id']));
$stmt->bindColumn(1, $type, PDO::PARAM_STR, 256);
$stmt->bindColumn(2, $lob, PDO::PARAM_LOB);
$stmt->fetch(PDO::FETCH_BOUND);

header("Content-Type: $type");
fpassthru($lob);
?>
Il est fort probable, que pour les types blob, clob.. la valeur retournée lors du fetch soit un pointeur vers un flux. Essaie de récupérer la chaine sérialisée en utilisant la fonction stream_get_contents($allData['dataobject']), et désérialise ensuite.

Tracker.

Eléphanteau du PHP | 11 Messages

13 oct. 2007, 17:45

Salut Traker,

Je comprends pas trop l'exemple, masi si je test ce que tu me dis, j'obtiens ca:
Warning: stream_get_contents() expects parameter 1 to be resource

Merci de ton aide.

Eléphant du PHP | 443 Messages

13 oct. 2007, 19:50

Et si tu modifies ton code en suivant l'exemple de la doc ?:
<?php
$db = new PDO('mysql:host=localhost;dbname=sessions', 'root', '', array(PDO::ATTR_PERSISTENT => true)); 
      $getData = $db->prepare("SELECT dataobject FROM sessions AS Session WHERE Session.id = ?");
      $getData->bindParam(1, session_id());
      $getData->execute();
      $getData->bindColumn(1, $lob, PDO::PARAM_LOB);
      $getData->fetch(PDO::FETCH_BOUND);
      $client = unserialize(stream_get_contents($lob));
?> 

Eléphanteau du PHP | 11 Messages

13 oct. 2007, 20:38

J'ai toujours le meme pb:
Warning: stream_get_contents() expects parameter 1 to be resource

Tu crois que blob est bien adapté pour stocher ce type de données?

Merci pour ton aide.

Eléphant du PHP | 443 Messages

13 oct. 2007, 21:12

J'ai toujours le meme pb:
Warning: stream_get_contents() expects parameter 1 to be resource

Tu crois que blob est bien adapté pour stocher ce type de données?

Merci pour ton aide.
Je pense t'avoir mis sur une fausse piste, en fouillant sur le net le driver pdo_mysql semble retourner des strings et pas des identifiants de resource (stream) pour les lobs comme il serait logique de trouver.
Extrait du trac de propel (tournant sur PDO)
PDO returns stream resources from certain databases for LOB columns (e.g. PostgreSQL), but it seems that only strings are returned by the MySQL driver.
Donc dans le dernier code, la variable $lob doit contenir une chaine.
Essaie de comparer la chaine que tu insères dans la base à celle que tu récupères dans $lob...

Tracker.

Eléphanteau du PHP | 11 Messages

13 oct. 2007, 22:01

J'ai fais afficher les notices et j'en ai une qui me dit :
Notice: unserialize() [function.unserialize]: Error at offset 0 of 101 bytes in C:\Progr......

J'ai peut etre un pb à l'encodage? $lob me renvoit exactement ce que j'ai dans ma table.
Mais c'est vrai que j'ai des caractères bizzares qd je récupére mon champ "dataobject". J'ai des �. C'est peut etre pas normal?
L'interclassement de mon champ est : latin1_swedish_ci

Tu aurais une idée? Tu pense que je récupère pas ce qu'il faut?

Eléphanteau du PHP | 11 Messages

13 oct. 2007, 22:03

J'essaye de désérialiser ca :

user|s:88:"O:4:"User":3:{s:3:"nom";s:2:"da";s:12:"�User�prenom";s:2:"da";s:9:"�User�tel";s:2:"23";}";

Eléphant du PHP | 443 Messages

13 oct. 2007, 22:10

J'essaye de désérialiser ca :

user|s:88:"O:4:"User":3:{s:3:"nom";s:2:"da";s:12:"�User�prenom";s:2:"da";s:9:"�User�tel";s:2:"23";}";

Essaie de mettre "binary" en collation de ton champ blob, mais c'est étrange un blob est par définition binaire...

Tracker.
Modifié en dernier par Tracker le 13 oct. 2007, 22:30, modifié 1 fois.

Eléphanteau du PHP | 11 Messages

13 oct. 2007, 22:13

Ca veut dire quoi en collation?

Eléphant du PHP | 443 Messages

13 oct. 2007, 22:21

Ca veut dire quoi en collation?
Tu peux filer le code SQL utilisé pour créer ta table contenant le blob ?

[edit]
Je ne sais pas ce que tu appelles interclassement, mais quand tu écris latin1_swedish_ci, moi je comprends:
Charset: latin1
Collation: latin1_swedish_ci
pour plus d'info va voir ici
Modifié en dernier par Tracker le 13 oct. 2007, 22:26, modifié 1 fois.

Eléphanteau du PHP | 11 Messages

13 oct. 2007, 22:25

CREATE TABLE sessions(
id varchar(32),
access int(10),
dataobject varchar(500)
)
ALTER TABLE `sessions` ADD PRIMARY KEY (id)

Eléphant du PHP | 443 Messages

13 oct. 2007, 22:28

CREATE TABLE sessions(
id varchar(32),
access int(10),
dataobject varchar(500)
)
ALTER TABLE `sessions` ADD PRIMARY KEY (id)
Mais dataobject n'est pas un blob !!??!!??

Ecris plutot

Code : Tout sélectionner

CREATE TABLE sessions( id varchar(32), access int(10), dataobject blob )

Eléphanteau du PHP | 11 Messages

13 oct. 2007, 22:36

J'ai essayé un peu toutes les possibilités. J'ai essayé blob et je récupére toujours la meme chose, avec les �.

Eléphant du PHP | 443 Messages

13 oct. 2007, 22:51

J'ai essayé un peu toutes les possibilités. J'ai essayé blob et je récupére toujours la meme chose, avec les �.
Quand tu prépares l'ordre d'insertion, lors de la définition des paramètres, vérifie que tu fais:
$stmt->bindParam(':blob', serialize(...), PDO::PARAM_BLOB);
Laisse le champ en type blob dans la base.

Tracker.