Laravel ルーティングについて
作成日:2019-03-25, 更新日:2024-03-08
基本
FuelPHPと違って結構面倒な感じ。
▼ざっくり3種。
・ルーティングと同時に出力内容を記載(クロージャー)
・ルーティングでコントローラーを呼びだす
・ルーティングでビューを呼びだす
※「routes/web.php」に記載
ルーティングと同時に出力内容を記載(クロージャー)
▼ブラウザで「/hello」を叩くと「hello world」が表示される
Route::get('hello', function () {
return 'hello world';
});
ルーティングでコントローラーを呼びだす
▼ブラウザで「/hello」を叩くと「コントローラー:HelloController」の「アクション:index」を実行
Route::get('hello', 'HelloController@index');
※「コントローラー:HelloController」は「app\Http\Controllers\HelloController.php」
→コントローラーでビューを呼び出したりする。
ルーティングでビューを呼びだす
▼ブラウザで「/hello」を叩くと「ビュー:resources\views\hello.blade.php」を表示(実行)
Route::view('hello', 'hello');
※「Route::get()」じゃなく「Route::view()」になる
ルーティング時に値を渡したい
・「hello/〇〇〇」で「〇〇〇」を渡したい
→適当な文字列を「{}」で囲む。囲んだ文字列を引数で受取る
※コントローラを呼び出すときも同じ感じ
Route::get('hello/{name}', function ($name) {
return 'hello ' . $name;
});
※「hello/」でアクセスがあったら値が無いので「404」になる。
※「{name}」を「$name」で受取っているけど単語の関連性は見やすさのみ。
▼「{name}」を「$name」じゃなくて別の変数名で受取る
Route::get('hello/{name}', function ($hoge) {
return 'hello ' . $hoge;
});
▼複数の値を受け取る
Route::get('hello/{name}/{age}', function ($name, $age) {
return 'hello ' . $name . ':' . $age;
});
▼どこに値をセットさせても大丈夫っぽい
Route::get('hello/{name}/home', function ($name) {
return 'hello ' . $name;
});
▼コントローラを呼び出すとき
■ルーティング
Route::get('hello/{name}', 'HelloController@index');
■コントローラ
class HelloController extends Controller {
public function index($name) {
}
}
値が無くてもOKにしたい
・「hello/〇〇〇」でも「hello/」でもOKにしたい
→「{}」の中を「?」で終わらせる
Route::get('hello/{name?}', function ($name='everone') {
return 'hello ' . $name;
});
※引数で初期値をセットせずに「/hello」でアクセスするとエラーになる。
値を正規表現で指定
・「Route::get()」に「where()」を追加(正規表現で指定)
※条件に合わない場合は「404」
▼「a~z」だけで構成されている場合
Route::get('hello/{name}', function ($name) {
return 'hello ' . $name;
})->where('name', '[a-z]+');
※「^」「$」は必要ないみたい
※前述の「{name?}」と値が無くてもOKとしていると正規表現が無効になるっぽい。
使いそうなのは・・・
・数字のみ - where(〇〇〇, '[0-9]+')
・任意の文字と数字 - where(〇〇〇, 'post_[0-9]+')
・任意の文字と数字(8桁) - where(〇〇〇, 'news_[0-9]{8}')
・特定の単語のみ - where(〇〇〇, '(hoge|foo)')
▼複数あるとき
Route::get('hello/{name}/{age}', function ($name, $age) {
return 'hello ' . $name . ':' . $age;
})->where([
'name' => '[a-z]+',
'age' => '[0-9]+'
]);
「app\Http\Controllers」直下じゃなくて「app\Http\Controllers\〇〇〇」の下のコントローラーを使いたい
・「app\Http\Controllers\HelloController.php」ではなくて、
・「app\Http\Controllers\Zebra\HelloController.php」としたい。
▼ルーティング
Route::get('hello/{name?}', 'Zebra\HelloController@index');
▼コントローラー(app\Http\Controllers\Zebra\HelloController.php)
<?php
//namespace App\Http\Controllers;
namespace App\Http\Controllers\Zebra;
略
//class HelloController extends Controller {
class HelloController extends \App\Http\Controllers\Controller {
以下、略
※「use App\Http\Controllers\Controller」とかしたほうがいいんだろうけど「use」が好きになれないので継承時に絶対PATH指定
ルーティング内でリダイレクト
▼「/hoge」でアクセスがあったら「/foo」に301リダイレクト
Route::redirect('/hoge', '/foo', 301);
※使わなくなったページやメンテ中のページなどで使えそう。
コントローラーからリダイレクト
後述の「名前付きルート」参照。
名前付きルート
▼ルーティングで名前をつけておく
//// 名前付きルーティング
//route::get(〇〇〇, 〇〇〇)->name('profile');
// URLの生成してリダイレクト
$url = route('profile');
return redirect()->route('profile');
//// パラメータを付けたURLの生成
//Route::get('user/{id}/profile', function ($id) {
// //
//})->name('profile');
$url = route('profile', ['id' => 1]);
ルーティングでグループ化
ルーティングの記述をネストさせたい。
▼いくつか種類がある
・middleware - ?
・namespace - namespaceを使う
・domain - サブドメインを使う
・prefix - URLを使う
・name - ?
domaineでグループ化
例えば、サブドメインで見せたい・見せたくないページを指定したい。
▼「kushi.example.com/chicken」「kushi.example.com/zebra」をOKだけど「sake.example.com/chicken」「sake.example.com/zebra」はNGな例
Route::domain('kushi.example.com')->group(function(){
Route::get('chicken', 'KushiController@chicken');
Route::get('zebra', 'KushiController@zebra');
});
Route::domain('sake.example.com')->group(function(){
Route::get('sake', 'SakeController@sake');
Route::get('beer', 'SakeController@beer');
});
※「sake.example.com」は「/sake」「/beer」がOKになる。
prefixでグループ化
特定のフォルダ以下をまとめて設定したい
// ▼こういう風に書くのがイヤだってとき
// Route::get('kushi/chicken', 'KushiController@chicken');
// Route::get('kushi/zebra', 'KushiController@zebra');
Route::prefix('kushi')->group(function(){
Route::get('chicken', 'KushiController@chicken');
Route::get('zebra', 'KushiController@zebra');
});
domaineとprefixを組み合わせたい
// 「http://hoge.example.com/kushi/〇〇〇」のルーティング
Route::domain('hoge.example.com')->prefix('kushi')->group(function(){
Route::get('chicken', 'KushiController@chicken');
Route::get('zebra', 'KushiController@zebra');
});
ルーティング:RESTful
未調査。
「Route::resource()」ってヤツを使えばいいそうだ。
HTTPメソッド指定
「Route::get()」のトコが「post」や「put」「delete」などにする
| GET | ただのget送信 |
Route::get('〇〇〇', function(){ return 'Methodは「get」です'; });
|
|---|---|---|
| POST | 新規作成(insert) |
Route::post('〇〇〇', function(){ return 'Methodは「post」です'; });
|
| PUT | 更新 or 新規作成(update or insert) |
Route::put('〇〇〇', function(){ return 'Methodは「put」です'; });
|
| PATCH | PUTの範囲限定の更新 |
Route::patch('〇〇〇', function(){ return 'Methodは「patch」です'; });
|
| DELETE | データの削除時に使うmethod |
Route::delete('〇〇〇', function(){ return 'Methodは「delete」です'; });
|
| OPTIONS | ? |
Route::options('〇〇〇', function(){ return 'Methodは「options」です'; });
|
※POSTとPUTの違いがよく分からん。「POST:新規」「PUT:更新」とかなら分かりやすいのに・・・。
複数のメソッドに対応させる
「Route::get()」のトコが「match」になり、第一引数にメソッド名を追加する
▼「Route::match([メソッド], 〇〇〇, function(){})」・・・「post、put」のみ対応したいとき
Route::match(
['post', 'put'],
'〇〇〇',
function() {
return 'Methodは「post」or「put」です';
}
);
サンプル
Route::match(['get', 'post'], '/hoge', [Controllers\HogeController::class, 'index'])->name('hoge');
form送信をさせるとき
▼formタグが「PUT」「PATCH」「DELETE」「OPTIONS」に対応していないので「_method」を使う
<form method="POST"> <input type="hidden" name="_method" value="PUT" /> </form>
API関連
・「http://〇〇〇/api/〇〇〇」は「ルーティング:routes/api.php」を使う
▼routes/api.php(「api/chicken」というURLの場合)
Route::get('chicken', 'KushiController@chicken');
※URLは「api」を省略して「chicken」以下を記載
URLの「api」を変更したい
「http://〇〇〇/api/〇〇〇」というURLが気に入らない場合「app/Providers/RouteServiceProvider.php」の「mapApiRoutes()」を書き換える
→「prefix('api')」を変更。
試していないけど使うミドルウェアやルーティングのファイルを変更したいときも同じ「mapApiRoutes()」の中を修正でいけるはず。