---
# System prepended metadata

title: laravel route 路由
tags: [Laravel]

---

# laravel route 路由

##  Scope Bindings
用在千套的relation route binding
https://www.youtube.com/watch?v=xqNip5PYBv8

## 路由緩存解析
https://learnku.com/courses/laravel-performance/8.x/routing-cache/10924

## Signed Routes 


## Php原生 路由
https://www.bilibili.com/video/BV1bt4y1m7p1?from=search&seid=4403342235367102614&spm_id_from=333.337.0.0

## resource跟原生show衝突
https://www.youtube.com/watch?v=exIfecOZd2E
![](https://i.imgur.com/YV0KTbY.png)
他會以為你對應show

所以你url 會一樣就移到
resource前面

## 建立一個新的 除了api web 之外用一個專門auth的
![](https://i.imgur.com/O6vb9xr.png)
寫一個 然後上面註冊
https://www.youtube.com/watch?v=I6kyfSmPhn8


## model綁定原理
沒有追 大概董而已
不是這方法
這方法可以在routeServicePovider寫Route::model去改變路由綁定
![](https://i.imgur.com/kajx6XD.png)

可以去看middware 那邊有bind (api那邊)


## route list
--name=???

--path= ??

只找要的
## 自訂路由綁定model
```
<?php
public function boot()
{
    parent::boot();

    Route::model('user', App\User::class);
}
```
**Answer:**
如果不想使用 type-hinted variable 來實現 model binding, 想要經由 url 的 parameter name 來實現 model binding 的話, 可以再 RouteServiceProvider 的 boot method
使用 Route class 的 model method 來將 url 中的 ‘user’ parameter 與 ‘App\User’ model 相關聯


## 路由綁定model過濾
```
<?php
public function boot()
{
    parent::boot();

    Route::bind('user', function ($value) {
        return App\User::where('name', $value)->firstOrFail();
    });
}
```
**Answer:**
預設在 controller method inject model binding 時, 像是 index(User $user), Laravel 的預設 convention 使用 id 尋找對應 model
可在 RouteServiceProvider 的 boot() 定義 model binding 規則, 當 binding 指定的 Model 為 User 時, 會到 User Model 以 where(‘name’, $value)->firstOrFail() 的方式取得 model

## route::list 篩選
**php artisan route:list --columns=Method,URI,Name**
只顯示方法 url 跟 name

## 想知道auth的路由位置
`知道後面到底有哪些路線Auth::routes()？從 Laravel 7 開始，它位於一個單獨的包中，因此請檢查文件/vendor/laravel/ui/src/AuthRouteMethods.php.`



```
public function auth()
{
    return function ($options = []) {
        // Authentication Routes...
        $this->get('login', 'Auth\LoginController@showLoginForm')->name('login');
        $this->post('login', 'Auth\LoginController@login');
        $this->post('logout', 'Auth\LoginController@logout')->name('logout');
        // Registration Routes...
        if ($options['register'] ?? true) {
            $this->get('register', 'Auth\RegisterController@showRegistrationForm')->name('register');
            $this->post('register', 'Auth\RegisterController@register');
        }
        // Password Reset Routes...
        if ($options['reset'] ?? true) {
            $this->resetPassword();
        }
        // Password Confirmation Routes...
        if ($options['confirm'] ?? class_exists($this->prependGroupNamespace('Auth\ConfirmPasswordController'))) {
            $this->confirmPassword();
        }
        // Email Verification Routes...
        if ($options['verify'] ?? false) {
            $this->emailVerification();
        }
    };
}
```


在 Laravel 7 之前，檢查文件`/vendor/laravel/framework/src/illuminate/Routing/Router.php.`


## 當沒有找到路由時 不要給他404
使用fallback
```
Route::group(['middleware' => ['auth'], 'prefix' => 'admin', 'as' => 'admin.'], function () {
    Route::get('/home', 'HomeController@index');
    Route::resource('tasks', 'Admin\TasksController');
});

// Some more routes....
Route::fallback(function() {
    return 'Hm, why did you land here somehow?';
});
```




## group

另外，如果您要将所有中间件 + 名称 + 前缀添加到一个组中，则将它们放入数组中更容易理解：

```
// 而不是这样做： 
Route::name('admin.')->prefix('admin')->middleware('admin')->group(function () {
    // ...
});

// 可以使用数组
Route::group([
    'name' => 'admin.', 
    'prefix' => 'admin', 
    'middleware' => 'auth'
], function () {
    // ...
});
```

## 特別不用帶參數
通過 Eloquent 模型填充參數
如果你重定向到一個帶有從 Eloquent 模型填充的“ID”參數的路由，你可以傳遞模型本身。將自動提取 ID：

```
// For a route with the following URI: profile/{id}

return redirect()->route('profile', [$user]);
```

## 路由模型綁定

當向路由或控制器的方法注入模型 ID主鍵 時，您可能總是會需要透過ID來找出該筆資料。Laravel 路由模型綁定提供了一個方便的方案，它可以自動注入模型實例到路由中。例如，您可以注入與主鍵值為給定 ID 的整個 User 模型實例，而不是只注入用戶的 ID

隱式榜定
Laravel 會自動處理在路由或控制器方法中，與型別提示的參數名相匹配的路由區段名稱的的 Eloquent 模型。例如：

```
use App\Models\User;

Route::get('/users/{user}', function (User $user) {
    return $user->email;
});
```
在這個例子中，由於 $user 參數被型別提示為 Eloquent 模型 App\Models\User，參數名稱又與 URI 中的 {user} 相同，因此，Laravel 會自動注入與請求 URI 中傳入的 ID 主鍵相符的用戶模型實例。如果在數據庫中未找到對應的模型實例，將會自動生成 404 異常

當然，在使用控制器方法時也可以使用隱式綁定。同樣，請注意 {user} URI 區段與控制器中的 $user 參數相同，並且該參數包含一個 App\Models\User 型別提示：

```
use App\Http\Controllers\UserController;
use App\Models\User;

// 路由定義...
Route::get('/users/{user}', [UserController::class, 'show']);

// 控制器方法定義...
public function show(User $user)
{
    return view('user.profile', ['user' => $user]);
}
```
自定義鍵名
有時，你可能希望使用 id 以外的欄位來查詢 Eloquent 模型。為此你可以在路由參數定義中指定要查詢的欄位：
```

use App\Models\Post;

Route::get('/posts/{post:slug}', function (Post $post) {
    return $post;
});
```
假如你希望永遠使用某個除id之外的欄位來進行查詢以取得模型實例，你可以複寫 Eloquent 模型的 getRouteKeyName():

```
/**
 * Get the route key for the model.
 *
 * @return string
 */
public function getRouteKeyName()
{
    return 'slug';
}
```
自定義鍵與作用域
有時，當一個路由定義中隱式綁定多個 Eloquent 模型時，您可能會想要限定第二個 Eloquent 模型的作用域，使它是第一個 Eloquent 模型的子模型。例如，考慮這樣一種情況，通過 slug 字段為特定用戶去查詢部落格文章:

```
use App\Models\Post;
use App\Models\User;

Route::get('/users/{user}/posts/{post:slug}', function (User $user, Post $post) {
    return $post;
});
```
當使用自定義鍵值隱式綁定作為巢式路由參數時，Laravel 將自動限定查詢的範圍，通過其父節點使用猜測父節點上關係名稱的約定來檢索巢狀模型。 在本例中，假定 User 模型有一個名為 posts 的關聯 (路由參數名的複數形式)，可用於查詢 Post 模型(這功能理解上有點複雜，先作筆記)。

顯示榜定
你並非只能透過 Laravel的隱式榜定才能夠使用模型綁定功能，你也可以清楚的定義到底路由參數與模型間的關係為何

要註冊顯式綁定，請使用路由器的 model() 方法為給定的參數指明參數對應的類別。您應該在 RouteServiceProvider 類別的 boot() 的開頭定義顯式模型綁定：

```
use App\Models\User;
use Illuminate\Support\Facades\Route;


/**
 * Define your route model bindings, pattern filters, etc.
 *
 * @return void
 */
public function boot()
{
    Route::model('user', User::class);

    // ...
}
```
接下來，定義一個包含 {user} 參數路段的路由：

use App\Models\User;

Route::get('/users/{user}', function (User $user) {
    //
});
由於我們已將所有 {user} 參數綁定至 App\Models\User 模型，所以 User 實例將被注入該路由。舉個例子，profile/1 的請求會注入數據庫中 id欄位為 1 的 User 實例

如果在資料庫中找不到對應的模型實例，就會自動拋出一個 404 異常。


## getRoutes
Route::getRoutes()方法可以在laravel项目中获取所有已定义的路由


## 自訂web.php 
寫一個map 跟 mapWebRoutes的方法
```
/**
     * Define the routes for the application.
     */
    public function map()
    {
        $this->mapWebRoutes();
    }

    /**
     * Define the "web" routes for the application.
     *
     * These routes all receive session state, CSRF protection, etc.
     */
    protected function mapWebRoutes()
    {
        Route::middleware('web')
            ->prefix($this->prefix)
            ->as($this->routeNameAs)
            // ->namespace($this->moduleNamespace)
            ->group(function () {
                // Load custom route overrides
                $routesFile = base_path('routes/twjoinadmin/web.php');
                if (file_exists($routesFile)) {
                    require $routesFile;
                }
            });
    }
```

原理是
在原本的boot方法,所有service都會跑boot
這邊會使用routes
近來可以看到他路由放在變數裡面
return this這樣才會跑register
register,裡面有一個
loadRoutes
這邊會去判斷有沒有map方法

再用map去跑mapWeb

**小提醒**
如果用建構式的話 要有$app 自己看底層
```
public function __construct($app)
    {
        parent::__construct($app);

        $this->prefix = Config::get('twjoinadmin.routes.prefix');
        $this->routeNameAs = Config::get('twjoinadmin.routes.name_as');
        // $this->moduleNamespace = Config::get('twjoinadmin.routes.namespace');
    }
```


## 簽名路由
https://www.youtube.com/watch?v=N40i3ljGNSI&ab_channel=Acadea.io

用route faced去給 route name 讓他generate一個簽名url 他會有過期時間跟雜湊
就不能亂改了

###### tags: `Laravel`