new takyam();

Qiitaぽい話はQiitaに書いていくことにする気がする http://qiita.com/takyam

Laravel 4 first impression

表題の通り、今最も熱いと噂のPHPフレームワーク「Laravel」を触ってみました。

LARAVEL 4 HAPPY HACKING
http://www.slideshare.net/takashiohida/laravel4

こちらの資料を拝見する限り、FuelPHPよりイケてるんじゃないかという気がしたので、ほんの少しだけ触ってみました。いくつか気になったところとか、メモメモ。

Routing

FuelPHPはControllerとController内のメソッド名に関する規約が定義されており、URLがそれに沿った形になるので、ルーティングする必要がありません。
一方Laravelは、Railsその他一般的なフレームワークと同様、ルーティングファイルを元に、URLとコントローラを関連付けていくようです。
個人的にはURLに対する自由度が低くなるけど、規約で強く束縛されるのでトンチキになりにくいFuelPHPの方式のほうが好きかなぁという気はしてますが、ぶっちゃけどっちでも良いレベル。

<?php
//GETとPOSTでメソッドを分けるパターン
Route::get('/hoge/create', 'HogeController@createGet');
Route::post('/hoge/create', 'HogeController@createPost');
//GETとPOSTで同一メソッドを参照させるパターン
Route::any('/hoge/create', 'HogeController@create');
//RESTfulなコントローラのパターン
Route::controller('hoge', 'HogeController');

みたいな感じで、「どのコントローラのどのメソッド」を指定してく、普通な感じです。
Laravel4で作ったぽい簡易CMSルーティングファイルを見ると、機能なんてほとんど無いにも関わらず80行くらいにはなってたので、やっぱこの方式だと糞長いルーティングファイルが出来上がるんじゃないかという懸念はある。

参考:https://github.com/Zizaco/zizaco_net/blob/master/app/routes.php

GETとPOST以外にもPUTとDELETEも対応していて、擬似HTTPメソッド(name="_method")にも対応してるっぽいので、RESTfulなアプリケーションはFuelPHPより作りやすいと思う。FuelPHPは擬似HTTPメソッドに対応していので。

Model

DB周りは割と普通。DB::select()みたいな感じのとかDB::table()->where()とか。本当に特に特筆すべきところが無いくらい普通。なので問題無し。

ORMについては、Eloquent ORMと呼ばれるLaravel用?のORMが使われてるっぽい。いくつか良さげな機能があったのでご紹介。

findOrFail() && ModelNotFoundException

基本的にはHoge::find(1);みたいにfind()メソッドでSELECTするっぽいんですが、それを拡張したHoge::findOrFail(1);のように使うfindOrFail()メソッドがある。

これ何かっていうと、モデルの対象が見つからなかった時にModelNotFoundExceptionがExceptionされるらしくて、「モデルが見つからなかった時の動作」を定義しておけるらしい。

ドキュメントの例だと、モデルが見つからなかったらNotFoundページを返す、とか。

<?php
use Illuminate\Database\Eloquent\ModelNotFoundException;
App::error(function(ModelNotFoundException $e)
{
    return Response::make('Not Found', 404);
});

fillable && guarded

Modelを生成する時のコンストラクタにパラメータを渡す事で、生成時にパラメータがモデルにセットされたかたちになるんですが、それをある程度制限するのがfillableguarded
それぞれprotectedパラメータで、配列でプロパティを指定します。

たとえば、Hogeモデルがfugaプロパティとpiyoプロパティを持ってた場合に、fillablepiyoが設定されてるとすると、Hogeモデルのコンストラクタにfugapiyoの両方を渡したとしてもpiyoしかセットされない、といった感じらしいです。

コンストラクタの設定パラメータを「ホワイトリスト」として定義するのがfillableで、その逆の「ブラックリスト」として定義するのがguardedのようです。fillableguardedのどっちが優先されるかは知らんですw

ぷち便利機能かなと思います。

query scope

Query Scopeって機能があります。 WHEREをスマートに使いまわすための機構といった感じでしょうか。
WHEREの条件をArrayで定義して、それを返すメソッドを使いまわすというのが、FuelPHPのORMの限界ですが、それをかなりスマートな感じで表現する事ができます。

まずはFuelPHPの場合。

<?php
class Model_Hoge extends \Orm\Model{
    protected static function get_hoge_where_array($number){
        return array(array('fuga', '>', $number));
    }
    
    public static function get_hoge($number){
        return static::find('all', array('where' => static::get_hoge_where_array($number)));
    }
    
    public static function get_hoge_count($number){
        return static::count(array('where' => static::get_hoge_where_array($number)));
    }
}

FuelPHPでやれる事つったらこんなもんです。これがLaravelの場合、Query Scopeを使う事で超キレイになります。

<?php
class Hoge extends Eloquent {
    public function scopeHoge($query, $number){
        return $query->where('fuga', '>', $number);
    }
    public static function get_hoge($number){
        return static::hoge($number)->get();
    }
    public static function get_hoge_count($number){
        return static::hoge($number)->count();
    }
}

みたいに、「クエリビルダに設定できるアレやソレ」をまとめておく事ができるんすね。 なので、別にWHEREだけじゃなくてORDER_BYやら何やかんや、まとめておけると。素敵やーん。

その他

  • 論理削除(soft-delete)をサポート。まともな設計だといいなぁ・・・。FuelPHPの論理削除は糞仕様だから・・・。
  • リレーションも普通。特に何か変なとこは無いんじゃね?

View

Bladeという独自?のテンプレートエンジンを使ってる。そんな仰々しく無いので、テンプレートエンジンとしては好きな部類。ただ、PHPでテンプレートエンジン使うのは、好きじゃないので、キモい。

View自身がテンプレート側に影響を与える処理をViewからできるのもキモい。が、親のレイアウトを定義してるViewは、子のView側が読んでて、親側はyieldしてるだけ、っていうこのデザインは嫌いじゃない。それを楽に実現するためのBladeってのもわかる。わかるが、若干のキモさは残る。

まぁ、テンプレートエンジン側がキャッシング処理をまるっと面倒見てくれるならいいんだけどねー・・・。

IoCコンテナ

個人的にはDIコンテナって名前の方がしっくりくるけど、コレがコア含めて全体でキレイに利用されているらしい。

コアのソース読んでないけど、勉強になるだろうなぁと期待中。
ファサードっていうstaticのための機構も含まれてるようで素敵。

正直DIコンテナの有用性をテストの時にモック使いやすくなる、くらいにしか理解できてないけど、それだけで充分に学習する価値があるレベルだと踏んでる。

TDD

Laravel公式サイトのトップに次のような事が書いてある。

Red, Green, Refactor

Laravel is built with testing in mind. Stay flexible with the IoC container, and run your tests with PHPUnit. Don't worry... it's easier than you think.

(拙訳)

レッド、グリーン、リファクタリング

Laravelはテスト志向に作られています。IoCコンテナにより柔軟性を保ち、PHPUnitでテストします。心配しないで、それはあなたが思うよりも簡単です。

いやまぁ実際、ドキュメント読むかぎりかなり「テストしやすい」作りになってます。
DOMのテストも標準で対応してるみたい。

いやもうこのテスト周りだけ見ても、FuelPHPから乗り換えたい気持ちでプルプルしちゃいますよ。

ディレクトリ構成

ディレクトリは割と好きに分割できるっぽいので特に問題なしっす。

サンプルだとHogeControllercontrollers/HogeController.phpとして作りましょうみたいなのしか見ませんでしたが、普通にPSR-0っぽくcontrollers/Hoge/FugaController.phpHoge_FugaControllerクラスを作ってあげればそれ参照するっぽかったので、特に問題なっしんです。


まとめ

というわけで、ザックリLaravel4のドキュメントを読みながら気になったところをピックアップしてみました。

最終的に思ったのは「日本語ドキュメントが素晴らしい」という事w
翻訳超頑張ってんなーという印象。

翻訳追いついてないところあると嫌なので、英語の公式ドキュメント読みながら、躓いたところだけ日本語訳を見る、ってかたちを取ったのですが、最終的に日本語ドキュメントだけ読めばいいじゃん状態。まじすごい。

それはそれとして、Laravel本当に良いわぁと思いました。

感覚的にはSymfonyほどガッチガチじゃなくて、FuelPHPよりも練られてるフレームワークという印象。
FuelPHPに多少失望してるところもあったりして、隣の芝生が青く見えてるだけかもしれませんが、次作るならLaravelで作ってみたいと素直に思わせてくれた良フレームワークだと思います。

TDDやらないんだったら、FuelPHPのほうが「お手軽」な印象はありますが、FuelPHPは現バージョンではTDD捨てられてるのでオススメできませぬ・・・。

しかもジャスト今日(日付代わったから正確には昨日)、こんな本も出版されてるみたいっす。

Laravel Testing Decoded (JP)
待望のLaravel 4ユニットテスト解説本
https://leanpub.com/laravel-testing-decoded-japanese

素敵すぐる。日本語訳してくれてる方々に感謝の限りを尽くしたいところです。

というわけで、週末はLaravelで遊べればと思ってますので、
もう少し使ってみて気になったところとか見えてきたら何か書きます。