サンゴラボ

4年目ソシャゲエンジニア

CodeIgniterでAjaxを使う

Ajaxを使うときに、いつも忘れていて調べることから始まるので、ブログに簡単なサンプルをまとめておく。

CodeIgniterの出力クラスを使えば、簡単にJSONを返すコントローラが作れる。FuelPHPならRestコントローラで楽勝。

サーバ側(コントローラ)

ajax.php

<?php
class Ajax extends CI_Controller{

    public function __construct(){
        parent::__construct();
    }

    public function index(){

        // サーバ側でもってるデータ
        $array = array(
            array('framework' => 'codeigniter', 'lang' => 'php',),
            array('framework' => 'fuelphp',     'lang' => 'php',),
        );

        //postで送られてきたデータ
        $post_data = $this->input->post('number');

        //postデータをもとに$arrayからデータを抽出
        $data = $array[$post_data];
		
        //$dataをJSONにして返す
        $this->output
             ->set_content_type('application/json')
             ->set_output(json_encode($data));
    }
}

クライアント側(ビュー)

ajax_client.php

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Ajaxのサンプル</title>
<style></style>
<script src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
<script>
$(function(){
    $('button').on('click', function(){

        //クリックされたボタンのid属性を取得
        var button_id = $(this).attr('id');

        //Ajax	
        $.ajax({
            type: 'post', // HTTPメソッド(CodeIgniterだとgetは捨てられる)
            url: 'http://localhost/codeigniter/index.php/ajax', //リクエストの送り先URL(適宜変える)
            data: {'number': button_id}, //サーバに送るデータ。JSのオブジェクトで書ける
            dataType: 'json', //サーバからくるデータの形式を指定

            //リクエストが成功したらこの関数を実行!!
            success: function(data){
                alert('フレームワーク:' + data.framework + ', 言語:' + data.lang);
            }
        });
    });
});
</script>
</head>
<body>
    <button id="0">ボタン1</button>
    <button id="1">ボタン2</button>
</body>
</html>

サーバ側ではAPIを作る感じかな。
あと、ちゃんとモデルに切り分けたいね。

URI設計に悩んで開発が進まない

最近CodeIgniterやFuelPHPでシステムを作っててURI設計を意識するようになりました。
理由としてはCodeIgniterやFuelPHPにおけるURLのセグメントが、コントローラのクラス、
メソッド名、メソッドの引数名に関係しているからです。


CodeIgniterにおけるURLセグメントの例:

 hogehoge.com/class/function/ID 

第1セグメント(class)がコントローラのクラスに対応
第2セグメント(function)がコントローラのメソッド名に対応
第3セグメント(ID)がメソッドに渡す引数に対応

とても直感的使いやすいのですが、URI設計という言葉を聞いていろいろ試行錯誤中です。なんとなくわかるようで、実際に設計するとなるとわからない。


てことでとりあえず調査。

第20回 “使いやすいURI(URL)”の設計を考える

たかが URI の設計、されど URI の設計

RESTful Web アプリの設計レビューの話


書いてあることは納得できることばかりですが、今までは全然意識してなかったです。挙げられているURI設計の指針をいくつか抽出しました。

  • 短くて入力しやすいURLにする
  • わかりやすい(記述的な)URIにする
  • サイトの構造をきちんと表す
  • マジックナンバーを使わない
  • 動詞ではなく名詞にする


結構ユーザ目線の事柄が多いですが、URI設計をしっかりすることは開発者にとっても利点があると個人的に感じました。開発者はユーザよりはるかにURLを直打ちしているので、URLの意味や構造がしっかりしていることはシステムの理解につながると思います。

特にCodeIgniterやFuelPHPのようにURLセグメントがソースコードと密接に関係しているので、良いURI設計はシステムの全体像を把握する助けになりそうです。

URI設計について概要は理解できたかな、という感じですが、実際のシステムの設計では結構苦労しています。原因はシステム特有であったり、CodeIgniterやFuelPHPならではであったりと、いろいろあります。話が変わってしまうので、別記事で書こうと思います。

CodeIgniterのMVCについてのメモ

最近CodeIgniterを触ってて、いろいろ悩むこととかあったので書いておきます。

特にMVC周りでは今もどうしていいかわかりません…

CodeIgniterに関しては公式が、MVCに対してルーズなアプローチをとっていると宣言しているので、MVCでちゃんと書くにあたりネット上でもいろいろな意見がある感じです。

ルーズでもいいけど、MVCに基いて設計する場合の解を示してくれたら、よかったんですがね。公式からしたら「勝手にしろよ」って感じなんでしょうが(^_^;)

実際問題、素人の僕がいろいろ悩めるくらいにルーズなので、CodeIgniter使ってチーム開発する場合には、ちゃんとルールを決める必要があると感じました。

 

そこで、どうしたらいいかを自分なりに考えたので残しておきます。

CodeIgniterであろうとなかろうと、MVCの流れは以下のようになると思います。

MVCの流れ(コントローラ目線)

1.ビューからの入力を受けて

2.対応するモデルに投げて、データもらって

3.データを対応するビューに渡して出力

 

この流れに準拠してもいろいろな問題が生じます。

CodeIgniterではモデル・ビュー・コントローラの部分をapplicationディレクトリ配下のmodels・views・controllersディレクトリにそれぞれ分けることができます。

「なんだわかりやすいじゃん!」って思っていたのですが、それぞれの境界線があいまいだし情報いろいろあって混乱してます。実際に使ってみて主に以下のような問題にぶつかりました。

・バリデーションはどこで実行するの?コントローラ?モデル?

・ロジックはどこに書くの?

・コントローラが肥大化する

最初のバリデーションに関する問題が発生する理由は、CodeIgniterがバリデーションの実行をユーザに委ねているからです。フォームからの入力値は入力クラスに勝手に入ってるんだけど(じゃあバリデーションもやってくれよ)、実行するときはアプリケーションでform_validation->run()をしないとダメ。

これについてはいろいろ悩んだんですが、結果的にどっちでもいいかなと思いました。もちろん開発する際にはコントローラに書くかモデルに書くかはしっかり決めるべきだと思います。個人的に不正な値はコントローラで叩いてしまうのが好みです。どちらにしてもバリデーションルールの設定は、ちゃんと設定ファイル(form_validation.php)にまとめてコードをすっきりさせた方がいいですね。

 

次のロジックの場所についてですが、これについては答えが出せてません。CodeIgniterのユーザガイドでは、モデルはデータベースとアクセスするもの(DAOと名乗れ!)と書かれていて、ロジックは知らねーよ状態です。じゃあコントローラに…となるのですが、大きなシステムでロジックをコントローラに書いてしまうと処理を追うのが大変になってしまいます。つまり、ロジックは迷子です。

そこで、ロジックの場所を考えてみたところ2つ浮かびました。1つはモデルにデータアクセスとロジックを分けてわかりやすいように書く。もう1つはロジックをユーザライブラリに書く。これもまたどっちでもいいけど、ちゃんと決めて守ることが大事だと思います。

 

最後のコントローラの肥大化についてですが、これは最初の2つにかなり関連しています。肥大化が問題なのではなくて、肥大化することにより処理の大枠が掴めなくなることが問題だと僕は考えています。つまり、「このURLを叩いたら、こうしてこうする!!」というのがわかる部分がないのが、個人的に辛いです。ロジックを上手く分離できたらなんとかなるのかなー、と甘い考えをもっています。結局チーム内でルール決めて、それに準拠するのが一番ですね。CodeIgniterのようなゆるいフレームワークを使う場合は、チーム内でのルールがかなり重要になってくると思います。

 

長々と書きましたが、今後はFuelPHPを使っていくことになりそうなので(え?)、CodeIgniterでぶつかった問題を意識して使っていければいいと思います。

ちらっと見た感じでは、FuelPHPにはアクションメソッド(ブラウザから実行されるメソッド)とかビューモデル(なんだかよくわからない)とかあって良さそう。