【Laravel】ルーティングで渡されたパラメータのフォーマットを正規表現でおしゃれに指定する方法

Laravel How to Set RegExp for RoutingLaravel Laravel
記事内に広告が含まれていることがあります。
[PR]

Laravelのルーティングでは、/user/{name}/user/{user-id} のように入力されたURL(URI)の一部をパラメータとして取得することができます。(Laravelでは{ } の中で受け取るデータをパラメータと呼びます)

このとき、渡されたパラメータが指定したフォーマットの場合だけルーティングを適用する設定にすることができます。

この設定を、ルーティングファイル(web.php)の上部で正規表現を記載した変数を定義して行うとシンプルに記述することができます

ここでは、正規表現でフォーマットを指定する基本的な方法と、ルーティングファルの冒頭で変数で指定するおしゃれな方法について紹介しています。

ルーティングで受け取ったパラメータのフォーマットを指定する方法

まずは、一般的な方法から解説します。大きく2つの方法があります。

  1. 正規表現を使ってフォーマットを指定する。
  2. ヘルパメソッドを使って指定する。

正規表現を使ってフォーマットを指定する方法

正規表現を使ってパラメータのフォーマットを指定するには、 whereメソッド を使います。

次のように、Routeでいつものようにルーティングを記述した後に、 ->where をつけて、対象となるパラメータ名と正規表現を指定します。

パラメータが1つの場合

Route::get('/user/{パラメータ名}', function ($変数名) {
    処理
})->where('パラメータ名', '正規表現');
point
  • パラメータとして受け取ったデータが、後ろに続く関数や、コントローラのアクションの引数に変数に渡されます。
  • パラメータはURIの順番に関数の引数に渡されます。
  • 関数の中でパラメータを使わない場合は、引数の中で変数を宣言しなくても問題ありません。(エラーにはなりません)

パラメータが複数の場合

パラメータが複数ある場合は whereメソッドの引数を配列にし、Key Value(連想配列)の形で記述するか、whereメソッドをつなげることで指定できます。

Route::get('/user/{パラメータ1}/{パラメータ2}', function ($変数名1, $変数名2) {
    処理
})->where( ['パラメータ1'=>'正規表現', 'パラメータ2'=>'正規表現' ]);
Route::get('/user/{パラメータ1}/{パラメータ2}', function ($変数名1, $変数名2) {
    処理
})->where( 'パラメータ1', '正規表現' )
->where( 'パラメータ2', '正規表現' );

実例1: 1つの変数にのみフォーマットの制限をかける場合

use App\Http\Controllers\UserController;

Route::get('/user/{name}/{testId}', [ UserController::class, 'userShow'] )
->where( 'name'=>'[A-za-z]+' );

URLから、nameとtestIdの2つのパラメータを受け取っています。

パラメータnameについてはアルファベットのみのフォーマット制限をかけています。
[A-za-z]+ は、大文字のアルファベットか小文字のアルファベットの1回以上の繰り返しです。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class UserController extends Controller
{
    public function userShow( Request $request, $name, $id ){
        return "Your name is " . $name . "!!! ID: " . $id;
    }
}

UserControllerを定義して、ルーティングから受け取ったパラメータ $nameと$idを使って文字列を返しています。

point
  • ルーティングのURIに { } を使うとそこで入力された値がコントローラのアクションの引数に渡されます。
  • { }の中のパラメータ名にハイフンは使えない。キャメルケースで指定すること。
    • NG: test-id
    • OK: testId
  • 渡される順番は記載の順番です。
  • アクションの引数名とルーティングの{ } の中のパラメータ名は関係ありません。(※名前が一致しているかではなく、記載の順番が大切です)
  • Request $requestはメソッドインジェクションで、リクエストを変数$requestに格納しています。

以下のようなURLを入力すると、ルーティングが問題なく機能します。

http://127.0.0.1:8000/user/Danny/test-1123

http://127.0.0.1:8000/user/Danny0123/test-1123

一方で、nameの部分に数値や日本語などフォーマットで指定したアルファベット以外の文字を使うとルーティングが適用されません。(ここではそのルートを定義していないので404ページに飛びます)

実例2: 複数のパラメータにのみフォーマットの制限をかける場合

複数のパラメータに対してフォーマットの指定をかける場合は、連想配列にして記述するか、whereメソッドをつなげることで指定することができます。

以下の例であれば、nameはアルファベットのみ、testIdの部分は冒頭に test- という文字列がつき、後ろに1~5桁までの数値がつく設定です。

それ以外は、ルーティングに該当しない設定となります。

use App\Http\Controllers\UserController;

Route::get('/user/{name}/{testId}', [ UserController::class, 'userShow'] )
->where( ['name'=>'[A-za-z]+', 'testId'=>'^test-[0-9]{1,5}'] );
use App\Http\Controllers\UserController;

Route::get('/user/{name}/{testId}', [ UserController::class, 'userShow'] )
->where( 'name', '[A-za-z]+' )
->where( 'testId', '^test-[0-9]{1,5}' );


ヘルパメソッドを使って指定する方法

続いてLaravelがデフォルトで用意しているヘルパメソッドを使う方法です。以下のヘルパメソッドを使うことができます。

ヘルパメソッド内容
whereNumber数値
whereAlphaアルファベット
whereAlphaNumeric数値とアルファベット
whereUuidUUID

使い方は、 ->whereNumber(‘パラメータ名’) のように指定します。

Route::get('/user/{id}/{name}', function ($id, $name) {
    //
})->whereNumber('id')->whereAlpha('name');

Route::get('/user/{name}', function ($name) {
    //
})->whereAlphaNumeric('name');

Route::get('/user/{id}', function ($id) {
    //
})->whereUuid('id');

web.phpの上部で正規表現を記載した変数を定義する方法

これまでは、ルーティング毎にwhereメソッドでフォーマットを指定しましたが、これらの正規表現をファイルの上にまとめて変数としてシンプルに使うことができます。

変数名には、 $regexs を使います。

$regexs は正規表現の英語表現である Regular expression の複数系です。複数系にしているのは連想配列として複数の正規表現を格納するためです。

これを使って記述すると以下のようになります。

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\UserController;

$regexs['name'] = '[A-za-z]+';
$regexs['id'] = '^[0-9]+';
$regexs['testId'] = '^test-[0-9]{1,5}';


Route::get('/user/{name}/{testId}', [ UserController::class, 'index'] )
->where( ['name'=>$regexs['name'], 'testId'=>$regexs['testId']] );


whereメソッドの記述がシンプルになりました。

それだけといえばそれだけですが、少しだけおしゃれになりました。

参考リンク

タイトルとURLをコピーしました