■設計
Laravelを最低限扱えるようになったら気を付けたいこと
■選択項目の管理
項目自体は設定ファイルで管理する
config\option.php
'administrator' => [
// 利用状況
'status' => [
'operation' => '運用中',
'stop' => '運用一時停止中',
],
],
ビューに表示する際はモデルを使用する
app\DataAccess\Eloquent\Administrator.php
public function getStatusLabelAttribute()
{
return config('option.administrator.status')[$this->attributes['status']];
}
■ミドルウェア
リクエストのフィルタリングとレスポンスの変更を行う
Laravel5.1以前ではコントローラでbeforeフィルターを設定するような仕様だったらしい
現在は非推奨となり、代わりにミドルウェアが推奨されている
ミドルウェア 5.4 Laravel
https://readouble.com/laravel/5.4/ja/middleware.html
Laravelでアクション実行前・後などで共通の処理をさせたいあなたに!コントローラーフィルターまとめ - Qiita
http://qiita.com/kenguy/items/321faa1bd2570a39ea35
php artisan make:middleware CheckCount
\test\app\Http\Middleware\CheckCount.php
セッションの値によって、ページの表示を制御するものとする
public function handle($request, Closure $next)
{
$count = session('count', 0);
if ($count < 10) {
return redirect('/home');
}
return $next($request);
}
\test\app\Http\Kernel.php
ミドルウェアを登録する
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
〜略〜
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'count' => \App\Http\Middleware\CheckCount::class, // ←追加
];
\test\routes\web.php
ルーティングでミドルウェアを呼び出す
// ルートプレフィックス
Route::prefix('/admin')->group(function () {
Route::get('/session', function () {
$count = session('count', 0);
return 'Admin count=' . $count;
})->middleware('count');
});
Kernel.php の $routeMiddleware に登録すると、ルーティングから必要に応じてミドルウェアを呼び出せる
Kernel.php の $middleware に登録すると、すべてのルーティングに対して自動的に実行される
■サービスコンテナ
Laravelでは以下のようなコードが頻繁に登場する
これだけでEntryServiceクラスのオブジェクトが $entry に入る。newを書かなくてもいい
public function __construct(EntryService $entry, CommentService $comment)
{
$this->entry = $entry;
$this->comment = $comment;
}
大まかな仕組みとしては、リフレクションを使用して自動でクラスを判断し、展開したものを自動で渡すようになっているみたい
以下では、個別にサービスコンテナを設定する方法などをまとめる
サービスコンテナ - ララ帳
https://laravel10.wordpress.com/tag/%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%82%B3%E3%83%B3%E3%83%86%...
サービスコンテナ
https://readouble.com/laravel/5.4/ja/container.html
LaravelのDIコンテナはどう使われているのか - 新人Webエンジニアの記録。
http://blog.fagai.net/2016/09/17/laravel-dependency-injection/
\test\routes\web.php
interface SenderInterface {
public function send($message);
}
class MailSender implements SenderInterface {
public function send($message) {
return "メールで $message を送りました。";
}
}
class BikeSender implements SenderInterface {
public function send($message) {
return "バイク便で $message を届けました。";
}
}
class Messenger {
protected $sender;
public function __construct(SenderInterface $sender) {
$this->sender = $sender;
}
public function send($message) {
return $this->sender->send($message);
}
}
//App::bind('sender', 'MailSender'); // DIコンテナにバインド
//App::singleton('sender', 'MailSender'); // シングルトンとしてDIコンテナにバインド
//$instance = new MailSender();
//App::instance('sender', $instance); // インスタンスをバインド
App::bind('SenderInterface', 'MailSender');
Route::get('send/{message?}', function(Messenger $sender, $message = '合格通知') {
//$sender = new BikeSender(); // 通常のクラス作成
//$sender = App::make('sender'); // DIコンテナから取得
//$sender = App::make('MailSender'); // DIコンテナから取得
//$sender = App::make('Messenger');
return $sender->send($message);
});
■DIとサービスコンテナの使い分け
Dependency Injection と Service Container (Service Locator) の使い分け
https://qiita.com/nunulk/items/2c637d3952096ef74677#2-dependency-injection-%E3%81%A8-service-contain...
2.3. 使い分け
コンストラクタインジェクションやメソッドインジェクションを使えば、
依存オブジェクトを引数として表現できるので、できるだけこちらを使った方がいいと思います。
サービスコンテナは便利な反面、どこからでもアクセスできてしまうので、
気をつけないと依存オブジェクトがどんどん増えてしまう恐れがあります。
サービスコンテナを使う場合でも、依存オブジェクトが多くなってきたな、と思ったら、
集約 (Aggregate) パターンを新たに作るなどして、依存関係を減らすように努めると、設計も洗練されて行くんじゃないかと思います。
■サービスプロバイダ
要勉強
サービスコンテナへのバインド処理で利用する機能をサービスプロバイダと呼ぶ
コントローラなどでは処理をクラス名で呼び出さずにコントラクト(インターフェース)をもとに呼び出し、サービスプロバイダ内で実際のクラスメイトコントラクトを紐付ける
これにより、サービスプロバイダ内の処理を変更するだけで処理の差し替えができる
サービスの初期処理(命令の初期起動処理)を行う
サービスプロバイダーとは - ララ帳
https://laravel10.wordpress.com/2015/04/22/%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%83%97%E3%83%AD%E3...
サービスプロバイダー 5.4 Laravel
https://readouble.com/laravel/5.4/ja/providers.html
Laravel5でカスタムライブラリ使いたい - Qiita
http://qiita.com/zaburo/items/e8e786624f88c253c87d
■イベント
要勉強
Laravelが様々な処理実行時にイベントを発行するため、
必要に応じてフックして処理を差し込むことができる
例えば illuminate.query はデータベースにクエリを発行したあとに発生するイベント
イベント 5.4 Laravel
https://readouble.com/laravel/5.4/ja/events.html
■ブロードキャスト
要勉強
websocketを利用して、ブラウザにイベントを通知するなど、リアルタイム性のあるアプリケーションを作れる
サーバサイドだけで完結せず、JavaScriptも関連する
ブロードキャスト 5.4 Laravel
https://readouble.com/laravel/5.4/ja/broadcasting.html
■フォームリクエストによるバリデーション
フォームリクエストを作成
php artisan make:request StoreArticlePost
\test\app\Http\Requests\StoreArticlePost.php
public function authorize()
{
return true;
}
public function rules()
{
return [
'subject' => 'required|max:255',
'detail' => 'required|max:255',
];
}
\test\app\Http\Controllers\ArticleController.php
use App\Http\Requests\StoreArticlePost;
public function store(StoreArticlePost $request)
{
/* リクエストが正しければここが実行される */
}
バリデーションと専用の項目名は、フォームリクエストで定義する
\test\app\Http\Requests\StoreArticlePost.php
汎用的に使われる項目名は、以下のファイル内にある「attributes」で設定する
モデルごとの特別な項目名は、各フォームリクエストで設定や上書きをする
\test\resources\lang\ja\validation.php