Python Tips: PHP でシリアライズされたデータを Python で扱いたい

今回は PHP でシリアライズされたデータを Python で扱う方法をご紹介します。

PHP でシリアライズされたデータを Python で扱うときはその名も phpserialize というライブラリを使うのが便利です。

基本的な使い方を見ていきましょう。まずは最も基本となる「 PHP 側でシリアライズされたデータを読み込む方法」から。

文字列の場合はこんな感じになります。

# ライブラリの読み込み
from phpserialize import loads

# PHP でシリアライズされたデータの文字列を読み込む
serialized1 = 's:11:"Hello world";'
loaded1 = loads(serialized1)
print(loaded1)
# => Hello world
# Python の文字列型として取得できる

つづいて連想配列の場合はこちら。

serialized2 = 'a:2:{s:1:"a";b:1;s:1:"b";i:345;}'
loaded2 = loads(serialized2)
print(loaded2)  # => {'a': True, 'b': 345}

次はインデックス配列の場合。 PHP ではインデックス配列と連想配列が統一的に扱われるので、インデックス配列の場合でも Python 側では統一的に dict として解釈する仕様になっています。この場合、元のデータがインデックス配列とわかっている場合には dict_to_list 関数を使って list に変換することができます。

from phpserialize import loads, dict_to_list

serialized3 = 'a:3:{i:0;i:3;i:1;i:7;i:2;i:5;}'
loaded3 = loads(serialized3)
print(loaded3)
# => {0: 3, 1: 7, 2: 5}
# 基本的に辞書が返される

loaded3_list = dict_to_list(loaded3)
print(loaded3_list)
# => [3, 7, 5]
# dict_to_list でリストに変換可
# タプルに変換したい場合は同様の関数 dict_to_tuple が使えます

つづいて、 loads とは逆に PHP 形式にシリアライズする関数も見てみましょう。 loads の逆の操作を行う関数として dumps というものが用意されています。

from phpserialize import dumps

print(dumps('Hello world'))  # => 'a:2:{s:1:"a";b:1;s:1:"b";i:345;}'
print(dumps({'a': True, 'b': 345}))  # => 's:11:"Hello world";'

さらにもうひとつだけ見てみましょう。 loads と dumps に似た機能を持つ関数として load 、 dump という 2 つの関数が用意されています。これらは文字列ではなくファイルのようなストリームオブジェクトを扱う関数です。

from phpserialize import load, dump

# ファイル php.txt から PHP でシリアライズされたデータを読み込み
loaded3 = load(open('php.txt'))

# Python データを PHP のシリアライズフォーマットでファイルに書き込み
dump(open('php2.txt', 'w'), loaded3)

以上です。

PHP と Python 間でデータの受け渡しをする場合には JSON 形式などが便利かと思いますが、 PHP でシリアライズされたデータをどうにかして Python で扱いたいという場合にはこちらの phpserialize が有用かと思います。

参考