Edited at
LaravelDay 1

Laravel5 route, event アノテーション

More than 3 years have passed since last update.


annotationは本体から切り離されて、3rdパーティと変更されました。

アノテーションパッケージ


Laravel5の状況

本題に入る前に現在の状況ですが、

チェックしている方はご存知の通り Laravel5は2015年1月リリースの可能性が高く、

すぐに情報が古くなる場合もあります

また現時点(2014/12/01)ではβ版はありませんが、

開発版をインストールして5の現時点の状態で使用する事が可能です

手軽に使う分にはそこまで大きく変わりませんが、

Laravelパッケージ開発者や、コアを熟知している中級者や上級者の方々は、

4よりもさらに便利に、より拡張し易い方向へと変わっています

それでは、5で追加されたルーティングとイベントのアノテーションを!


Laravel5 install

インストール方法はいくつかありますが、いつもと同じ方法で開発版をインストールする事が出来ます

$ composer create-project laravel/laravel プロジェクト名 --prefer-dist dev-develop

php artisan serveは削除された様なので、簡単に起動させたい場合は

$ php -S 127.0.0.1:8000 -t 'public/'

と、ビルトインサーバを立ち上げるだけです

実行環境の指定方法が変更されましたので、

プロジェクトルートの .env.sample.envにリネームする等してください

中に記述されているAPP_ENV=localで実行環境を変更する事が出来ます

(もちろんこれまでと同じ方法でも可能です、ソースコードを読んでみてください)


Laravel5 Router


スタンダードなrouter

今まで通りルーティングはroutes.phpに記述していくことができます

インストール時にすぐに動く様にいくつかルーティング記述されています

ファサードでの記述ではなくなりましたが、この辺りは後日誰かが書くはず・・!


app/Http/routes.php

$router->get('/', 'WelcomeController@index');

$router->get('/home', 'HomeController@index');

$routerは\Illuminate\Routing\Routerオブジェクトで特に変わりませんが、

サービスプロバイダで自由に色々実装できる様に拡張されました

app/Providers/RouterServiceProvider.phpがそれです

コントローラーの名前空間はデフォルトで下記の様に記述されています

protected $namespace = 'App\Http\Controllers';

に記述する事で省略して記述できますが、特に使わなくてもかまいません

使わない場合はこれまでのgroupでの指定と同じです


app/Http/routes.php

$router->group(['namespace' => 'App\Http\Controllers'], function($router) {

$router->get('/', 'WelcomeController@index');
$router->get('/home', 'HomeController@index');
}
);


アノテーション利用のrouter

ではアノテーションを利用してルーティングを作ってみます

app/Http/routes.phpに記述したものはコメントアウトしておきます

$ php artisan route:list

何も表示されない事を確認、もし表示されていればcompileされたファイルがあるはずなので、

$ php artisan clear-compiled

またはstorage/framework/compiled.phpを削除します

ルーティングで利用可能なアノテーションは

Illuminate\Routing\Annotations\Annotationsにあります

アノテーション
該当するもの
対象

@Controller
$router->controller()
クラス

@Resource
$router->resource()
クラス

@Middleware
filter処理等
クラス・メソッド

@Where
whenに該当 
クラス・メソッド

@Get
GET
メソッド

@Post
POST
メソッド

@Put
PUT
メソッド

@Patch
PATCH
メソッド

@Delete
DELETE
メソッド

@Options
OPTIONS
メソッド


メソッドに記述する例

シンプルなGet, Postなどのを利用してみます


app/Http/Controllers/SampleController.php

namespace App\Http\Controllers;

class SampleController extends Controller
{
/**
* @Get("sample")
* @return string
*/

public function sample()
{
return "sample";
}
}


sampleメソッドをGETの処理で使う様にアノテーションで指定します

URIは/sampleとなります

それから、先ほどのapp/Providers/RouterServiceProvider.phpに次の様に追加します


app/Providers/RouterServiceProvider.php

    protected $scan = [

'App\Http\Controllers\SampleController'
];

次にControllerのアノテーションをスキャンして、ルーティングを自動で作成します

$ php artisan route:scan

storage/framework/routes.scanned.phpファイルが作成、または元からある方は追記されます

$router->get('sample', [

'uses' => 'App\Http\Controllers\SampleController@sample',
'as' => NULL,
'middleware' => [],
'where' => [],
'domain' => NULL,
]);

ブラウザなどからアクセスしてsampleと表示されるか確認してみましょう!

spring frameworkのbeanファイルのルーティング版の様なものですね

なおスキャンをしなくても、

app/Providers/RouterServiceProvider.phpに下記のプロパティを有効にすると

自動で追加される様になります!

protected $scanWhenLocal = true;

他のPost等も基本的には同じです

次にフィルターやルーティングに名前を付けていってみましょう

最初から登録されているフィルター(middleware)は

app/Http/Kernel.phpにあります ここではauthを使ってみる事にします

きっと誰かが詳細書いてくれるはず・・!

    /**

* @Get("sample", as="sample", middleware={"auth"})
* @return string
*/

public function sample()
{
return "sample";
}

再度scanを実行してroute:listで確認してみます



ブラウザからアクセスすると、ログイン画面に遷移されます(用意されていないのでエラー画面のはず)

middlewareとwhenは配列でいくつでも指定できます

    /**

* @Get("sample/{id}", as="sample", middleware={"auth"}, where={"id": "[0-9]+"})
* @param $id
* @return string
*/

public function sample($id)
{
return "sample";
}

引数を必須として、且つ数字以外は利用できないルーティングの場合はこの様になります

またこれまであったdomainも利用できますので、同じ様に追加するだけで指定が可能です

    /**

* @Get("sample")
* @Middleware({"auth"})
* @param $id
* @return string
*/

public function sample($id)
{
return "sample";
}

さらにMiddlewareとWhereは個別に記述する事も可能です


クラスに記述する例

いままでのResourceコントローラーと同様に指定してみます

namespace App\Http\Controllers;

/**
* @Resource("sample", only={"index"}, names={"index": "index.name"})
*/

class SampleController extends \App\Http\Controllers\Controller
{

public function index()
{
return "sample index";
}

}

URIが/sampleでそれぞれのメソッドがルーティングに登録されますが、

onlyでindexのみ利用する様に指定し、

nameは指定しない場合はsampleをprefixに自動で付与されますが、

名前を任意で指定しました

さらに@Controllerアノテーションでprefixを付与させたり、

実行するdomainを指定します

/**

* @Resource("sample", only={"index"}, names={"index": "index.name"})
* @Controller(prefix="api", domain="app")
* @Middleware({"auth"})
*/

class SampleController extends \App\Http\Controllers\Controller
{

}

メソッドにもさらに記述して様々なルーティングを作る事が出来ます

他にも色々あり、自分でアノテーションを追加する事も出来ますが、

まだイベントについても書いてないのでまた次回に・・


ルーティングを共存

複数人のチームで開発している場合は、アノテーションだけだと分かり辛い場合もあります

開発者の好みによってアノテーション有無の両方のルーティングを混ぜて使う事が出来ますので

routes.phpを削除しなければならないとか、そういう事はありませんが、

アノテーションを使ったルーティングが優先されます

またこれらのルーティングはroute:cacheでキャッシュする事も出来ますが、

書くと長くなるのでこの辺で・・


Laravel5 event annotation

routerに比べれば遥かにシンプルです

app/Providers/EventServiceProvider.phpにデフォルトのサービスプロバイダーがあります

routerと同じ様にannotationを利用するので、scanで配列を使います

ファイルはどこに作っても構いませんので、簡単なクラスを作ってみます


app/Listener/SampleListener.php

namespace App\listener;

class SampleListener
{

/**
* @hears("accessEvent")
*/

public function access()
{
echo "access";
}
}


ただ単に文字列を返却するだけのシンプルなeventです

@hearsでイベント名を付けます

それでは同様にscanにクラスを追加するので

app/Providers/EventServiceProvider.php

class EventServiceProvider extends ServiceProvider

{

protected $scan = [
"App\Listener\SampleListener"
];

}

スキャンコマンドは

$ php artisan event:scan 

です

実行後にevent.scanned.phpに追記されているのを確認します

もちろんrouterと同じ様に自動で追記することもできます

$events->listen(array (

0 => 'accessEvent',
), 'App\listener\SampleListener@access');

先ほど利用したcontrollerを利用します

namespace App\Http\Controllers;

use Illuminate\Contracts\Events\Dispatcher;

class SampleController extends Controller
{

/**
* @Get("sample")
* @return string
*/

public function sample(Dispatcher $event)
{
$event->fire('accessEvent');
}
}

折角なのでファサードを使わずにメソッドインジェクションでDispatcherを指定して

fireでイベントを起こします

ブラウザからアクセスすると

accessと表示されているはず!

複数の名前をつける事も出来ますので色々遊ぶ事ができます

    /**

* @hears({"accessEvent", "sample.event"})
*/

public function access()
{
echo "access";
}

それぞれの機能については実装されているコードに記載されていますので、

色々試してやりやすい実装方法でルーティングなどを作りましょう!