1

64 ビット サーバーでシリアル化されたオブジェクトを 32 ビット サーバーでシリアル化解除しようとしています。問題をオブジェクト内の整数に分離しました。ここに問題の小さな再現があります。

64 ビット マシンの場合:

$i = serialize('20110510134021'); //i:20110510134021;

32 ビット マシンの場合:

$i = unserialize('i:20110510134021;');

エラーを与える

Notice: unserialize(): Error at offset 0 of 16 bytes

これで、これらのシリアル化方法をクロス システム データ送信に使用すべきではないことがわかりました。ただし、データを別のシステムに移行しようとしているだけで、転送に積極的に使用することはありません。これは 1 回限りのことです。

これは整数オーバーフローが原因である可能性があると思いますが、32ビットサーバーでも次のようなことができます

$i = 20110510134021;
echo $i;

そして、それはうまくいきます。PHP の整数型は double 型などにスケーリングされると思います。しかし、シリアル化を解除するときにそれを行わないのはなぜですか?

これらのオブジェクトのシリアル化を解除するにはどうすればよいですか? できない場合、それらを別のものに変換する方法はありますか? 最後に、PHP 自体で逆シリアル化メソッドを作成した人はいますか? または、プロトコルの詳細はありますか? それを使用して、それらの整数のカスタムケースを作成できます。

ありがとう。

注:元のデータにはアクセスできず、シリアル化された結果のみにアクセスできます。

4

3 に答える 3

2

32 ビット システムでの最大整数は4294967296; $i = 20110510134021;PHP が変数を double に変換するため、動作します。

だから置き換えiますd

$i = unserialize('d:20110510134021;');

このスクリプトを実行すると、実行しているシステムで変数の正しい表現が表示されます (d: 32 ビット システムでは、i: 64 ビット システムでは):

$int = 20110510134021;
var_dump(serialize($int));
于 2011-10-26T15:00:46.357 に答える
1

簡単な解決策は、64 ビットでシリアル化されたデータが 32 ビット マシンでシリアル化されない可能性があることがわかっている場合、シリアル化する前に (double) にキャストすることです。

次に、double として非シリアル化され、整数あたり標準の 4 バイト (32 ビット) よりも多くの整数あたりのビット数が提供されます。

シリアル化を解除したら、その数値を double として扱うだけです。99% のケースで、これは良い解決策です。非常に大きな数の場合、32 ビット マシンの倍精度数の「実数」部分に割り当てられるビット数が十分でない可能性があります。56ビットだと思うので、最大整数はint型の32ビットよりもかなり大きいです。

于 2011-10-26T14:56:15.173 に答える