レベル: 中級 Thomas Myer, Principal, Triple Dog Dare Media
2009年 03月 03日 軽量な JavaScript フレームワーク、jQuery を使って PHP ページに Ajax (Asynchronous JavaScript + XML) 機能を追加する方法を学んでください。
皆さんが大半の PHP 開発者と同じだとしたら、きっと昔からのやり方で技術を学んだことでしょう。つまり、単純な PHP ページを定義して作成する方法、単純な PHP ページを単純な MySQL テーブルに接続する方法を学んだら、それで学習はおしまいです。その後はスキル・レベルを上げるにつれ、経験したことのない複雑な PHP 機能を作成する方法や、MySQL でテーブルを結合して他の高度なタスクを実行する方法を実地で経験していくということです。
経験を積むなかで、皆さんは Web アプリケーションに命を吹き込む多くのクライアント・サイドのスキルを身に付けたことと思います。XHTML や CSS、あるいは JavaScript プログラミングについては、多少の知識があることでしょう。普段行っているプロジェクトの種類によっては、Web アプリケーションに Web 2.0 の感覚、いわゆる「デスクトップ」の感覚を与えるために Ajax に取り組む機会もあったかもしれません。皆さんが初めて経験した Ajax での作業が、私が経験したようなものだったとしたら、手作業で関数を作成したり、Ajax で駆動するページを作成するプロセスに四苦八苦したりと、大変な作業だったはずです。
 |
よく使われる頭字語
- CSS: Cascading Style Sheet
- HTML: Hypertext Markup Language
- XHTML: Extensible Hypertext Markup Language
- XML: Extensible Markup Language
|
|
一部の人々にとって、Ajax は未だに不可解なものです。Ajax はいわゆる Web 開発/双方向性の「天才」や「反逆児」が成せる業だと思っている人々には、Ajax に取り組むだけの時間も、忍耐力も、スキルもありませんでした。これは残念なことでもあります。なぜなら、顧客の多くが Ajax スタイルの機能を追加して、Web アプリケーションを簡単に操作できるようにしたいと思っているからです。もし皆さんがそのような PHP 開発者の一人であったとしたら、恐れることは決してありません。この記事を読み終わる頃には、正真正銘の Ajax のプロになれるほどに Ajax を十分に理解できているはずです。
この記事では、jQuery を使用して、あらゆる PHP Web アプリケーションに簡単に Ajax 機能を追加する方法を説明します。そのために、まず PHP と MySQL を使って名前と電話番号が含まれる電話帳という単純な Web アプリケーションを構築します。このアプリケーションにはご期待通りの標準的なすべての機能を持たせます。といっても、それは名前または電話番号が含まれる MySQL テーブルを検索する機能だけです。次に、jQuery をアプリケーションに追加して、名前と電話番号を入力すると同時に検索できるようにします。この作業を完了した暁には、jQuery の基本だけでなく、Ajax についてもかなり十分な基礎的知識が身に付いているはずです。
Ajax とは何か
Ajax をわかりやすく説明する最良の方法として、皆さんが理解しているものと比較して説明します。ほとんどの Web ページとアプリケーションは同期モードで動作します。リンクやフォームの Submit ボタンをクリックすると、リクエストがサーバーに送信され、サーバーがそのリクエストを処理してレスポンスを返します。このモデルを要約するのに最もふさわしい表現は、「クリック、待機、表示」です。このひたすら繰り返される「クリック、待機、表示」のサイクルは、皆さんにはあまりにもおなじみのものです。つまり、ページに定期的に更新される情報を表示する必要があるとしたら、ある種の自動更新機能をしのばせるか、ユーザーにページを更新させたりして、リンクをクリックさせてページを更新するしか方法はなかったということです。
この事態を一変させるのが、Ajax です。Ajax の頭文字、「A」は非同期 (Asynchronous) を表します。Ajax ではページをプログラミング言語で作成した上で、そのページの個々のパーツをデータベースやその他のバックエンドのサーバー・プロセスからの情報で更新することができます。一例として、商品を表示する e-コマース・サイトがあるとします。それぞれの商品のページにはいつも通りの項目として、商品のタイトル、宣伝文句、サムネール写真、そして在庫数が記載されます。
例えば、サイトの訪問者に常に最新の在庫数を表示したいとします。その場合には、訪問者に表示するページとは別に、在庫数を問い合わせる MySQL クエリーを含んだ PHP ページを用意し、そのページを実行する Ajax 関数を追加します。この Ajax 関数によって得られた情報を、ユーザーからの入力や「クリック、待機、表示」パターンが持つ同期的性質のイベントとも無関係に、訪問者が表示しているページに設定することになります。
Ajax の「j」は JavaScript を表します。そしてこれが、すべての振る舞いの原動力となりますが、このことは幸運であるとともに災いでもあります。幸運な部分は、JavaScript は一貫してクライアント・サイドのコードであることから、移植してもサーバーに影響を与えることがないという点です。一方、多くの PHP 開発者にとって災いとなるのは、JavaScript は慣れ親しんだ環境とは異なることです。そこで登場するのが、jQuery のようなツールとフレームワークです。これらのツールやフレームワークは、PHP と Ajax とのインターフェースを大幅に単純化することによって、コードを完成させるまでの時間を短縮させてくれます。
Ajax の残る「+」と「x」は何を意味するかと言うと、この 2 つは「and XML」の略ですが、XML の部分はまったくの真実であるとは限りません。多くの Ajax アプリケーションは XML コードがなくても十分に機能するからです。これらのアプリケーションは HTML、さらにはプレーンテキストをやり取りするだけで機能します。おそらく x は、「XMLHttpRequest」を表すと定義したほうが適切でしょう。Ajax ではこのオブジェクトを使ってバックグラウンドでデータを取得することで、既存のページの表示や振る舞いには影響が及ばされないからです。
jQuery とは何か
jQuery は John Resig によって作成され、2006年の初めに Internet にリリースされた軽量の JavaScript ライブラリーです。jQuery は無料のオープンソース・ソフトウェアで、MIT (Massachusetts Institute of Technology) と GNU General Public License 双方の下で使用が許諾されます。jQuery はその単純さとわかりやすさにより、開発の世界で多くのファンを獲得しています。
jQuery の人気の理由は、JavaScript を単純化した使いやすいライブラリーを提供しているところにあり、誰しもが (もちろん、生粋のバックエンド・プログラマーでさえも) 作業に骨を折ることなく素晴らしい効果を作成することができます。このライブラリーを使えば DOM (Document Object Model) 要素の選択、CSS の変更と操作、要素の動画化を行えるだけでなく、Ajax と連動することもできます。そしてこのすべての機能を、jQuery サイト (「参考文献」を参照) からダウンロード可能なたった 1 つの JavaScript ファイルによって手に入れることができます。
jQuery をダウンロードした後、以下の単純な <script> タグを組み込むことで任意の HTML または PHP ファイルに jQuery を追加することができます。
<script type="text/javascript" src="/path/to/jquery.js"></script>
|
例えばサイト上のあらゆるフォームのラベルの最後にコロン (:) を追加しなければならないという、至って単純ながらも、かなりの手作業を必要とする面倒なタスクがあるとします。この場合、コード全体でフォームのラベルを探し、それぞれの行の最後にコロンを追加することもできますが、代わりに以下の jQuery コードを使用するという手段もあります。
リスト 1. jQuery によるコロンの追加
<script type="text/javascript">
$(document).ready(function(){
$("label").append(":");
});
</script>
|
この関数は単純なもので、ページの準備が整って完全にロードされるのを待ってから ($(document).ready() の部分)、DOM 要素 label をすべて検索する匿名関数を実行し、それによって検出されたテキストの最後にコロンを追加します。$() 関数では DOM 要素にアクセスする際に DOM 要素のそのままの名前を使ってアクセスすることができるため、DOM を使い慣れている開発者にとっては理想的なインターフェースとなります。
もちろん、jQuery を使ってできることは他にもたくさんありますが、最初の紹介としてはこれで十分です。jQuery では、単純な組み込み関数を使用してページがロードされるまでコードを待機させることによって、確実にコードが機能するようにします。そしてもう 1 つの単純な行によって、コードが検出した DOM 要素 label をすべて素早く変更します。すべてはクライアント内で行われるため、マークアップをいちいち探し出して変更を加えるといった作業をする必要はありません。
単純なアプリケーションの作成: 電話帳
jQuery の基本について説明し終わったところで、早速 PHP と MySQL を使って単純な電話帳アプリケーションを作成してみましょう。このアプリケーションを構成する要素は、以下の 3 つです。
- 個人の名前と電話番号を保持する MySQL テーブル
- 検索フォームが含まれる index.php ファイル
- データベース・テーブルにクエリーを実行するための find.php ページ
これから、上記の要素を 1 つずつ作成します。
データベース・テーブルを作成する
MySQL でデータベース・テーブルを作成する作業は、おそらくこの手順のなかで最も簡単な部分です。このアプリケーションに必要なのは、ID (テーブルのキー)、名前のフィールド、電話番号のフィールドといった最低限の情報だけが含まれるテーブルです。名前と電話番号のフィールドは英数字にできるため、varchar() 関数を使用することになります。ID フィールドは autoincrement primary key として作成します。このテーブルには directory という名前を付け、以下の SQL (Structured Query Language) コードを使って作成します。
リスト 2. SQL による directory テーブルの作成
CREATE TABLE `directory` (
`id` INT NOT NULL AUTO_INCREMENT ,
`name` VARCHAR( 64 ) NOT NULL ,
`phone` VARCHAR( 16 ) NOT NULL ,
PRIMARY KEY ( `id` )
) TYPE = MYISAM ;
|
見てのとおり、このコードには何も複雑な点はありません。実際、このアプリケーションを後から独自に改良する機会は山ほどあります。例えばキーワードまたはロケーション・フィールドを追加して検索を絞り込めるようにすることで、アプリケーションを拡張するという方法もありますが、とりあえずは、このままのアプリケーションで作業を進めることにします。
テーブルの作成が完了したら、今度はテーブルにデータを入力します。名前と電話番号を入力するには、phpMyAdmin またはコマンドラインを使用できますが、以下の SQL 命令セットを使用することもできます。
リスト 3. SQL によるテーブルへのデータ入力
insert into `directory` (name,phone) values ('Tom Smith', '512-555-0111');
insert into `directory` (name,phone) values ('Bill Smith', '512-555-0112');
insert into `directory` (name,phone) values ('John Smith', '512-555-0113');
insert into `directory` (name,phone) values ('Jane Smith', '512-555-0114');
insert into `directory` (name,phone) values ('Sara Smith', '512-555-0115');
|
値の入力が完了したら、コマンドラインから select * ディレクトリー操作を実行するか、または phpMyAdmin で Browse をクリックして、レコードの一覧が返されることを確認してください。
index.php ファイルを作成する
次に、このアプリケーション用の簡単なホーム・ページを作成します。このページは index.php という名前の PHP ファイルですが、この時点でファイルに含まれる内容はほとんどが HTML コードですfind.php ファイルでの作業 (次のステップ) が終わってから、このファイルに戻って最後の仕上げをすることなります。
とりあえず必要なのは、フォームが含まれる必要最小限の HTML ファイルだけです。フォームの各要素には一意の ID を含めます。これは、jQueryを使ってそれぞれの要素を識別できるようにするためです。
リスト 4. フォームが含まれる HTML
<html>
<head>
<title>Welcome!</title>
</head>
<body>
<h1>Search our Phone Directory</h1>
<form id="searchform" method="post">
<div>
<label for="search_term">Search name/phone</label>
<input type="text" name="search_term" id="search_term" />
<input type="submit" value="search" id="search_button" />
</div>
</form>
<div id="search_results"></div>
</body>
</html>
|
上記コードですぐに気づくのは、次の 2 つの点です。1 つ目は、フォームにアクションが関連付けられていないことです。しかし、これはまったく問題ありません。前にも言ったように、このフォームは従来の「クリック、待機、表示」の同期パターンには従いません。その代わりとして、search_term フィールドにユーザーのアクティビティーを監視する機能を追加することになります。
2 つ目の点は、フォームの直下にある空の DOM 要素 search_results です。検索によって返ってくるレスポンスはすべて、この DOM 要素に含まれることになります。この点についてはまだ掘り下げず、まずは find.php ページを作成することにします。
find.php ファイルを作成する
find.php ファイルは、すべてのアクションが起こる場所です。つまりこのファイルで、アプリケーションがデータベースに接続し、directory テーブルに対するクエリーを実行します。
find.php ファイルの最初の部分に含まれるのは、接続情報です。この記事のために、このファイルには該当する情報をすでに組み込んでおきました。実際には、この情報をインクルード・ファイルまたは必須ファイルに含めるか、それよりも遙かに大きなフレームワークの一部にすることになると思います。
リスト 5. find.php ファイルの作成
<?php
define(HOST, "your.host.here");
define(USER, "your-user-name");
define(PW, "your-password");
define(DB, "your-db-name");
$connect = mysql_connect(HOST,USER,PW)
or die('Could not connect to mysql server.' );
mysql_select_db(DB, $connect)
or die('Could not select database.');
|
次に、index.php ファイルのフォームから検索語を取得します。返された検索語に簡単な処理を行ってから、処理された値をデータベースに挿入します。ここでは strip_tags() 関数と substr() 関数を使用して、検索語からすべての HTML タグを除去してサイズを縮小することにします。ユーザーの入力を 100 パーセント信用することはできないため、このような前処理をしておくことは得策です。
実際には、検索語から HTML タグを取り除いた後に、追加のステップとして mysql_escape_string() を実行してください。これによってさらに、データベースを台無しにし兼ねない他のあらゆるもの (単一引用符など) が除去されることになります。
$term = strip_tags(substr($_POST['search_term'],0, 100));
$term = mysql_escape_string($term);
|
今度は SQL 文を作成する番です。directory テーブルからは、検索語に一致するすべての名前と電話番号を取得しなければなりません。それには、LIKE を使用して検索語を名前フィールドと電話番号フィールドに突き合わせてから、mysql_query() を使ってクエリーを実行します。
リスト 6. SQL 文の作成
$sql = "select name,phone
from directory
where name like '%$term%'
or phone like '%$term%'
order by name asc";
$result = mysql_query($sql);
|
クエリーを実行した後は、結果を出力することができます。結果を保持する $string 変数を初期化し、続いて mysql_num_rows() を使用して、返された行があるかどうかをチェックします。検索語の検索結果を受け取らなかった場合には、$string を "No matches!" に設定し、結果を受け取った場合には結果セットに含まれるそれぞれの名前と電話番号を出力します。このプロセスの最後で echo コマンドを実行して、ストリング全体を出力します。
リスト 7. echo コマンドによるストリングの出力
$string = '';
if (mysql_num_rows($result) > 0){
while($row = mysql_fetch_object($result)){
$string .= "<b>".$row->name."</b> - ";
$string .= $row->phone."</a>";
$string .= "<br/>\n";
}
}else{
$string = "No matches!";
}
echo $string;
?>
|
PHP 機能のこの部分自体、かなり有益なことはもちろんですが、まだ何もこのスクリプトに提供されるようになっていません。そこで必要となるのが、このスクリプトに検索語を提供できるようにすることです。次のセクションで、その作業を行います。
jQuery を index.php に追加する
この時点で揃っているのは、何の変哲もない PHP ページのペアと、単純な MySQL テーブルだけです。jQuery を追加すると、この控えめなアプリケーションが最新の Ajax 対応アプリケーションに変身し、Mac OS X での Spotlight や Google Desktop Search といったデスクトップ検索アプリケーションのように振る舞うようになります。
まずは index.php ファイルを開いて、ダウンロードしたばかりの jquery.js ファイルへの呼び出しを確実に追加してください。
<script src="./jquery.js"></script>
|
次に、検索フォームがありふれたフォームのように振る舞わないようにするための単純な関数を作成します (それには、preventDefault() 関数を使用します)。すべての Submit ボタンのクリックとキー・アップ・イベント (つまり、キーボードで文字を入力するたびに発生するイベント) によって、これから新しく作成する ajax_search() という名前の関数が呼び出されるようにします。
リスト 8. 検索フォームが通常のフォームのように振る舞わないようにするための関数の作成
<script type='text/javascript'>
$(document).ready(function(){
$("#search_results").slideUp();
$("#search_button").click(function(e){
e.preventDefault();
ajax_search();
});
$("#search_term").keyup(function(e){
e.preventDefault();
ajax_search();
});
});
|
slideUp() 関数を使用して DOM 要素 search_results を一時的に非表示にしている点に注目してください。また、その DOM 要素を名前で参照するために、$() 関数を使用しています。CSS を十分に使い慣れていれば、jQuery の手法も直観的に理解できるはずです。例えば、search_results という一意の ID を持つ DOM 要素を参照するには、$("#search_results") を使用すればよいだけです。
もう一点、誰かが Search をクリックした場合も、search_term フィールドに文字を入力した場合も、それぞれのデフォルトの振る舞いは匿名関数によって阻止され、アプリケーション・フローが変更されて ajax_search() 関数 (次に作成する関数) が呼び出されることにも注目してください。
ajax_search() はごく単純な関数です。この関数は、DOM 要素 search_results を表示し (前に非表示にしたことを思い出してください)、search_term 入力フィールドの値を取り込んで、find.php ファイルを非同期で実行する関数 ($.post()) に渡した後、レスポンスを待機します。レスポンスが到着すると (前に説明したように、一致する結果が 1 つもないとしても、find.php はある種のレスポンスを返します)、jQuery は DOM 要素 search_results にそのレスポンスの値を設定します。
リスト 9. ajax_search() 関数
function ajax_search(){
$("#search_results").show();
var search_val=$("#search_term").val();
$.post("./find.php", {search_term : search_val}, function(data){
if (data.length>0){
$("#search_results").html(data);
}
})
}
</script>
|
これで、すべてのシステムが用意できたので、検索したい情報を入力してみてください。検索エンジンがリアルタイムで動作して、キー・アップ・イベントごとにレコードを取り込むはずです。また、Submit をクリックした場合にも検索エンジンは動作します。例えば図 1 では、検索フィールドに「a」が入力されたことによって、アプリケーションがこの文字が含まれる Jane と Sara Smith のレコードを返しています。
図 1. Ajax による検索が行われている様子
まとめ
言うまでもなく、このアプリケーションはさらに改良することができます。例えば、キーワード・フィールドを追加してキーワードで検索できるようにすることも可能です。あるいは、各個人のレコードにそれぞれが専門とする分野のタグやキーワードが含まれるように変更すれば、プロジェクトごとに適切な人材を検索できるようになります。また、E メール・のフィールド、誕生日のフィールドなどを追加して、検索パラメーターを拡張するのも一考です。
要は、このアプリケーションで jQuery を使用している部分にとっては、バックエンドで何が行われていても構わないということです。jQuery は、検索語を find.php というファイルに渡していることだけしか認識していません。find.php ファイルは、その命令を jQuery 関数から受け取っていることを認識もしなければ、考慮もしません。find.php ファイルにしてみれば、検索語は通常のフォーム送信プロセスによって送信されたものと変わりなく、そのデータを使ってクエリーを実行して検索語と一致するレコードを返すだけのことです。
参考文献 学ぶために
製品や技術を入手するために
- IBM ソフトウェアの試用版を使用して、次のオープンソース開発プロジェクトを革新してください。ダウンロード、あるいは DVD で入手できます。
- IBM 製品の評価版をダウンロードして、DB2®、Lotus®、Rational®、Tivoli®、および WebSphere® のアプリケーション開発ツールとミドルウェア製品を使ってみてください。
議論するために
著者について  | 
|  | Thomas Myer は、テキサス州オースチンにあるコンサルティング会社、Triple Dog Dare Media の共同創立者です。彼は、ナレッジ・マネージメント、情報設計、そしてユーザビリティーに関する著作活動を行っています。 |
記事の評価
|