AWSの話題を中心に、日々の業務やプログラミングの徒然を綴るエンジニアブログです。

HANDS LAB

HANDS LAB ENGINEERS BLOG

ハンズラボエンジニアブログ

DynamoDB PHP SDKのMarshalerクラスを使った時にはでかい数値に気をつける

Pocket

Pocket

下記のblogで紹介されているように、AWS PHP SDKの 2.7.7 から PHPの型とjsonとDynamoDBの型の相互変換を行うクラス、Marshaler が追加されています。

DynamoDB JSON and Array Marshaling for PHP

この Marshaler クラスを使うと、型変換が行われるため、数値型に大きな値を入れている場合に注意が必要です。

以下に例を示します。

id = 1 のレコードに number = 9223372036854775808 という値が入っているレコードを取り出してみます。

結果

9223372036854775808 という値が取り出せました。

これを Marshaler でPHPの型に戻してみます。
使用するメソッドは、unmarshalItem です。

結果

9.2233720368548E+18 になってしまいました。/(^o^)\ ナンテコッタイ

原因

PHPでの整数の最大値はPHP_INT_MAXで定められており、9223372036854775807 になっています。(64bitの場合)
それを超えた数字を整数に変換しようとすると、指数表記になってしまいます。

参考:PHP>マニュアル>言語リファレンス>型>整数

一方、DynamoDBの方は、下記ドキュメントにて、最大 38 桁の精度とあるように、 99999999999999999999999999999999999999 まで投入できます。

参考:DynamoDB データモデル

この辺りの相互変換は、言語側の精度に依存する形になると思うので、使っている言語側の仕様を確認しておいた方がよさそうです。
たしか、rubyの場合には BigDecimal に変換されたと思います。

参考

Pocket