忍者ブログ
[PR]
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。



2017/08/20 07:23 |
PHP5.3 Services_JSONで数値をデコード
<?php
	require_once('Services/JSON.php');
	
	$data = '{"hoge" : 12345678901234567890}';
	$json = new Services_JSON();
    $decode = $json->decode($data);
    
	var_dump($decode->hoge);
float(1.2345678901235E+19)

値が数値となっているJSONデータをServices_JSONでデコードすると結果が浮動小数となり、元のJSONデータが無くなってしまいます。

仕方ないので無理矢理文字列型でデコードできないのかと思えばできません。
数値をパースしているのはServices/JSON.phpの600行目あたり、if (is_numeric($str))の分岐内です。

処理はどうなっているかというと
if (is_numeric($str)) {
    return ((float)$str == (integer)$str) ? (integer)$str : (float)$str;
}
と見事に割り込む余地が無く、integerに入りきればint型、長い数値は自動的にfloat型になってしまいます。
数値だとしても正確な値がほしいんだよ、という場合は無理矢理継承するかソースを直接編集するしかありません。

Services/JSON.php
	//メソッドひとつ追加
    function setDecodeMode($decodeMode = false){
		if(isset($this->decodeMode) && $this->decodeMode){
			$this->decodeMode = $decodeMode;
		}
	}

	//Services_JSON::decode()の中を一部修正
		if (is_numeric($str)) {
			//デコードモードが指定してあれば
				if($this->decodeMode){
					if($this->decodeMode === SERVICES_JSON_IN_STR){
						return $str;
					}
				}
			// Return float or int, as appropriate
				return ((float)$str == (integer)$str)
				? (integer)$str
				: (float)$str;
		}
setDecodeMode(SERVICES_JSON_IN_STR)を呼べば数値型の場合でも文字列で返ってきます。 
<?php
	require_once('Services/JSON.php');
	
	$data = '{"hoge" : 12345678901234567890}';
	$json = new Services_JSON();
	$json->setDecodeMode(SERVICES_JSON_IN_STR);
    $decode = $json->decode($data);
	
	var_dump($decode->hoge);
実はSERVICES_JSON_IN_STRとかは元々Services_JSON内で別の意味で使用されている定数なので、あまりこういう使い方はするべきではないのですが、まあいいや。
ていうか、いいかげんPearもクラス定数使うべき。

実行すると、
string(20) "12345678901234567890"
となり無事に元の値を復元できました。
この場合元の"hoge"が数値型だったという情報は失われてしまうのですが、型が失われるのと値が失われるのとどちらがいいと言われたら前者ではないかと。


// Lookie-loo, it's a number
// This would work on its own, but I'm trying to be
// good about returning integers where appropriate:

とか書いてあるので中の人も微妙って思ってるのかね?
PR


2011/07/16 01:22 | Comments(0) | TrackBack(0) | PHP

トラックバック

トラックバックURL:

コメント

コメントを投稿する






Vodafone絵文字 i-mode絵文字 Ezweb絵文字 (絵文字)



<<今週の実績 2011/07/17 | HOME | PHP5.3 PHPからMongoDBを使う>>
忍者ブログ[PR]