【jQuery】CakePHPでAjaxを実装する方法




GoogleMapやGoogle検索のレコメンド機能など、さまざまな活躍をしているajaxですが、それをCakePHPとjQueryで実装してみることにしました。

目次

Ajaxとは?

Ajaxについて

そもそもAjaxとは、Asynchronous JavaScript XMLの略です。すなわち、JavaScriptとXMLを利用した非同期処理のことを指し、上にも書いたようにGoogleMapやGoogle検索のレコメンド機能に使われています。

この機能の最大のメリットは、ページ内の要素を更新する際にページ全体を再読み込みする必要がないということです。

例えば、GoogleMapで表示範囲をドラッグで変更する度にページがリロードされたらストレスが溜まってしまいます。Google検索をする際、一文字打つごとにレコメンドの内容が変わるのは非常に便利です。その他にも、例えば何かのフォームを作る際に、フォームに打ち込まれた内容がDBに存在するかをチェックするような機能を実装することが出来ます。

Ajaxをうまく活用することで、ユーザビリティの改善やストレスの軽減といったことを実現できることができるのです。

Ajaxの処理の流れ

  1. クライアント(ブラウザ)がサーバーに対して処理のリクエストを行う
  2. サーバーはリクエストを受け取って必要ならばDBと通信を行う
  3. サーバーはブラウザにレスポンスを返す
  4. ブラウザはレスポンスを受け取り、ページ内の要素を更新する

GoogleMapの例だと、

  1. マップをドラッグして表示範囲を移動する
  2. サーバー側で新しい表示範囲のデータを取得する
  3. サーバーは新しい表示範囲のデータをブラウザに送る
  4. ブラウザ側で新しい表示範囲を表示する

という流れになります。

使われている技術

JavaScript

フロントエンドでおなじみのJavaScriptです。(サーバーエンドでも使われてます)

XMLHttpRequest

XMLHttpRequest (XHR) オブジェクトを使用すると、サーバーと対話することができます。ページ全体を更新する必要なしに、データを受け取ることができます。これでユーザーの作業を中断させることなく、ウェブページの一部を更新することができます。 XMLHttpRequest は AJAX プログラミングで頻繁に使用されます。

XMLHttpRequest という名前ではあるものの、 XML だけでなくあらゆる種類のデータを受け取るために使用することができ、 HTTP 以外の (file および ftp を含む) プロトコルにも対応しています。

MDN「XMLHttpRequest」(公式ドキュメント)より

こちらはあまり聞き慣れないかもしれませんが、JavaScriptでサーバーと非同期通信を行うためのAPI(組み込みオブジェクト)です。

API名にXMLとありますが、Ajaxを利用する場合は扱いやすさからJSONを使うことがほとんどです。

DOM

Document Object Model (DOM) は HTML や XML 文書のためのプログラミングインターフェイスです。ページを表現するため、プログラムが文書構造、スタイル、内容を変更することができます。 DOM は文書をノードとオブジェクトで表現します。そうやって、プログラミング言語をページに接続することができます。

MDN「DOMの紹介」(公式ドキュメント)より

つまりHTMLやXMLなどのドキュメントを、JavaScriptで操作するためのモデルとなります。HTMLやXMLを構造的に解釈することで、「どの要素に対して」「どんな操作を行うか」を任意に決めることができるようになります。

JSON

JSONは「JavaScript Object Notation」の略で、端的に言えばデータのフォーマットで、CSVやXMLなどと同じ分類になります。JavaScriptやPHPで扱いやすいため、Ajax通信はもちろん、PHPとJavaScriptのやりとりにおいても頻繁に使われます。

{ "name": "Keita", "age" : 26 }

特徴としては、波括弧{}で括ることと、Key-Valueのセットでデータを記述していくこと、Keyはダブルクォーテーションで囲むことです。シングルクォーテーションは使えません。これはPHPの連想配列やPythonのディクショナリ型とも同じ概念です。

Ajaxの実装

では早速、CakePHPで実装していきます。前提として

  • コントローラー名はMyController
  • アクション名、ビュー名はsample
  • Ajax通信先のアクション(メソッド名)はrecieveAjax

とします。

sample.ctp(ビュー)

var data = {x: 45, y: 90};
var json_data = JSON.stringify(data);//dataをJSON形式に変換

$(function(){
  $('#target').on('click', function(){
    $.ajax({
      type: 'POST', //サーバーとの通信方式.POSTかGETか
      url: 'my/recieveAjax', //myController.php内のrecieveAjaxメソッドとやりとりする
      data: json_data, //json_dataをサーバに送る
      dataType: 'json', //json形式でデータを送る
    }).done(function(response){ //Ajax通信が成功した場合、結果をresponseという変数で受け取る
      console.log('Ajax通信に成功しました');
      console.log(response);
    }).fail(function(){//Ajax通信が失敗した場合
      console.log('Ajax通信に失敗しました');
    });
  });
});

11行目はサーバーから返ってきた値をresponseという変数で受け取っていますが、ここの引数は3つまで指定することが出来ます。

}).done(function(response, result, xhr){

  • response: サーバーから返ってきたデータ
  • result: 通信結果(successかどうか)
  • xhr: コールバック関数

myController.php(コントローラー)

public function recieveAjax()
{
  if ($this->request->is('ajax')){ //ajax通信で呼び出されたら
    $recieved_data = $this->request->getData(); //JavaScriptから送られてきたデータを受け取る
    $this->response->body(json_encode(['result' => $recieved_data]));//Javascriptにデータを送る
    return;
  }
}

3行目ですが、Ajaxに対して行うことが前提になっている処理は、実行する前にAjaxからのリクエストであるかを確認するのが良いです。直接URLを叩かれて実行されると、予期しない挙動になる可能性があります。

また、5行目において今回は送られてきたデータをそのまま送り返していますが(意味のないことをしているが)、本来は4行目と5行目の間でデータベースと通信をおこなったり、受け取ったデータを処理したりします。

5行目では、連想配列をjson_encodeして送っています。つまり、JSONに変換すれば、’result’ だけではなく、複数データをビュー側のJavaScriptに戻すことが出来ます。

おわりに

おおよそのデータ処理はJavaScriptでも実行できるので、Ajaxが真価を発揮するタイミングは例えば以下のようなものが考えられます。

  • 重い計算をサーバー側にやらせたいとき
  • データベースとの通信がしたいとき
  • TensorFlowを用いた機械学習などサーバー側でしか出来ない処理があるとき

Ajaxを上手に活用すると、非同期でDBと通信してユーザーアクションに対するフィードバックを返せるなど、UI/UXに大きな改善をもたらすことができます。

あまりに頻繁に通信しすぎるとサーバー負荷の問題が出てくるので要注意ですが、上手く活用することでより良いウェブアプリをつくっていきましょう。