本文へジャンプ

最新鋭のPHPフレームワーク「Laravel4」でWeb開発 | (2)ルーティング編

Posted by mio.satoh

前回の投稿から早2ヶ月半が経ってしまったのですね。
東京は梅雨入りしてちょっぴりアンニュイな空模様ですが、来週から始まるW杯へ向けて心の準備で忙しくてテンションを下げる暇が無いmioです。
打ち合い上等ザックJAPANと松木氏解説の相性の良さに最近気づいてしまいました。TVで代表戦を観ているとツッコミが間に合わなくて大変なのでもう少し落ち着かせてくれると助かります。ディフェンスラインを。

さて、天使過ぎるPHPフレームワークLaravelを勝手に国内に啓蒙するこのシリーズ。
前回の導入編に引き続き、今回もLaravel4の基本的な部分をご紹介したいと思います。

今回の課題は、これがなくては処理が始まらない「ルーティング」の基本です。

本当はコントローラやビューの話まで進みたかったのですが、あまりに記事が長くなりそうなので分けて書くことにしました。フレームワークに初めて触る人にも分かりやすくをモットーに進めてまいります。

mioのLaravel初心者講座 目次

ルーティングとは

ここに書くことは基本のキであり、PHPフレームワークの基礎知識をお持ちの方なら既にお分かりの話と思います。
でも意外と基本的な概念の解説ってネットを探しても見つからないものです。

例えばあなたがLaravel4で何かWebサービスを作っていて、登録ユーザ"monster"さんのプロフィール画面を作りたい場合。

http://www.servicename.com/user/?id=monster

みたいなリクエストの仕方は格好悪い。

http://www.servicename.com/monster

というURIの方がスマートです。でも、

http://www.servicename.com/setting/account

でアクセスする設定ページなどとプロフィールページは処理を分けなければいけない。
そこでLaravel(に限らずPHPフレームワーク)を使ってサービスを構築すると、

"/setting"にアクセスされたら設定画面、それ以外の"/hoge"にアクセスされたらhogeさんのプロフィールを表示

みたいな処理を柔軟に行うことができます。 この、URIと処理を繋げる役割がルーティングです。

MVCパターンとは

Laravelは他の多くのフレームワークと同様MVCパターンというデザインパターンを基本構造としております。
MVCパターンは以下の3種類のプログラムで構成されます。

  • Controller/コントローラ:

内部処理。リクエストされたURIやフォームの入力値にしたがって、何かしらの処理をする。主役。

  • View/ビュー:

表示処理。ウェブページであれば、htmlのソースを生成する部分。フォームを含む場合は、入力値を受け取ってコントローラに送る仕事もある。

  • Model/モデル:

データ処理。PHPの場合は、主にDBとの連携部分。DBから必要な情報を引き出したり、保存したり。

この3つの処理の連携によってアプリケーションを作成するわけですが、この辺の概念的な内容から説明を始めるとキリが無くなるので、今は先に進みます。
ただし今回のルーティングの章にはこの中のコントローラが若干絡んでくるので、コントローラは色々処理する本体部分、くらいの気分で覚えていてください。

Laravel4のルーティングパターン

ここから本題に入ります。
Laravel4に用意されたルーティングパターンを紹介していくわけですが、とにかく沢山種類があります。

公式リファレンス

正直、Laravel4はリファレンスが親切だし読みやすいしで、上記のリンク先を読むだけで大抵のことが分かってしまうのですが、この記事では「いいから要点を教えてくれ」というせっかちな方のために重要なポイントに絞って紹介していきます。

基本原則

ルーティングを記述する場所

/app/routes.php
です。
おそらく初期状態でトップページのHello, Worldやエラーページへのルーティングが既に描かれていると思います。
ここにどんどん独自のルーティングを足していきましょう。

ルーティングの記述方法

Route::ルーティングメソッド('パス', 呼び出す処理);

このような形でメソッド、パス、処理を指定します。

そしてLaravelのルーティングには大きく分けて2通りの処理の呼び出し方法があります。

1:クロージャで書く

routes.php

Route::get('hello/', function()
{
    return 'Hello World'; //こんな風にroutes.phpに直接処理を書いてしまう
});

2:コントローラに渡す

routes.php

Route::get('hello/', 'HelloController@helloWorld'); //HelloControllerというコントローラのhelloWorldというメソッドを呼び出す

クロージャ型は、routes.phpに処理を直接書く方法です。
複雑な処理はコントローラに載せるのが基本なので、ある程度の規模のWebアプリになるとあまり使う機会はない気がします。が、これは即時性の高いデバッグ方法として使い出があるのです。説明にも便利なので、以下のサンプルコードでも基本的にこちらの書き方を挙げています。
コントローラ型の方は、コントローラを別に用意しておきルーターは橋渡しをするだけという形で、通常Laravelでのアプリ構築の標準形となります。

ここからいよいよ今回の肝であるルーティングメソッドの紹介に移りましょう。

ルーティングメソッド

get / post

routes.php

//getのとき
Route::get('hello/', function()
{
    return 'Hello World';
});

//postのとき
Route::post('hello/', function()
{
    return 'Hello World';
});

//getだろうがpostだろうが
Route::any('hello/', function()
{
    return 'Hello World';
});

上の例でもあった、一番シンプルなルーティングですね。
最初の引数にパスを入れ、後ろに処理を書きます。

パスにユーザ名などを入れてコントローラに渡したいときは...

routes.php

Route::get('user/{userName}', function($userName)
{
    return 'Hello, ' . $userName . '!';
});

"http://www.servicename.com/user/mio"の出力結果

Hello, mio!

このように、{hoge}の形でパスを書くことで、リクエストされた文字列を$hogeという引数に入れて処理に渡すことができます。
さらにこのパラメータ、デフォルト値を指定したり正規表現で条件を絞ったりといった高度な処理もできます。このあたりの凝った使い方についてはリファレンスへどうぞ。

filter

フィルターとはどんなときに使う代物かといいますと、例えばユーザログイン機能があるWebサービスの場合、ほぼ全てのページで「ログインチェック」処理を行う必要があるわけです。
でも全部のコントローラに同じログインチェックを書くのはダサいわけです。
そこでこのfilter、ルーティングの時点で「コントローラに渡す前にこの処理をする」という指示ができます。便利ですね。

これを使うには、まずフィルターの内容を準備して、そのフィルター名をルーティングに渡すという手順をとります。

filters.php

//checkフィルターの指定
Route::filter('check', function()
{
    if (Input::get('name') == '')
    {
        return '名前が空ですよ';
    }
});

routes.php

//ルーターにcheckフィルターを挿入
Route::get('user', array('before' => 'check', function()
{
    return '名前は空じゃなかったよ';
}));

さらにありがたいことに、ユーザのログイン状況チェックや、データの送受信を伴うWebアプリに必須のCSRFトークンチェックなど、メジャーなフィルター処理についてはあらかじめシンプルな処理が同梱されてます。(filters.phpの中を覗けばどんなフィルターが用意されているか分かるはず)。

routes.php

Route::get('user', array('before' => 'auth', function()
{
    return 'ログイン済みだったよ';//authというフィルターを通せばログインチェックできちゃう
}));

ログイン処理自体は、次の次の投稿になる(予定の)「モデル編」辺りで解説したいと思っております。

controller

さあ、ここからがLaravel4の可愛いところです。
このルーティング方法はRESTフルコントローラと呼ばれるものなのですが、ひとまず下の簡単なコードを見てみてください。
コントローラの記述も含みますが、これを読むだけでどんなルーティングが行われているか何となく分かると思います。

routes.php

Route::controller('users', 'UserController'); //userディレクトリ以下へのアクセスはUserControllerが捌いてね

controllers/UserContriller.php

//ルーターで指定したUserControllerの中身
class UserController extends BaseController { 
    public function getIndex()
    {
        echo 'ここはインデックス';
    }

    public function postProfile()
    {
        echo 'ここはプロフィール';
    }

    public function anyLogin()
    {
        echo 'ここはログイン';
    } 
}

上記の場合、例えば
"http://www.servicename.com/user"へのアクセスしたときは
UserControllerのgetIndex()メソッドが走ります。
"http://www.servicename.com/user/login"であれば
anyLogin()メソッドです。 "http://www.servicename.com/user/profile"に直接アクセスした場合は?
コントローラに用意されたメソッドが"postProfile()"なので、getは受け付けません。つまりエラーになるはずです。

routes.phpには一行書くだけ、あとはコントローラのメソッド名だけで処理の分岐が出来てしまうお手軽さ。可愛いですね。

resource

このリソースフルコントローラは上のRESTフルコントローラと似てますが、違いは「コマンドライン上(artisan)で様々なルーティングに対応したコントローラを自動生成する」という点です。
これは大量の同じパターンのリソースを扱う処理の為に用意されたもので、具体的には画像の扱いなどが想定されているようです。

php artisan controller:make PhotoController

これでPhotoControllerクラスが作成されます。
photo/hogeというパスにアクセスされたときにこのコントローラに対してルーティングするには、

routes.php

Route::resource('photo','PhotoController');

となります。
リソースコントローラには最初から処理の雛形が用意されておりまして、例えば"/photo/show/15"だったらID=15の写真を表示する、"/photo/destroy/15"だったら破棄する、のような「ありがちな画像処理」があっという間に実装できるようになっています。
詳しい内容はリファレンスへどうぞ。

まとめ

ここに挙げた以外にも色々と便利な機能があるので、しつこいようですがさらに突っ込んだ内容はリファレンスで確認して頂きたく。やっぱり教科書には全ての基本が詰まってます。
でもここまでで紹介したパターンだけでも大抵のルーティングは出来ちゃうはずなので、併せて参考にして頂ければ幸いです。

ルーティングが出来たら次はいよいよコントローラとビューの話。次回「コントローラ・ビュー編」へと続きます。
早く続きを書きたいところですが、ごめんなさい、絶対に負けられない戦いが終わるまではしばしお待ち下さい。

mioのLaravel初心者講座 目次

Recent Entries
MD EVENT REPORT
What's Hot?