2010-06-14 11 views
6

Devo scrivere a deserializzare un dizionario in PHP che è stato serializzato utilizzando cPickle in Python.Deserializzazione cPickle di Python da PHP?

In questo caso specifico, probabilmente potrei semplicemente inserire le informazioni desiderate, ma c'è un modo migliore? Qualche estensione per PHP che mi consentirebbe di deserializzare più nativamente l'intero dizionario?

A quanto pare viene serializzato in Python come questo:

import cPickle as pickle 

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

contenuti di tali serializzazione non possono essere incollati facilmente qui, perché contiene dati binari.


Soluzione

Dalla fine Python è Django, ho finito per creare own JSON SessionStore.

+3

Hai menzionato che la serializzazione non è sotto il tuo controllo. Come stai ricevendo questi dati in salamoia? Un file locale? –

+0

Viene dal database di Django, è session_data nella tabella delle sessioni di Django. Probabilmente finirò per scrivere SessionMiddleware per serializzare il session_data come JSON. Ho solo desiderato di non dover modificare l'app di Django per questo. – Ciantic

risposta

7

Se si desidera condividere oggetti di dati tra programmi scritti in lingue diverse, potrebbe essere più semplice serializzare/deserializzare utilizzando qualcosa come JSON. La maggior parte dei principali linguaggi di programmazione ha una libreria JSON.

+2

Python 2.6+ lo ha integrato e c'è un semplice json per le versioni precedenti. –

+2

Anche se una buona idea, la parte di serializzazione non è sotto il mio controllo. – Ciantic

+0

Per prima cosa ho pensato di non voler hackerare l'app Django, ma poi potrebbe essere una soluzione più veloce. Quindi ecco il mio semplice [JSON SessionStore for Django] (http://gist.github.com/441132) – Ciantic

5

È possibile effettuare una chiamata di sistema? È possibile utilizzare uno script Python come questo per convertire i dati serializzati in 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) 

In questo modo, se il vostro ottenere i dati da un file si potrebbe fare qualcosa di simile:

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

o se si vuole salvarlo in un file questo:

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

Tutto il codice di cui sopra, probabilmente non è perfetto (io non sono uno sviluppatore PHP), ma sarebbe qualcosa di simile a questo lavoro per voi?

1

Se il pickle viene creato dal codice mostrato, non conterrà dati binari, a meno che non si stiano chiamando "dati binari" a capo. Vedi the Python docs. Il seguente codice è stato eseguito da 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.' 
>>> 

Quale di questi sembra più simile a quello che stai vedendo? Puoi pubblicare il contenuto del file in picchiata come visualizzato da un editor esadecimale/dumper o qual è l'equivalente PHP di Python's repr()? Quanti elementi in un dizionario tipico? Quali tipi di dati diversi da "intero" e "stringa di byte da 8 bit" (quale codifica?)?

0

Ho avuto lo stesso problema. Non ho trovato una soluzione, quindi ho creato la mia porta minimalista del modulo python in php. In seguito ho trovato l'adattatore per Serializer Zend PythonPickle da Zend Framework.

Problemi correlati