Help us understand the problem. What is going on with this article?

Laravel5 route, event アノテーション

More than 5 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/'

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

実行環境の指定方法が変更されましたので、
プロジェクトルートの .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で確認してみます
route:list.png
ブラウザからアクセスすると、ログイン画面に遷移されます(用意されていないのでエラー画面のはず)
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";
    }

それぞれの機能については実装されているコードに記載されていますので、
色々試してやりやすい実装方法でルーティングなどを作りましょう!

ytake
著: Laravelリファレンス(インプレス) Laravelエキスパート養成読本(技術評論社) PHPフレームワーク Laravel Webアプリケーション開発 バージョン 5.5 LTS対応(ソシム)
https://blog.ytake.jp.net/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした