2010-06-14 32 views
6

Tôi phải deserialize từ điển trong PHP được tuần tự hóa bằng cách sử dụng cPickle bằng Python.Gỡ lỗi cPickle của Python từ PHP?

Trong trường hợp cụ thể này, tôi có thể chỉ cần regexp thông tin mong muốn, nhưng có cách nào tốt hơn không? Bất kỳ phần mở rộng cho PHP mà sẽ cho phép tôi deserialize nhiều nguyên bản toàn bộ từ điển?

Rõ ràng nó được xuất bản trong Python như thế này:

import cPickle as pickle 

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

Nội dung serialization như vậy không thể được dán một cách dễ dàng đến đây, bởi vì nó có chứa dữ liệu nhị phân.


Giải pháp

Kể từ cuối Python là Django, tôi đã kết thúc tạo own JSON SessionStore.

+3

Bạn đã đề cập đến việc tuần tự hóa không nằm trong tầm kiểm soát của bạn. Làm thế nào bạn nhận được dữ liệu ngâm này? Tệp cục bộ? –

+0

Nó đến từ cơ sở dữ liệu ở Django, đó là session_data trong bảng phiên django. Tôi có thể sẽ thực sự viết SessionMiddleware để tuần tự hóa session_data như JSON. Tôi chỉ ước tôi không phải sửa đổi ứng dụng Django cho việc này. – Ciantic

Trả lời

7

Nếu bạn muốn chia sẻ các đối tượng dữ liệu giữa các chương trình được viết bằng các ngôn ngữ khác nhau, việc tuần tự hóa/deserialize có thể dễ dàng hơn bằng cách sử dụng một cái gì đó như JSON thay thế. Hầu hết các ngôn ngữ lập trình chính đều có một thư viện JSON.

+2

Python 2.6+ đã tích hợp sẵn và có các phiên bản cũ hơn cho các phiên bản trước đó. –

+2

Mặc dù một ý tưởng hay, phần tuần tự hóa không nằm trong tầm kiểm soát của tôi. – Ciantic

+0

Lần đầu tiên tôi nghĩ rằng tôi không muốn hack ứng dụng Django, nhưng sau đó một lần nữa nó có thể là giải pháp nhanh hơn. Vì vậy, đây là [JSON SessionStore cho Django] đơn giản của tôi (http://gist.github.com/441132) – Ciantic

5

Bạn có thể thực hiện cuộc gọi hệ thống không? Bạn có thể sử dụng một kịch bản python như thế này để chuyển đổi dữ liệu dưa vào 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) 

Bằng cách này, nếu bạn nhận được dữ liệu từ một tập tin bạn có thể làm một cái gì đó như thế này:

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

hoặc nếu bạn muốn lưu tệp này vào một tệp này:

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

Tất cả mã ở trên có lẽ không hoàn hảo (tôi không phải là nhà phát triển PHP), nhưng điều này có thể phù hợp với bạn?

1

Nếu dưa được tạo bởi mã bạn đã hiển thị, thì nó sẽ không chứa dữ liệu nhị phân - trừ khi bạn đang gọi newlines "dữ liệu nhị phân". Xem the Python docs. Mã sau được chạy bởi 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.' 
>>> 

Điều nào ở trên trông giống như những gì bạn đang thấy? Bạn có thể đăng nội dung tệp đã được hiển thị bằng trình chỉnh sửa hex/dumper hay bất kỳ giá trị nào tương đương PHP của repr() của Python không? Có bao nhiêu mục trong một từ điển điển hình? Những loại dữ liệu nào khác với "số nguyên" và "chuỗi byte 8 bit" (mã hóa nào?)?

0

Tôi cũng gặp vấn đề tương tự. Tôi không tìm thấy giải pháp vì vậy tôi đã tạo cổng mô-đun python tối giản của riêng mình trong php. Sau đó, tôi tìm thấy Bộ đổi nguồn nối tiếp Zend PythonPickle từ Zend Framework.