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



last updated
2005/06/04

counter hits
since 1999/11/06


Ajax(エイジャックス)とPHPの連携

最近Hotな(死語?)話題としてAjax(「Asynchronous JavaScript + XML」の略:エイジャックス)があります。

Ajaxを使用した有名なアプリケーションとしては、Google Gmail、Google Mapsが知られていますが、サンプルを紹介している日本語サイトとしては以下のものがあります。

これらのサイトのアプリケーションを見てもらうと分かると思いますが、どれも従来のWebアプリケーションでは考えられないような動きをします。特に「ページを更新しないでデータを更新する」といった動作はAjaxならではのメリットと思います。いや、Google Mapsを初めてみたときかなりのショックでした。冗談抜きで。。。

Ajax自体は既存の枯れた技術であるXMLやJavaScript、CSS、HTMLなどを組み合わせたWebアプリケーションのアーキテクチャと位置付けられています。以下の図は従来型WebアプリケーションとAjaxのモデルの比較を表しています(Ajax: A New Approach to Web Applicationsより)。

従来型WebアプリケーションとAjaxのモデルの比較

この図を見るとクライアント側の「Ajax engine」が大きく異なっていますがその他はほとんど変わっていません。これは、例えばFlashを使ったページでFlashとやりとりを行う場合のアーキテクチャをイメージするとかなり近いものがあるのではないかと思います。つまりこのページでは「Ajax(エイジャックス)とPHPの連携」とうたっていていますが、「Ajax」というものとPHPが直接結びつくわけではなく、サーバ側で動作するPHPにとっては従来のWebアプリケーションと同じです。最終的な出力がHTML/XHTML/XML/HDMLなのか、CSVやタブ区切りデータ、その他テキスト/バイナリデータなのか、Ajax用のデータ(XMLやテキスト)なのかの違いしかありません。なので、Ajaxを使ったWebアプリケーションでは極端な話、クライアント側のHTML(javascript)で受け取るべきデータフォーマットに合わせたデータの出力を行えば良いことになります。

かなり前置きが長くなりましたが、要は「Ajaxだからといって、PHP側ではCVSの出力と大差ない」ということです。

ということで、ありがちですがAjax を使った郵便番号検索を参考(というか、PHPに焼き直しただけ。。。)にざっくりサンプルを作ってみました。ただし、私の地元「広島県」限定ですが。。。(^-^;

構成はPHP5.0.x+PEAR::DB+SQLiteというシンプルなものにしました。クライアント・サーバ間のデータはXMLとしました。実際の動作はEXPERIENCEのページで確認できます。また、実際のデータ出力で使用しているPHPは以下の通りです。


<?php
    /**
     * PHP5のPEAR::DBでE_STRICTを指定するとかなりのメッセージが表示
     * されるのでそれを抑制する
     */
    error_reporting(E_ALL);

    /**
     * コードはeuc-jpだが、XMLをutf-8で出力するするため(手抜き。。。)
     */
    mb_http_output('utf-8');

    header('Content-type: text/xml; charset=utf-8');
    echo '<?xml version="1.0"?><ziplist>';

    /**
     * パラメータのチェック
     */
    $zip = null;
    if (isset($_GET['zip']) && ereg('[0-9]+', $_GET['zip'])) {
        $zip = $_GET['zip'];

        /**
         * 郵便番号DBに接続
         */
        require_once("DB.php");
        $dsn = array (
            'phptype'  => "sqlite",
            'database' => "/tmp/zipdb"
        );
        $db = DB::connect($dsn);
        if (DB::isError($db)) {
            die($db->getMessage());
        }

        /**
         * フェッチした結果セットをstdClassのオブジェクトとして返す
         */
        $db->setFetchMode(DB_FETCHMODE_OBJECT, 'stdClass');
        $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());
        }

        /**
         * 結果セットからXMLを作成
         */
        while ($row =& $rs->fetchRow()) {
            printf('<zip><pref>%s</pref><city>%s</city><ville>%s</ville></zip>',
                $row->adr1, $row->adr2, $row->adr3);
        }

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

    echo '</ziplist>';
?>

PHP側の処理自体は「DBからデータを取得しXMLとして出力する」といったごく普通のWebアプリケーションだということが分かると思います。他のサイトのサンプルについても、サーバ側の処理は「何らかのフォーマットでデータを返す」ものや「送信されたデータを元に何らかのトランザクション処理を行う」といったみなさんもイヤというほどやってきた処理と何ら変わりありません。

その反面、画面構成や処理内容によってはクライアント側(特にjavascript)が非常に複雑になります。そもそもjavascript自体の動作をブラウザ側で変更できますのでそれへの対応、また様々なブラウザへの対応も必要になってきます。また、今回のサンプルではkeyupイベントによりサーバへリクエストを送信する仕組みになっているため、頻繁にHTTPリクエストやDBアクセスが発生します。当然、別のタイミングでHTTPリクエストを送信することも可能ですが、基本的には従来型Webアプリケーションよりも大量のHTTPリクエストやDBアクセスが発生すると思われます。これはサーバ負荷やネットワーク負荷に直結しますので、HTTPリクエストを送信するタイミングやAjax自体使いどころ、ひょっとするとサーバ構成も今後の課題になりそうです。

その他としては、画面遷移がなくなる分、アクセスログの分析が困難になってきそうです(おそらくFlashを使った場合もそうでしょうね)。ECサイトなどインターネット上でサービスを行っている場合、ログの分析結果はかなり重要なものになりますが、それを補う方法を何らか考えておく必要がありそうです。

といっても、またまた面白い技術(というかネタ)が出てきましたね。。。



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