Page 1 sur 2

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

Posté : 13 oct. 2007, 16:32
par kiki650
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 !

Posté : 13 oct. 2007, 17:37
par Tracker
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.

Posté : 13 oct. 2007, 17:45
par kiki650
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.

Posté : 13 oct. 2007, 19:50
par Tracker
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));
?> 

Posté : 13 oct. 2007, 20:38
par kiki650
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.

Posté : 13 oct. 2007, 21:12
par Tracker
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.

Posté : 13 oct. 2007, 22:01
par kiki650
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?

Posté : 13 oct. 2007, 22:03
par kiki650
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";}";

Posté : 13 oct. 2007, 22:10
par Tracker
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.

Posté : 13 oct. 2007, 22:13
par kiki650
Ca veut dire quoi en collation?

Posté : 13 oct. 2007, 22:21
par Tracker
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

Posté : 13 oct. 2007, 22:25
par kiki650
CREATE TABLE sessions(
id varchar(32),
access int(10),
dataobject varchar(500)
)
ALTER TABLE `sessions` ADD PRIMARY KEY (id)

Posté : 13 oct. 2007, 22:28
par Tracker
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 )

Posté : 13 oct. 2007, 22:36
par kiki650
J'ai essayé un peu toutes les possibilités. J'ai essayé blob et je récupére toujours la meme chose, avec les �.

Posté : 13 oct. 2007, 22:51
par Tracker
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.