Articles
| |
Oracle + PHP Cookbook |
PHPとOracleを使用したAjaxプロセスの作成著者:Larry Ullman シームレスなデータベースの相互作用をWebページに追加するJavaScriptの利用法
2007年2月公開 以前からWeb開発の世界では、Ajax(Asynchronous JavaScript and XML)が脚光を浴びています。 Ajaxは、一部のGoogleの機能(サジェスト、マップ、Gmailなど)によって注目を集めることになりましたが、これを使用するとユーザーがフォームを送信したり、リンクをクリックしたりすることなくサーバーへのリクエストが実行されます。 つまり、ユーザーは何もする必要がないばかりか、何が起こっているのかを知る必要もない状態で、Webブラウザがサーバーへのリクエストを実行し、レスポンスを処理しています。 Ajaxがもたらす即時性は、単に便利であるだけでなく、実にすばらしい威力を発揮する可能性も秘めているのです。 このレシピでは、シンプルなWebページにはじまり、JavaScript関数、XMLHttpRequest、PHPスクリプト、そして最終的にはOracleデータベースに至るまで、Ajaxを使用するために必要なすべてのコードを説明します。 また、コードに関する説明にあわせて、個々の要素を全体像と結びつけ、各チャンクの働きや重要性についても解説していきます。 このHowToを読むことで、一部のサンプル・コードだけでなく、Ajaxのコンセプト全体に関する幅広い理解を得ることができます。 背景 これから取り上げるサンプルは、一種の登録フォーム(またはその一部)です。 ここではユーザーの登録に同じアドレスが何度も使用されないようにするために、ユーザー表の電子メール・アドレスが一意であることを確認する必要があります。 通常これは、ユーザーが処理用のPHPスクリプトにフォームを送信した後に発生する検証プロセスの一部です。 しかし、このサンプルを利用すれば検証のためにユーザーが待たされることはありません。 それどころか、ユーザーが各自の電子メール・アドレスを入力して次のフォーム・フィールドに移動すると、電子メール・アドレスの検証が即座に実行されます。 ただし、この場合もデータベースへの問合せは必要で、ここでAjaxがかかわってきます。 このサンプルで使用する表構造は簡単なもので、以下のSQL文で作成できます(ほかの表を使用する必要はなく、ここでは識別キーなども使っていません)。
CREATE TABLE users (
email VARCHAR2(60)
)
この表構造は、さまざまな方法で拡張できます。 ここで重要な点は、このサンプル・コードにおいては、上記のような表がすでに作成されており、その表に対してPHPスクリプトから接続できることが前提となっているということです。 一部のレコードについては、サンプルを完全に動作させるために、この表に配置されている必要があります。そのため、以下のように表へ移入します。
INSERT INTO users (email) VALUES ('this@that.com')
INSERT INTO users (email) VALUES ('me@school.edu')
INSERT INTO users (email) VALUES ('fake@address.net')
表の作成と移入が完了したら、コーディングを開始できます。 前述のとおり、関連するスクリプトは2つあります。 すべての開発とテストをおこなう場合、以下の手順を実行します。
手順1: データベース問合せのプログラミングPHPスクリプト全体はajax.phpと呼ばれます( sample code zipを参照)。 このスクリプトの目的は、Oracleで問合せを実行し、問合せ結果に基づいてメッセージを表示することです。 これは、Oracle、SQL、そしてPHPの典型的な基本スクリプトですが、具体的な手順を把握できるように説明していきます。 このスクリプトでは、URLで電子メール・アドレスを受け取る必要があります。これには、変数$_GET['email']を使用します。 次に、スクリプトはOracleデータベースに接続します。 問合せ自体によって、対象となる電子メール・アドレスが含まれたユーザー表のレコード数がカウントされます。
SELECT COUNT(*) AS NUM_ROWS FROM users WHERE email='{$_GET['email']}'
これにより、0または1が返されます(何も返されない場合もあります)。 問合せはOracleで実行され、返された結果はPHPの$rows変数にバインドされます。 このとき$rowsは、その電子メール・アドレスが含まれたレコードがデータベース内にいくつあるのかを示します。 Ajaxに関して、スクリプトの重要な部分を以下に示します。
if ($rows > 0) {
echo 'Email address has already been registered!';
} else {
echo 'Email address is available!';
}
$rowsの値に基づいて、上記の2つのメッセージのうち1つが表示されます。 このページについて確認することは以上です。 このスクリプトは、標準のWebページのように使用されるわけではないため、HTMLの記述は必要ありません。
このスクリプトにさらに手を加える場合、入力された電子メール・アドレスが、電子メール・アドレス用の正規表現のパターンと一致しているかどうかの確認が可能です。 正規のパターンと一致していれば問合せを通常どおりに実行し、一致していない場合は有効な電子メール・アドレスではないことを示す文をエコーします。 少なくともSQLインジェクション攻撃については防止する必要があります。 (つまり、なんらかの形で妥当性が保証されないままに、$_GET変数が問合せで使用されることを避ける必要があります。) 手順2: PHPスクリプトのテストこのAjaxプロセス全体には、HTML、JavaScript、PHP、SQL、Oracleという複数のテクノロジーが関連しているため、プログラミングをおこなう際には各要素をテストすることが推奨されます。 テストを実行しなければ、問題がどこにあるかを特定しようとして行き詰ってしまうことにもなりかねません。 このPHPスクリプトのテストは、以下に示すとおり実に簡単です。
手順3: JavaScriptのプログラミングこのセクションは、すでにJavaScriptについて多くの経験を積んでいるユーザーでないと難しいかもしれません。 いずれにしても、PHPページからのリクエストを実行したり処理したりするのはJavaScriptコードであるため、JavaScriptコードはAjaxプロセスの核となる部分であるといえます。 そのため、このコードについては詳細に説明していきます。 このJavaScriptコードでは、3つの関数を定義します。 最初の関数で、リクエストのオブジェクト変数を作成します。
function createRequestObject() {
var ro;
if (navigator.appName == "Microsoft Internet Explorer") {
ro = new ActiveXObject("Microsoft.XMLHTTP");
} else {
ro = new XMLHttpRequest();
}
return ro;
}
このコードは、あらゆるAjaxアプリケーションで、修正を加えずに使用できます。 使用しているWebブラウザがMicrosoft Internet Explorerの場合、ro変数はタイプMicrosoft.XMLHTTPのActiveXObjectとして初期化されます。それ以外のすべてのブラウザでは、ro変数は直接的なXMLHttpRequestタイプのオブジェクトとなります。 ここで必要なことはこれだけです。 これで、ro変数は、非同期リクエストを実行するために必要な機能すべてを備えたオブジェクトになりました。 リクエストのオブジェクト変数が作成されると、この関数がそれを返します。
この関数は、初めてページがロードされた直後に、JavaScriptコードによって呼び出されます。 var http = createRequestObject();これで、httpはオブジェクトを示し、ほかの関数でグローバルに使用できるようになりました。 次は、PHPスクリプトを呼び出す関数です。
function sendRequest(email) {
http.open('get', 'ajax.php?email=' + encodeURIComponent(email));
http.onreadystatechange = handleResponse;
http.send(null);
}
この関数は引数を1つ持ちます。この引数が検証の対象となる電子メール・アドレスです。 次に、PHPスクリプトへの接続が開かれます。 open()メソッドの最初の引数が示すとおり、リクエストのタイプはpostではなくgetとなります。 電子メール・アドレスがURLに追加され、その結果、ページ・リクエストはajax.php?email=this@that.comのようになります。すでに説明したとおり、これがPHPスクリプトを適切に呼び出す方法です。 encodeURIComponent()関数は、単に送信された値をエンコードしてURLにするだけですが、これを安全な形で実行します。 この関数の3行目は、リクエストがおこなわれた後に呼び出すJavaScript関数を、オブジェクトに伝えるものです。 そして最後の行によって、実際にリクエストがおこなわれます。
要約すると、まず1番目の関数createRequestObject()で、必要なオブジェクト変数を作成します。 次に2番目の関数sendRequest()で、PHPスクリプトの実際のリクエストが実行されます。 ここで必要となるのが、そのリクエストを処理する関数です。
function handleResponse() {
if (http.readyState == 4) {
document.getElementById('email_label').innerHTML = http.responseText;
}
}
2番目の関数で、リクエストがおこなわれた後にこの関数が呼び出されるよう、リクエスト・オブジェクトに対する指示が出されています。 この関数では、まずリクエストが正常に実行されたかどうかを確認します。 リクエストが正常におこなわれていれば、http.readyStateは4となります。この値が4の場合はリクエストが正常に動作したことを示しますが、場合によっては0から3になる可能性もあります(各数値の実際の意味については、必要に応じてオンラインで検索してください)。 リクエストの結果はhttp.responseText属性に格納され、その結果として、PHPスクリプトによってエコーされる2つのメッセージのいずれかが表示されます。 つまり、リクエストが正常に機能した場合、http.responseTextは、"Email address has already been registered!"または"Email address is available!"のいずれかとなります。
この時点で、JavaScriptにおいてPHPスクリプトの結果が認識されます。 ここで必要となるのは、JavaScriptで結果がユーザーに通知されるようにすることだけです。 この処理を実行する簡単な方法は、以下で示すように、alert()ボックスを使用することです。 alert(http.responseText);これを条件節に挿入すると、アプリケーション全体をテストしたときに結果が表示されます。 (実際、alert()はJavaScriptコードの動作を確認するための優れたデバッグ・ツールです。) しかし、エンドユーザーにとっては、こうしたアラートが表示されるのは目障りなので、フォームの電子メール入力欄の横にメッセージを表示するほうがよいでしょう。 これを処理する場合は、DOM(ドキュメント・オブジェクト・モデル)を使用します。 具体的には、email_labelと呼ばれる自分のページの要素にhttp.responseTextを割り当てます。 このプロセスについては、手順4で説明します。 ここまでは問題ないでしょうか。 繰返しとなりますが、上記のJavaScriptに関する手順は、このシーケンスにおいてもっとも重要かつ複雑な部分です。 このJavaScriptでは、3つの関数を使用して、ブラウザ固有のリクエスト・オブジェクトの定義、PHPスクリプトに対するリクエストの実行、そしてそのリクエストの結果に関する処理の3つを実行します。 この点について何か分からない点がある場合や、より複雑なAjaxアプリケーションを作成する段階へと進む場合には、JavaScriptおよびDOMについて、もう少し知識が必要です。 手順4: JavaScript関数に基づくHTMLフォームの作成前述のとおり、このサンプルは、少なくとも電子メール・アドレスを取得する登録フォームであることが前提となっています。 最小限のフォームは、次のようになります。<form action="somepage.php" method="post"> Email Address: <input name="email" type="text" size="30" maxlength="60" <//><br <//> First Name: <input name="first_name" type="text" size="20" maxlength="20" <//><br <//> (Rest of the form...) </form>これで完了!・・・ではありません。 "送信"ボタンなどのほかの機能を追加する必要があるでしょう。 ただし、このサンプルで必要となるのはこれだけです。 混乱を避けるために付け加えると、上記のアクションおよびメソッドは、ajax.phpスクリプトとは関係がありません(このスクリプトはこのフォームの送信に関する処理をおこないません)。 実際は、あと2つ必要なことがあります。 まず、このフォームでは、リクエストを実行するJavaScriptコードを何らかの方法で呼び出す必要があります。 これを実現するには、いくつかの方法があります。たとえば、クリックが可能なリンクを作成する、送信ボタンがクリックされるのを待つなどの方法です。 ここでは、ユーザーが電子メール・アドレスを入力して次のフォーム要素に進んだ後に、JavaScriptが呼び出されるようにします。 これには、onchange()メソッドが必要となるため、電子メールの入力で以下のように追加します。
Email Address: <input name="email" type="text" size="30" maxlength="60"
初めて何らかの入力をおこなう場合や、そのあとで他の入力のためにタブやクリックを操作する場合など、この入力の値をユーザーが変更すると、その直後にJavaScriptのsendRequest()関数が呼び出されます。 この関数により、唯一の引数として電子メール・フォーム入力の値が挿入されます。 JavaScriptコードを見直すと、ここで入力された値がこの関数に送られ、さらにPHPスクリプトに送られる流れを確認できます。
もう1つ、HTMLフォームで必要となるのは、ユーザーが受信メッセージを表示させることができるようにするために、JavaScriptによる受信メッセージの"書込み"が可能な場所です。 handleResponse()関数の記述にあるとおり、このメッセージはemail_labelと呼ばれる要素のinnerHTMLに割り当てられます。 このため、電子メール・アドレス入力の後に、このIDを使用したspan要素を追加します。 <span id="email_label"></span>HTMLフォームをJavaScriptに結びつけるための処理は、これで完了です。 (最後のコードについては、 sample code zipのリスト1を参照してください。) それでは、実際の動作を確認してみましょう。 手順5: AjaxプロセスのテストHTMLとJavaScriptが完成したら、ajax.htmlとして(ほかの名称も使用可能)保存し、さらにPHPスクリプトと同じディレクトリに配置します。 フォームは、ファイル・システムから開くのではなく、WebブラウザでURLを使用して実行することでロードします(つまり、http://yoururl/ajax.htmlにアクセスします)。 未使用の電子メール・アドレスを適切な入力先に入力し、[Tab]キーを押すか、次の入力先をクリックします。 保存済みの電子メール・アドレスを使用して繰り返します。 表示される結果は、以下の2つのスクリーンショットのようになります。 Absolute magic!
結論この記事では、PHPとOracleを使用したAjaxプロセスを簡単に実装する方法について確認しました。 これを実装すると、サーバー側の検証がクライアント内で実行されるようになります(ただし、JavaScriptが無効な場合のために、サーバー側での検証も継続する必要があります)。 ここで示したサンプルがエンドユーザーにとって有益な機能であることは、実装により以下の操作をおこなう必要がなくなる点を考えると明らかではないでしょうか。
また、Ajax、PHP、およびOracleを使用すれば、さらに多くのことを実行できます。 この記事で取り上げたサンプルでは、1つのデータをPHPスクリプトに送り、1つの文字列を取得したにすぎませんが、実際には、さらに多くの情報をやりとりすることができます。 呼出しページに返されるデータが大量にある場合は、PHPを使用してXML形式で返し、JavaScriptでその解析と表示をおこなうことができます。 オンラインで検索すれば、ほかにもさまざまな例を参照できます。 Larry Ullmanは、情報技術を専門とする DMC Insightsで、デジタル・メディア・テクノロジー担当ディレクター兼Web開発担当主任を務めています。 ワシントンDC郊外に在住し、PHP、SQL、Web開発およびその他のコンピュータ技術関連の書物の著者として活躍しています。 |