路由器

目录老牛浏览 27讨论 0发表于

路由闭包

绝不在路由配置文件里书写『闭包路由』或者其他业务逻辑代码,因为一旦使用将无法使用路由缓存

路由器要保持干净整洁,绝不放置除路由配置以外的其他程序逻辑。

控制器方法定义

路由中的控制器方法定义,必须使用 Controller::class 这种方式加载。

✅ 正确

php
Route::get('/photos', [PhotosController::class, 'index'])->name('photos.index');

❌ 错误的例子:

php
Route::get('/photos', 'PhotosController@index')->name('photos.index');

这样做 IDE 可以加代码索引。有两个好处:

  1. 支持点击跳转到方法;

  2. 支持重构。

Restful 路由

必须优先使用 Restful 路由,配合资源控制器使用,见文档

1dd4ff2a-3daa-4844-90a9-620e7e910b3c

超出 Restful 路由的,应该模仿上图的方式来定义路由。

resource 方法正确使用

一般资源路由定义:

php
Route::resource('photos', PhotosController::class);

等于以下路由定义:

php
Route::get('/photos', [PhotosController::class, 'index'])->name('photos.index');
Route::get('/photos/create', [PhotosController::class, 'create'])->name('photos.create');
Route::post('/photos', [PhotosController::class, 'store'])->name('photos.store');
Route::get('/photos/{photo}', [PhotosController::class, 'show'])->name('photos.show');
Route::get('/photos/{photo}/edit', [PhotosController::class, 'edit'])->name('photos.edit');
Route::put('/photos/{photo}', [PhotosController::class, 'update'])->name('photos.update');
Route::delete('/photos/{photo}', [PhotosController::class, 'destroy'])->name('photos.destroy');

使用 resource 方法时,如果仅使用到部分路由,必须使用 only 列出所有可用路由:

php
Route::resource('photos', PhotosController::class, ['only' => ['index', 'show']]);

绝不使用 except,因为 only 相当于白名单,相对于 except 更加直观。路由使用白名单有利于养成『安全习惯』。

单数 or 复数?

资源路由路由 URI 必须使用复数形式,如:

  • /photos/create

  • /photos/{photo}

错误的例子如:

  • /photo/create

  • /photo/{photo}

路由模型绑定

在允许使用路由模型绑定的地方必须使用。

模型绑定代码必须放置于 app/Providers/RouteServiceProvider.php 文件的 boot 方法中:

php
    public function boot()
    {
        Route::bind('user_name', function ($value) {
            return User::where('name', $value)->first();
        });

        Route::bind('photo', function ($value) {
            return Photo::find($value);
        });

        parent::boot();
    }

注:如果使用了 {id} 作为参数,Laravel 已经默认做了绑定。

全局路由器参数

出于安全考虑,应该使用全局路由器参数限制,详见文档

必须RouteServiceProvider 文件的 boot 方法里定义模式:

php
/**
 * 定义你的路由模型绑定, pattern 过滤器等。
 *
 * @return void
 */
public function boot()
{
    Route::pattern('id', '[0-9]+');

    parent::boot();
}

模式一旦被定义,便会自动应用到所有使用该参数名称的路由上:

php
Route::get('users/{id}', [UsersController::class, 'show']);
Route::get('photos/{id}', [PhotosController::class, 'show']);

只有在 id 为数字时,才会路由到控制器方法中,否则 404 错误。

路由命名

除了 resource 资源路由以外,其他所有路由都必须使用 name 方法进行命名。

必须使用『资源前缀』作为命名规范,如下的 users.follow,资源前缀的值是 users.

php
Route::post('users/{id}/follow', [UsersController::class, 'follow'])->name('users.follow');

获取 URL

获取 URL 必须遵循以下优先级:

  1. $model->link()

  2. route 方法

  3. url 方法

在 Model 中创建 link() 方法:

php
public function link($params = [])
{
    $params = array_merge([$this->id], $params);
    return route('models.show', $params);
}

所有单个模型数据链接使用:

php
$model->link();

// 或者添加参数
$model->link($params = ['source' => 'list'])

『单个模型 URI』经常会发生变化,这样做将会让程序更加灵活。

除了『单个模型 URI』,其他路由 必须 使用 route 来获取 URL:

php
$url = route('profile', ['id' => 1]);

无法使用 route 的情况下,可以使用 url 方法来获取 URL:

php
url('profile', [1]);
点赞
收藏
暂无讨论,快来发起讨论吧~
私信
老牛@ilaoniu
老牛,俗称哞哞。单纯的九零后理工小青年。喜欢折腾,爱玩,爱音乐,爱游戏,爱电影,爱旅游...
最后活跃于