Do You PHP?    
Search Engine Optimization  php5 powerd  Valid XHTML 1.0!  Valid CSS!  このサイトのはてなブックマーク数 



last updated
2006/10/31

counter hits
since 1999/11/06


PHPでJSON

memo[2006/10/31] php-jsonはPHPのソースツリーに取り込まれ、PHP5.2.0からデフォルトで組み込まれるようになります。

Web2.0の盛り上がりに連れてますます盛り上がっているAJAXですが、非同期通信でやりとりされるデータフォーマットとしては、

があります。以前AJAXのサンプルを作ったときはデータはXML形式でしたが、(今更ですが)今回はJSONを色々試してみます。

PHPでJSONを扱う場合、現時点で以下の二つのモジュールがよく知られています。いずれも配列・連想配列などをJSON形式へ変換する機能を提供しています。

今回はこれらのインストール手順のまとめと簡単な動作サンプルの作成、前回の郵便番号検索をそれぞれのJSONに焼き直したサンプルの作成を行いました。

PEAR::Services_JSONのインストールと簡単なサンプル

PEAR::Services_JSONは(当然ですが)PHPによる実装です。PEPrのページによると、2005/01/27に提案され、2005/10/13からの投票で9票獲得しています(条件付き5票)ので、そのうち何らかの形(PEAR::HTML_AJAXとか)でPEARに組み込まれると思われます。

その他情報源としては、以下のページがあります。

インストール手順ですが、まだpearコマンドで管理できないため、アーカイブをダウンロードし、任意のディレクトリに展開するだけになります。

●PEAR::Service_JSONのインストール
# wget http://mike.teczno.com/JSON.tar.gz
# tar zxf JSON.tar.gz
# 

展開後、JSON.phpが作成されますので、適宜require/includeして使用します。

簡単なサンプルはJSON.phpにも記載されていますが、Services_JSONインスタンスを生成し、配列をencodeメソッドに渡すとJSON形式でデータが返されます。基本的な使い方はこれだけです。どのような配列を渡すとJSONデータがどうなるか、色々試してみてください。その他メソッドについてはService_JSONのドキュメントを参照してください。

なお、マルチバイト文字を扱う場合、エンコーディングをUTF-8に変換してServices_JSONクラスに渡す必要があります。

●json_sample.php
  
<?php
require_once('JSON.php');
?>
<pre>
<?php
    /**
     * マルチバイト文字を扱うには、intern_encoding=utf-8もしくは
     * utf-8にエンコーディング変換する必要がある
     */
    $string = 'ほげほげ';
    $string = mb_convert_encoding($string, 'utf-8', mb_internal_encoding());

    $json = new Services_JSON();
    $obj = array(
       'id'   => array('foo', 'bar', array('aa' => 'bb')),
       'hoge' => $string,
       'no'   => 123 ,
       'bo'   => true
    );

    $js = $json->encode($obj);
    echo $js;
    echo '<hr>';

    $decoded = $json->decode($js);
    var_dump($decoded);
    echo '<hr>';

    $hoge = $decoded->hoge;
    echo mb_convert_encoding($hoge, mb_internal_encoding(), 'utf-8');
    echo '<hr>';
    echo mb_internal_encoding() . '<hr>';
    echo 'a=' . mb_convert_encoding($hoge, mb_internal_encoding(), 'utf-8');
?>
</pre>
<hr>
<?php
    show_source($_SERVER['SCRIPT_FILENAME']);
?>

php-jsonのインストールと簡単なサンプル

php-jsonはPHP拡張モジュールとして提供されています。PECLのCVSに登録されているようなので、こちらもそのうちアナウンスがあるかも知れません。

その他情報源としては、以下のページがあります。

インストール手順ですが、まずお決まりのコマンドを使って行います。

●php-jsonのインストール
# wget http://www.aurore.net/projects/php-json/php-json-ext-1.1.1.tar.bz2
# tar jxf php-json-ext-1.1.1.tar.bz2 -C /usr/local/src/
# cd /usr/local/src/php-json-ext-1.1.1/
# ./configure
# make
# make install
# 

インストール実行後、所定のディレクトリに拡張モジュールがインストールされていることを確認してください。以下は、CentOS 4.2に付属しているrpm版PHPの場合です。

●php-jsonモジュールの確認
# ll /usr/lib/php4/json.so
-rwxr-xr-x  1 root root 77917 Feb 19 12:21 /usr/lib/php4/json.so
# 

インストールが終わったら、拡張モジュールをロードするようphp.iniに追記します。

●php.iniの編集
            :
extension=json.so
            :

最後にApacheを再起動し、phpinfoの画面で正しくロードされている事を確認します。

phpinfo画面

なお、この拡張モジュールを使用することで以下の二つの関数が追加されます。

  • json_decode
  • json_encode

サンプルですが、php-jsonのページにあります。使い方を見てみると、PEAR::Services_JSONとほとんど同じで配列をjson_encode関数に渡すだけでJSON形式でデータが返されます。また、マルチバイト文字を扱う場合もPEAR::Services_JSONと同様、エンコーディングをUTF-8に変換する必要があります。

●php_json_sample.php
  
<?php
echo '<pre>';
$val = array("abc" => 12,
             "foo" => "bar",
             "bool0" => false,
             "bool1" => true,
             "arr" => array(1, 2, 3, null, 5),
             "float" => 1.2345,
             "hoge" => mb_convert_encoding('ほげほげ', 'utf-8', mb_internal_encoding())
            );
$output = json_encode($val);
echo 'encoded=' . $output . '<br>';

$decoded = json_decode($output);
var_dump($decoded);
echo mb_convert_encoding($decoded->hoge, mb_internal_encoding(), 'utf-8');
?>
</pre>
<hr>
<?php
    show_source($_SERVER['SCRIPT_FILENAME']);
?>

郵便番号検索のJSON化

前回作成した郵便番号検索のサンプルで、検索結果データを送出する側を以下のように変更しました。実際の動作はEXPERIENCEのページで確認できます。基本的な検索ロジックは変わっていませんが、最後のデータ出力の部分でJSON形式に変換し出力するようにしています。

ついでに、返されるJSONデータも表示するようにしてみましたので、併せて確認してみてください。

  
<?php
define('OUTPUT_ENCODING', 'utf-8');
    error_reporting(E_ALL);
    mb_http_output(OUTPUT_ENCODING);
?>
<?php
function convert($str) {
    return htmlspecialchars(
            (strtolower(OUTPUT_ENCODING) == 'euc-jp')
            ? $str
            : mb_convert_encoding($str, OUTPUT_ENCODING, 'auto'));
}
?>
<?php
    $zip = null;
    $data = array();
    if (isset($_GET['zip']) && ereg('[0-9]+', $_GET['zip'])) {
        $zip = $_GET['zip'];

        require_once("DB.php");
        $dsn = array (
            'phptype'  => "sqlite",
            'database' => "./zipdb"
        );
        $db = DB::connect($dsn);
        if (DB::isError($db)) {
            die($db->getMessage());
        }

        $db->setFetchMode(DB_FETCHMODE_ASSOC);
        $db->autoCommit(false);

        $stmt = $db->prepare("SELECT * FROM zip where zip like ? ORDER BY zip ");
        if (DB::isError($stmt)){
            die($stmt->getMessage());
        }

        $rs = $db->execute($stmt, $zip . '%');
        if (DB::isError($rs)){
            die($rs->getMessage());
        }

        $ziplist = array();
        while ($row =& $rs->fetchRow()) {
            $row['adr1'] = convert($row['adr1']);
            $row['adr2'] = convert($row['adr2']);
            $row['adr3'] = convert($row['adr3']);
            $ziplist[] = $row;
        }
        $data['ziplist'] = $ziplist;

        $rs->free();
        $db->disconnect();
    }

    if (isset($_GET['json']) && $_GET['json'] == 'pear-json') {
        include_once('json/JSON.php');
        $json = new Services_JSON();
        $data['json'] = 'pear-json';
        echo $json->encode($data);
    }
    else {
        $data['json'] = 'php-json';
        echo json_encode($data);
    }
?>

まとめ

JSONネタを2つまとめてみました。2005年にはこのようなモジュール・ライブラリが考案されていたということで、今後もっと発展していきそうです。ただ、AJAX自体ある意味「サーバとクライアントが一体化」した技術なので、その辺がより簡単に実装できる仕組みが必須と考えています(でないと、開発者は大変です)。その一つがPEAR::HTML_AJAXのようなPEAR純正のライブラリです。2006/02/19現在まだα版のため、色々と制約はありますがかなり注目しています。これについては(時間があれば)今後取り上げたいと思います。

その他、Echo2のようなフレームワークやEchoStudio 2のようなEclipseプラグインも出てきていますし、Sun Microsystems、IBM、Microsoftも開発ツールキットの提供に注力していくようです。国内では、HOWS社が開発ツールであるAjax Builderを提供し始めています。この辺のツール群は急ピッチで整備されていくことと思います。

あとは「AJAXを使うことでユーザーに大きなメリットをもたらす何か」を考えれば。。。といっても、これだけはライブラリやツールじゃ無理ですね(^-^;



About This Site |  Privacy Policy |  Contact
Copyright © 1999 - 2006 by Hideyuki SHIMOOKA all rights reserved.