twitterの投稿IDをjson_decode()できない
PHPのjson_decode()が大きい数値をfloat()に変換してしまう現象があり、twitterのIDをdecodeできなくて困った。
floatに変換しない方法は無いものだろうか?
http://www.php.net/manual/ja/function.json-decode.php を見たところ、JSON_BIGINT_AS_STRINGというオプションを指定すると、Stringとして扱ってくれるようなんだけど、その機能は開発中のPHPにしか入っていない。
それじゃ、開発中のjson_decode()を使おう
ということで、どうしてもjson_decode()の新しいバージョンが使いたかったので、
PHPの開発中のソースをダウンロードして、新しいバージョンのjson.soをコンパイルしたときのメモでござる。
ここで、ダウンロードするソースを確認。
http://svn.php.net/viewvc/php/php-src/trunk/ext/json/
svnを使ってソースの取得
$ svn co http://svn.php.net/repository/php/php-src/trunk/ext/json php-trunk-20110128-ext-json
取得したソースのディレクトリへ移動して
$ cd php-trunk-20110128-ext-json
さて、extensionのコンパイルでござる。
phpizeをして、configureの作成をします。
$ phpize Configuring for: PHP Api Version: 20041225 Zend Module Api No: 20060613 Zend Extension Api No: 220060519
configureができるので、実行するよ。一緒のphp-configの場所を指定するなり。
$ ./configure --with-php-config=/usr/bin/php-config
終わったら、make をしてみて既存のjson.soと置き換えてみる。
CentOSの場合、/usr/lib/php/modules/json.so に合ったので、そこと置き換えました。
テスト用のPHPファイルを作って、
<?php echo "php version:".phpversion()."\n"; echo "============================\n"; $json = '{"bignumber":100999999999999999999}'; var_dump( json_decode($json)); var_dump( json_decode($json,false,512,JSON_BIGINT_AS_STRING));
実行してみると、
$ php x.php PHP Warning: PHP Startup: Unable to load dynamic library '/usr/lib/php/modules/json.so' - /usr/lib/php/modules/json.so: undefined symbol: Z_DELREF_P in Unknown on line 0
むむ、こまった。
Z_DELREF_P()って何だ?って思って、ググって見ると、PHP5.2.2からPHP5.2.3になるときにリファレンスカウンタ関係のAPIが変わったらしい。*1
とりあえず、それっぽいAPIに置き換えてみる。
JSON_parser.cにある、Z_DELREF_P()をZVAL_DELREF()に変更して、再度コンパイルをしよう。
さて、再度実行。
$ php x.php PHP Warning: PHP Startup: Unable to load dynamic library '/usr/lib/php/modules/json.so' - /usr/lib/php/modules/json.so: undefined symbol: zend_parse_parameters_none in Unknown on line 0
こんどは何だ? zend_parse_parameters_none() はjson_last_error()で使っているのかな。
あんまりつかわなそうな関数なので、コメントアウトしてしまいました。
/* {{{ proto int json_last_error() Returns the error code of the last json_decode(). */ static PHP_FUNCTION(json_last_error) { // if (zend_parse_parameters_none() == FAILURE) { return; // } RETURN_LONG(JSON_G(error_code)); } /* }}} */
さて、コンパイルしなおして、実行してみよう。
$ php x.php php version:5.2.4 ============================ object(stdClass)#1 (1) { ["bignumber"]=> float(1.01E+20) } object(stdClass)#1 (1) { ["bignumber"]=> string(21) "100999999999999999999" }
ふう、できた。よかったよかった。
あれ?
twitterからidじゃなくて、id_strつかってねって書いてある。泣きたい。><
http://groups.google.com/group/twitter-development-talk/browse_thread/thread/6a16efa375532182?pli=1