何この記事?
アプリケーションコード中の任意の場所で、「管理画面だった」「APIだったら」「特定のディレクトリ配下だったら」といった、URLによって条件分岐をしたい場合、Laravel的にどうするのがいいのか?を考えた足跡です。
// 管理画面の場合だけメッセージを出したい
if( CurrentUrl() == '/admin' ){
ShowMessage('エラーです');
}
結論
URLは使わない
いきなり全否定してすみませんが、URLは使わないでください。
でも使うとしたらこんな感じ。
// URLのディレクトリが /admin で始まる場合
if( strpos(\Request::path(),'admin/')===0 ){
// 常にデバッグモードでLaravel標準エラー画面を表示
config(['app.debug' => true]);
return parent::convertExceptionToResponse($e);
}
書いたのはワタクシですが……。@エラー画面のレンダリング条件を追加する
使うな!って言っておいてあれですが、こうするともっとエレガントです。
if (\Request::is('admin/*')) {
Routeを使う
Laravelでは、URLやページ構成をすべて「ルーティング」で管理しているので
こういった要件には「ルーティング」を使うのが定石です。
上記コードはこのように置き換えできます。
// route名が admin. で始まる場合
if (\Route::is('admin.*')) {
// 常にデバッグモードでLaravel標準エラー画面を表示
config(['app.debug' => true]);
return parent::convertExceptionToResponse($e);
}
ちなみに、しれっとワイルドカードが使用できましたが、これはLaravelのStrクラスの機能です。
自分のコードの文字列判定にも使えるので覚えておくと便利ですよ。
use Illuminate\Support\Str;
if( Str::is( 'laravel*', 'laravel framework' ) ){ // true
解説
「URL判定する」という要件はよくあるのですが、そこで素直に「URLを文字列判定しよう」とか「今のURLってどう取得するんだっけ?」と発想していくのはそろそろやめませんか?という提案です。なぜなら、URLはHTTPという外部世界に依存したとても具体的な世界で、自分たちの全く力の及ばないところでコロっと変更を強いられることがあるからです。それに同じURLでも、リクエストメソッドによって全く別の処理をしているのはLaravelでなくてもふつうの話。
「やばい!URLの /admin が一般的すぎてDOS攻撃を受けている。/secretAdmin5545 に変更しておいて」
「この /Post って大文字のURL、カッコ悪い※から /post にしておいて。あと複数形 /posts がいいな」
「/post/9999 にPOSTでアクセスしてきたときだけこのメソッド通して」
※「カッコ悪い」と感覚的な評価ありえない…と冗談っぽく書きましたが、重要なのは「人目にさらされている」ことです。エンドユーザーが見る、使う、広告媒体にもどーんと載るのがURLなので見た目の要求が出てくることがあります。ルート名ならカッコ悪くても内部でしか使わないのでそうした要求は起きない、と言いたいのです。
そんな細かな要求に、毎回URLの文字列判定と、リクエストメソッドの判定を書くのは疲れました。
METHOD | URL | ルート名 |
---|---|---|
GET/HEAD | / | home |
GET/HEAD | /posts | posts.index |
POST | /posts | posts.store |
GET/HEAD | /posts/create | posts.create |
GET/HEAD | /posts/{id} | posts.show |
PUT | /posts/{id} | posts.update |
Laravelさんは、URLとメソッドの組み合わせを、アプリケーション内で一意の文字列「ルート名」で管理しているので、
ルート名と仲良くなって、一枚上手なURL管理方法を手に入れましょう(^^)
ちなみに、URLを書く場合は、route()
ヘルパ関数を使います。url()
はもう使わないでね。