laravel控制器之资源控制器

资源控制器

Laravel 的资源控制器可以让我们很便捷地构建基于资源的 RESTful 控制器,例如,你可能想要在应用中创建一个控制器,用于处理关于文章存储的 HTTP 请求,使用 Artisan 命令 make:controller,我们可以快速创建这样的控制器:

php artisan make:controller PostController --resource

该 Artisan 命令将会生成一个控制器文件 app/Http/Controllers/PostController.php,这个控制器包含了每一个资源操作对应的方法:

<?php

namespace AppHttpControllers;

use IlluminateHttpRequest;

class PostController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return IlluminateHttpResponse
     */
    public function index()
    {
        //
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return IlluminateHttpResponse
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  IlluminateHttpRequest  $request
     * @return IlluminateHttpResponse
     */
    public function store(Request $request)
    {
        //
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return IlluminateHttpResponse
     */
    public function show($id)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return IlluminateHttpResponse
     */
    public function edit($id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  IlluminateHttpRequest  $request
     * @param  int  $id
     * @return IlluminateHttpResponse
     */
    public function update(Request $request, $id)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return IlluminateHttpResponse
     */
    public function destroy($id)
    {
        //
    }
}

接下来,可以通过 resource 方法为该控制器注册一个资源路由:

Route::resource('posts', 'PostController');

这个路由声明包含了处理文章资源对应动作的多个路由,相应地,Artisan
生成的控制器也已经为这些动作设置了对应的处理方法。

你可以通过传递数组到 resources 方法从而一次注册多个资源控制器:

Route::resources([
    'photos' => 'PhotoController',
    'posts' => 'PostController'
]);

资源控制器处理的动作

请求方式URI路径控制器方法路由名称作用
GET /posts index posts.index 获取所有列表的页面 
GET /posts/create create posts.create 创建数据的页面
POST /posts store posts.store 提交创建的数据
GET /posts/{post} show posts.show 获取单个数据的页面
GET /posts/{post}/edit edit posts.edit 获取要修改数据的页面
PUT/PATCH /posts/{post} update posts.update 提交要修改数据
DELETE /posts/{post} destroy posts.destroy 删除数据

指定资源模型

如果你使用了路由模型绑定,并且想要在资源控制器的方法中对模型实例进行依赖注入,可以在生成控制器的使用使用 --model 选项:

php artisan make:controller PostController --resource --model=Post

不过学院君个人不推荐使用这种模型绑定,因为这里会涉及到对模型数据的缓存逻辑,为性能考虑,我们不想总是从数据库取数据,所以,尽量保持单个功能的简单和单一职责,让开发者自己去组装需要的功能,这是 Unix 奉行的设计哲学,也是我们在系统设计的时候需要考量的重要因素。

伪造表单方法

由于 HTML 表单不支持发起 PUTPATCH 和 DELETE 请求,需要添加一个隐藏的 _method 字段来伪造 HTTP 请求方式,Blade 指令 @method 可以帮我们做这件事:

<form action="/foo/bar" method="POST">
    @method('PUT')
</form>

部分资源路由

声明资源路由时可以指定该路由处理的动作子集:

Route::resource('post', 'PostController', ['only' => 
    ['index', 'show']
]);

Route::resource('post', 'PostController', ['except' => 
    ['create', 'store', 'update', 'destroy']
]);

API 资源路由

声明被 API 消费的资源路由时,你可能需要排除展示 HTML 模板的路由,如 create 和 edit,为了方便起见,Laravel 提供了 apiResource 方法自动排除这两个路由:

Route::apiResource('post', 'PostController');

同样,你可以传递数组到 apiResources 方法从而一次注册多个 API 资源控制器:

Route::apiResources([
    'posts' => 'PostController',
    'photos' => 'PhotoController'
]);

要想快速生成不包含 create 或 edit 方法的 API 资源控制器,可以在执行 make:controller 命令时使用 --api 开关:

php artisan make:controller API/PostController --api

命名资源路由

默认情况下,所有资源控制器动作都有一个路由名称,不过,我们可以通过传入 names 数组来覆盖这些默认的名称:

Route::resource('post', 'PostController', ['names' => 
    ['create' => 'post.build']
]);

命名资源路由参数

默认情况下,Route::resource 将会基于资源名称的单数格式为资源路由创建路由参数,你可以通过在选项数组中传递 parameters 来覆盖这一默认设置。 parameters 是资源名称和参数名称的关联数组:

Route::resource('user', 'AdminUserController', ['parameters' => [
    'user' => 'admin_user'
]]);

上面的示例代码会为资源的 show 路由生成如下 URL:

/user/{admin_user}

本地化资源 URI

默认情况下,Route::resource 创建的资源 URI 是英文风格的,如果你需要本地化 create 和 edit 请求路由,可以使用 Route::resourceVerbs 方法。该功能可以在 AppServiceProvider 的 boot 方法中实现:

use IlluminateSupportFacadesRoute;

/**
 * Bootstrap any application services.
 *
 * @return void
 */
public function boot()
{
    Route::resourceVerbs([
        'create' => 'xinzeng',
        'edit' => 'bianji',
    ]);
}

定制化请求方式完成后,注册资源路由如 Route::resource('wenzhang', 'PostController') 将会生成如下 URI:

/wenzhang/xinzeng
/wenzhang/{wenzhang}/bianji

好吧,你可以看出来,我是用拼音的方式对资源路由进行了本地化设置。

注:启用了定制化后,原来的create,edit的请求路由同样有效

补充资源控制器

如果需要在默认资源路由之外添加额外的路由到资源控制器,应该在调用 Route::resource 之前定义这些路由,否则,通过 resource 方法定义的路由可能无意中覆盖掉补充的额外路由:

Route::get('posts/popular', 'PostController@method');
Route::resource('posts', 'PostController');

注:注意保持控制器的单一职责,如果你发现指向控制器动作的路由超过默认提供的资源控制器动作集合了,考虑将你的控制器分割成多个更小的控制器。

原文地址:https://www.cnblogs.com/f-rt/p/9900813.html