PEAK XOOPS - serialize()とvar_export()の比較 (2) in englishin japanese

Archive | RSS |
PHP
PHP : serialize()とvar_export()の比較 (2)
Poster : GIJOE on 2008-11-12 04:08:39 (9067 reads)

in englishin japanese
serialize()/unserialize()
var_export()/eval()

A)安全性

この2つのペアを一見して判るのが、後者でeval()を使う怖さです。当たり前ですが、var_export()の出力であることが保証されているテキストでなければ、アンシリアライズしてはいけません。

もっとも、unserialize()についても、ちょっと古いPHPであれば、バッファオーバー脆弱性があったわけで、シリアライズテキストがリクエスト依存、という状況はいずれにせよあり得ないでしょう。

B)速度

結果から書いてしまうと、serialize()/unserialize() の方がだいぶ速いようです。
こんな感じのベンチプログラムで検証してみました。


#!/usr/local/bin/(php-cli binaries)
<?php

function getmicrotime()
{
        list($usec, $sec) = explode(" ",microtime());
        return ((float)$sec + (float)$usec);
}

function var_import( $data ) {
        eval( '$ret='.$data.';' ) ;
        return $ret ;
}

$data = ( big array ) ;

$time_start = getmicrotime();

for( $i = 0 ; $i < $_SERVER['argv'][1] ; $i ++ ) {
        $serialized_data = serialize( $data ) ;
        $restored_data = unserialize( $serialized_data ) ;
        $serialized_data = var_export( $data , true ) ;
        $restored_data = var_import( $serialized_data ) ;
}

$time_end = getmicrotime() ;
echo $time_end - $time_start , "sec. \n" ;
?>

あくまでCLI版での検証ですが、赤は青のだいたい3倍くらいかかってます。PHPバージョン依存も確認してみましたが、PHP4.4.xでも5.2.xでも、同じようなパターンです。

ただ、eval()だけが遅いのかと思いきや、var_export()単独でも、serialize()の3倍かかります。

もちろん、この検証で重要なのは絶対値です。具体的な数字は書けませんが、シリアライズ/アンシリアライズなんてもともと小さな処理です。そこが3倍かかったくらいで、全体の処理にはほとんど影響ないはずです。(もちろん、大量に処理するケースでは避けた方が無難かも知れません)

C)使いやすさ

var_export()の圧勝です。
エンコーディング変換によるトラブルがなくなるだけでなく、シリアライズ形式でデータをいじることも、serialize()によるものより、はるかに楽です。

D)結論

失われてもさほど問題にならないデータや、大量のデータなら serialize()
重要性の高いデータで、さほど量が大きくないなら var_export()

という形で使い分けるのが良い気がします。
unserialize()で復元できなかった時の痛さと言ったら…

E)余談

ここでいきなりXOOPSの話題になって恐縮ですが、拙作picoでは、追加フィールド機能やフォーム機能で、serialize()/unserialize()を使っていました。しかし、この結論から、今後は、var_export()/eval()に変更していきます。

0 comments

Related articles
Printer friendly page Send this story to a friend

Comments list

Login
Username or e-mail:

Password:

Remember Me

Lost Password?

Register now!