連載
» 2007年08月24日 00時00分 公開

今から始める MySQL入門(10):AjaxのバックエンドにPHP+MySQL (2/3)

[鶴長鎮一,@IT]

サンプルファイルで理解するAjaxの動作(2)

 sample6で使用するファイルは下記のとおりで、フロントエンド部とバックエンド部で構成されています。フロントエンドはHTMLとJavaScriptで作成し、バックエンドはPHPとMySQLで作成します。

 なお本サンプルでは、前回までに紹介したDTO・DAOパターンは使用していません。簡素化のため、データベースアクセスに関連する操作は1つのPHPファイルに集約しています。

sample6
┣━ backend.php       バックエンド用PHP
┣━ frontend.html     フロントエンドHTML
┣━ frontend.js       フロントエンドに取り込まれるJavaScript
┗━ sample_db6.sql    データベースダンプファイル

JavaScriptとXMLで連携

 フロントエンドでは、複雑化したJavaScriptを外部ファイルとしてHTMLファイルから読み込むようにしています。郵便番号テキストボックスへの入力をトリガーに、JavaScriptでURL「backend.php?zip_code=郵便番号」を作成し、サーバへの問い合わせを実行します。

 問い合わせを受けたバックエンドでは、郵便番号を前方一致で検索し、該当があれば住所データと該当件数、それにステータス「ok」を付加したものをXMLで出力し、フロントエンドに送り返します。該当するものがなければ「該当なし」というメッセージに、ステータス「ng」を付加したものをXMLでフロントエンドに送り返します。

 ここでは前方一致検索を用いているため、最初の1文字だけで検索を実行できます。そのため該当データも複数件に及ぶため、フロントエンドには該当件数と最初1件目の住所データだけを送り返します。

 バックエンドからの返信を受けたフロントエンドは、XMLを解析し、ステータス/住所データ/バックエンドからのメッセージを取り出し、各テキストボックスやテキストエリアにデータを当てはめます。

図1 サンプルの基本動作 図1 サンプルの基本動作

バックエンド(backend.php)の処理

 バックエンドでは、受け取った郵便番号を基に、zip_addressテーブルに対し「SELECT * FROM zip_address WHERE zip like '$zip_code%'」のような前方一致検索を実行します(12行目)。実行結果から該当件数を拾い出し(13行目)、該当があれば最初の1件だけを抜き出します。抜き出したデータは、この後定義するsendOk()関数を使ってXMLに整形します(14〜16行目)。

 該当するものがない場合は、この後定義するsendNa()関数を使ってXML出力を行います(17〜19行目)。backend.phpではDAOパターンを踏襲していないため、MySQLサーバ接続(4〜8行目)や切断(24、25行目)の処理を直接盛り込む必要があります。

 3 //MySQLサーバへ接続
 4 $mysqli = new mysqli("localhost", "php", "password", "sample_db6");
 5 if(mysqli_connect_errno()){
 6   sendNa("MySQLサーバ接続に失敗しました\n理由:" . mysqli_connect_error());
 7   exit();
 8 }
 9
10 $mysqli->query("SET NAMES utf8");
11 $zip_code = $mysqli->real_escape_string($_GET["zip_code"]);
12 if($result = $mysqli->query("SELECT * FROM zip_address WHERE zip like '$zip_code%'")){
13   $num = $result->num_rows;
14   if($num != 0){
15     $row = $result->fetch_array(MYSQLI_ASSOC); //最初の1件だけ取得
16     sendOk($row["address"],$num);
17   }else{
18     sendNa("該当なし");
19   }
20 }else{
21   sendNa("クエリ実行エラー");
22 }
23
24 is_null($result) or $result->close();
25 is_null($mysqli) or $mysqli->close();
      リスト1-1 backend.php

 フロントエンドに該当住所データを送り返す際には、ユーザー定義関数「sendOk()」を使用します。sendOk()は住所と該当件数を引数に、okステータスとともに引数の値をXMLの要素に変換し、出力します。

27 function sendOk($address,$num){
28   $address = htmlspecialchars($address,ENT_QUOTES);
29   header("Content-type:text/xml;charset=utf-8");
30 echo <<<EOS
31 <?xml version="1.0" encoding="UTF-8" ?>
32 <zipinfo>
33 <stat>ok</stat>
34 <mess>$num 件該当あり</mess>
35 <address>$address</address>
36 </zipinfo>
37 EOS;
38 }
      リスト1-2 backend.php

 フロントエンドに該当データがないことを通知する際やデータベース処理にエラーが発生した際には、ユーザー定義関数「sendNa()」を使って、naステータスとともに引数で渡されたメッセージ内容をXMLの要素に変換し、出力します。

40 function sendNa($mess){
41   $mess = htmlspecialchars($mess,ENT_QUOTES);
42   header("Content-type:text/xml;charset=utf-8");
43   echo <<<EOS
44 <?xml version="1.0" encoding="UTF-8" ?>
45 <zipinfo>
46 <stat>na</stat>
47 <mess>$mess</mess>
48 </zipinfo>
49 EOS;
50 }
51
52 ?>
      リスト1-3 backend.php

 ブラウザのアドレス欄に「http://HTTPDサーバ/sample6/backend.php?zip_code=郵便番号」のようなURLを入力することで、バックエンドだけで動作を確認することができます。ここで表示されるXMLおよび各要素を確認しておきます。

画面2 該当データがある場合のXML 画面2 該当データがある場合のXML
画面3 該当データがない場合のXML 画面3 該当データがない場合のXML

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。