【问题标题】:Python's cPickle deserialization from PHP?来自PHP的Python Pickle反序列化?
【发布时间】:2011-03-03 17:20:55
【问题描述】:

我必须在 PHP 中反序列化一个字典,该字典是在 Python 中使用 cPickle 序列化的

在这种特定情况下,我可能只是 regexp 所需的信息,但有更好的方法吗? PHP 的任何扩展都可以让我更本机地反序列化整个字典?

显然它在 Python 中是这样序列化的:

import cPickle as pickle

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

这种序列化的内容不能轻易粘贴到这里,因为它包含二进制数据。

【问题讨论】:

  • 您提到序列化不在您的控制之下。你是如何收到这个腌制数据的?本地文件?
  • 它来自django中的数据库,是django会话表中的session_data。我可能最终实际上编写了 SessionMiddleware 来将 session_data 序列化为 JSON。我只是希望我不必为此修改 Django 应用程序。

标签: php python json serialization pickle


【解决方案1】:

如果您想在用不同语言编写的程序之间共享数据对象,则使用JSON 之类的东西可能更容易进行序列化/反序列化。大多数主要的编程语言都有一个 JSON 库。

【讨论】:

  • Python 2.6+ 已内置,早期版本有 simplejson。
  • 虽然是个好主意,但序列化部分不在我的控制之下。
  • 我一开始以为我不想破解 Django 应用程序,但话又说回来,它可能是更快的解决方案。所以这是我的简单JSON SessionStore for Django
【解决方案2】:

你能做一个系统调用吗?您可以使用这样的 python 脚本将 pickle 数据转换为 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)

这样,如果您从文件中获取数据,您可以执行以下操作:

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

或者如果你想把它保存到一个文件中:

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

上面的所有代码可能都不完美(我不是 PHP 开发人员),但是这样的代码对你有用吗?

【讨论】:

    【解决方案3】:

    如果泡菜是由您显示的代码创建的,那么它将不包含二进制数据——除非您将换行符称为“二进制数据”。见the Python docs。以下代码由 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.'
    >>>
    

    以上哪个看起来最像您所看到的?您可以发布由十六进制编辑器/转储程序显示的腌制文件内容,或者任何与 Python 的 repr() 等效的 PHP 内容吗?一本典型的字典有多少项?除了“整数”和“8位字节的字符串”之外还有哪些数据类型(什么编码?)?

    【讨论】:

      【解决方案4】:

      我知道这是古老的,但我只需要为 Django 1.3 应用程序(大约 2012 年)执行此操作并发现:

      https://github.com/terryf/Phpickle

      所以以防万一,有一天,其他人也需要同样的解决方案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-16
        • 1970-01-01
        • 1970-01-01
        • 2013-10-05
        • 2014-09-16
        相关资源
        最近更新 更多