2010-06-14 5 views
6

Je dois désérialiser un dictionnaire en PHP qui a été sérialisé en utilisant cPickle en Python.La désérialisation cPickle de Python de PHP?

Dans ce cas précis, je pourrais probablement regexp l'information voulue, mais est-il un meilleur moyen? Des extensions pour PHP qui me permettraient de désérialiser plus nativement le dictionnaire entier?

Apparemment, il est sérialisé en Python comme ceci:

import cPickle as pickle 

data = { 'user_id' : 5 } 
pickled = pickle.dumps(data) 
print pickled 

contenu de ces sérialisation ne peuvent pas être collés facilement ici, car il contient des données binaires.


Solution

Depuis la fin Python est Django, je fini par créer own JSON SessionStore.

+3

Vous avez mentionné que la sérialisation n'est pas sous votre contrôle. Comment recevez-vous ces données décapées? Un fichier local? –

+0

Il provient de la base de données de Django, c'est session_data dans la table de session django. Je finis probablement par écrire SessionMiddleware pour sérialiser la session_data en JSON. Je voulais juste ne pas avoir à modifier l'application Django pour cela. – Ciantic

Répondre

7

Si vous souhaitez partager des objets de données entre des programmes écrits en différentes langues, il peut être plus facile de sérialiser/désérialiser en utilisant quelque chose comme JSON à la place. La plupart des principaux langages de programmation ont une bibliothèque JSON.

+2

Python 2.6+ l'a intégré, et il y a simplejson pour les versions antérieures. –

+2

Bien que ce soit une bonne idée, la partie de sérialisation n'est pas sous mon contrôle. – Ciantic

+0

J'ai d'abord pensé que je ne voulais pas pirater l'application Django, mais là encore, il pourrait être une solution plus rapide. Voici donc mon simple [JSON SessionStore pour Django] (http://gist.github.com/441132) – Ciantic

5

Pouvez-vous faire un appel système? Vous pouvez utiliser un script python comme celui-ci pour convertir les données de conserves au vinaigre en JSON:

# pickle2json.py 
import sys, optparse, cPickle, os 
try: 
    import json 
except: 
    import simplejson as json 

# Setup the arguments this script can accept from the command line 
parser = optparse.OptionParser() 
parser.add_option('-p','--pickled_data_path',dest="pickled_data_path",type="string",help="Path to the file containing pickled data.") 
parser.add_option('-j','--json_data_path',dest="json_data_path",type="string",help="Path to where the json data should be saved.") 
opts,args=parser.parse_args() 

# Load in the pickled data from either a file or the standard input stream 
if opts.pickled_data_path: 
    unpickled_data = cPickle.loads(open(opts.pickled_data_path).read()) 
else: 
    unpickled_data = cPickle.loads(sys.stdin.read()) 

# Output the json version of the data either to another file or to the standard output 
if opts.json_data_path: 
    open(opts.json_data_path, 'w').write(json.dumps(unpickled_data)) 
else: 
    print json.dumps(unpickled_data) 

De cette façon, si vous obtenir les données d'un fichier que vous pourriez faire quelque chose comme ceci:

<?php 
    exec("python pickle2json.py -p pickled_data.txt", $json_data = array()); 
?> 

ou si vous voulez enregistrer dans un fichier ceci:

<?php 
    system("python pickle2json.py -p pickled_data.txt -j p_to_j.json"); 
?> 

Tout le code ci-dessus est probablement pas parfait (je ne suis pas un développeur PHP), mais serait quelque chose comme ce travail pour vous?

1

Si le pointeur est créé par le code que vous avez affiché, alors il ne contiendra pas de données binaires - sauf si vous appelez des lignes nouvelles "données binaires". Voir . Le code suivant a été exécuté par Python 2.6.

>>> import cPickle 
>>> data = {'user_id': 5} 
>>> for protocol in (0, 1, 2): # protocol 0 is the default 
...  print protocol, repr(cPickle.dumps(data, protocol)) 
... 
0 "(dp1\nS'user_id'\np2\nI5\ns." 
1 '}q\x01U\x07user_idq\x02K\x05s.' 
2 '\x80\x02}q\x01U\x07user_idq\x02K\x05s.' 
>>> 

Lequel des éléments ci-dessus ressemble le plus à ce que vous voyez? Pouvez-vous poster le contenu du fichier pickled tel qu'il est affiché par un éditeur/dumper hexadécimal ou quel que soit l'équivalent PHP de repr() de Python? Combien d'éléments dans un dictionnaire typique? Quels sont les types de données autres que "entier" et "chaîne de 8 bits" (quel encodage?)?

0

J'ai eu le même problème. Je n'ai pas trouvé de solution donc j'ai créé mon propre port minimal de module python en php. Plus tard j'ai trouvé Zend Serializer Adapter PythonPickle de Zend Framework.

Questions connexes