フロントエンドのfrontend.htmlの5行目で、外部のJavaScriptファイルfrontend.jsを読み込みます。JavaScriptを外部ファイル化することで、HTMLファイルのヘッダー部(<HEAD>〜</HEAD>)を簡素化できます。
入力フォーム(16〜38行目)では、name属性でform1を指定しておきます(16行目)。同様に各テキストボックスやテキストエリアにもname属性で固有の識別子を割り当てておきます(21、27、32行目)。固有の識別子を割り当てることで、テキストエリアに入力された値の操作などを、容易にJavaScriptから行えるようになります。
郵便番号テキストボックスではキー入力(具体的には、押下したキーが解放された瞬間)をトリガーに、JavaScriptで定義したsetZip_code()関数を実行するよう、イベント属性「onkeyup」にsetZip_code()関数を指定します。その際、「this.value」で得られるテキストボックスへの入力値をsetZip_code()の引数として渡します(21行目)。なおキー入力がトリガーになるため、setZip_code()の実行頻度は高くなっています。
バックエンドのメッセージを表示するメッセージテキストエリアは、表示のみのため、readonly属性を付加します(32行目)。
5 <script type="text/javascript" src="frontend.js"></script> |
Ajaxのフロントエンド処理を担うfrontend.jsは、大まかに以下のような処理で構成されています。
JavaScriptでHTTP通信を行うためのXMLHttpRequestオブジェクトを生成する(2行目)(ブラウザ別に生成方法を用意(47〜74行目))
↓
バックエンドへのリクエストURL「backend.php?zip_code=郵便番号テキストボックスに入力された値」を作成(8行目)
↓
XMLHttpRequestオブジェクトのopen()メソッドで、HTTPメソッド(GET)/リクエストURL/非同期の使用(true)を設定する(9行目)。
↓
バックエンドからデータを受信する際にコールバック関数が実行されるよう、XMLHttpRequestオブジェクトのonreadystatechangeプロパティにコールバック関数を設定する。レスポンスデータの処理はコールバック関数で行う(12行目)
↓
XMLHttpRequestオブジェクトのsend()メソッドでサーバへリクエストを送信する(15行目)
1 //XMLHttpRequestオブジェクト生成 |
さらに、バックエンドからデータを受信したときに呼び出されるコールバック関数「handleHttpEvent」では、以下のような処理が行われます。
XMLHttpRequestオブジェクトのreadyStateプロパティを使って、受信データが読み込み済み(4)か確認し、同時にstatusプロパティでHTTPレスポンスコードが正常(200)であることを確認する。正常性を確認できたとき、この後の処理を行う(21行目)
↓
XMLHttpRequestオブジェクトのresponseXMLプロパティで、サーバからのレスポンスをXMLDocumentオブジェクトとして取得(24行目)
↓
取得したXMLDocumentオブジェクトからgetElementsByTagName("要素名")を使ってXMLの各要素を取り出す。まず「<stat>〜</stat>」から値を取り出し、「ok」ならば住所データと該当件数を取り出し、各テキストボックス・エリアに当てはめる(29〜35行目)。「na」ならメッセージだけを取り出してメッセージテキストエリアに当てはめ、住所テキストボックスの内容はクリアする(36〜41行目)
19 function handleHttpEvent(){ |
以上がバックエンドとフロントエンドの処理内容になります。
なお、作成過程でJavaScriptやバックエンドを修正したにもかかわらず、ブラウザの表示結果に反映されない場合があります。AjaxもHTTPリクエストを使用する以上、非同期で取得するデータにもブラウザのキャッシュが使用されます。特に、GETメソッドを使用し、しかもURLに変化がない場合は、キャッシュヒット率が高くなります。
また、データベースのデータ、HTMLやPHPファイルのエンコード、バックエンドから送出されるXML、すべての文字コードをUTF-8に統一しています。文字化けが発生するようなら、php.iniに以下の2行を追加しておきます。php.iniのインストール先は第1回「MySQL+Apache+PHPをインストールしよう」を参考にしてください。
[mbstring] |
ブラウザからの動作確認で、バックエンドへ直接アクセスしXMLを表示しようとした際、画面4のように「XMLパースエラー」が表示され、正常な動作が確認できない場合があります。これは、エラー内容のとおり「」が先頭になく、スペースや改行などの不正文字が挿入している場合に発生します。
これを防ぐにはPHPファイルを確認し、特に、<?php ...?>前後に無駄な改行や空白がないようにします。また直接XMLを出力するPHPとは別に、require_onceなどで外部ファイルを読み込んでいる場合は、そのPHPファイルに無駄な改行や空白がないか確認します。
←ここにスペースや改行が挿入されていないか確認する |
sample6で作成したAjaxによる住所データ入力支援機能を、前回までに作成した「簡易オンラインストア」に組み込みます。
前回作成したsample5に先ほどのsample6を統合しますが、その際、DTO・DAOパターンを踏襲するよう改修を加えます。
Ajaxのバックエンドを担うbackend.phpでは、MySQL接続・切断・データ抽出といったDB操作を、新たに作成するZip_addressDao.phpに分離します。それに伴いZip_address.phpを作成し、DTOに利用します。frontend.jsはほぼそのまま使用しますが、メッセージテキストエリアがないため、関連する処理を削除します。frontend.jsを読み込む1行を、ユーザーに住所入力を促すconfirm.phpに追加します。
PHPファイルの改修は以上です。最後に、sample6と同様に、郵便番号・住所データをMySQLに用意します。
こちらからサンプルアーカイブ「sample7.tgz」をダウンロードし、Apache HTTPDのドキュメントルート(注)など、PHPが動作するディレクトリに展開し、作業ディレクトリを移動します。その後サンプルに含まれる「sample_db7.sql」を利用し、データベース「sample_db7」を準備します。
注:ソースからデフォルトインストールした場合は/usr/local/apache2/htdocs、FedoraやRed hatなどRPMインストールした場合は/var/www/htmlなど
サンプル「sample7」をドキュメントルートに展開し、作業ディレクトリを移動する。下のドキュメントルートはFedoraやRed hatなどRPMインストールした場合の例。適宜変更する |
インストール後の確認作業として、まずmenu.phpを表示させ、商品を購入します。その後表示されるconfirm.phpの「〒番号」に数字を入力し、住所欄に自動的にデータが挿入されることを確認します。なお、最初の入力では、MySQLサーバ接続処理のために多少反応が遅れる場合があります。その際は少し入力速度を抑え、反応を確かめるようにします。
以上、Ajaxを取り入れ、PHPをバックエンドに使用する方法を紹介しました。
セッションステートレスなHTTPでは、画面の切り替わりに伴い入力データを引き継がせる処理が煩雑になるため、ネイティブアプリケーションのような入力支援機能を取り入れるには、大変な苦労が伴います。しかしこのようにAjaxを使用することで、画面遷移に関係なく、ユーザーインターフェイスを充実させることができます。
ただし、その分バックエンドに掛かる負荷は高くなります。今回のサンプルのように、キー入力が発生するたびにデータベースへの問い合わせが発生するようなケースでは、別途データベースとの接続を最適化させる手段を検討するようにしてください。(次回に続く)
【参考】
KJ(著)、田中 ナルミ(著)
「PHPによるWebアプリケーションスーパーサンプル 活用編」
ソフトバンククリエイティブ
Copyright © ITmedia, Inc. All Rights Reserved.