Controller trong Laravel 8

Bài viết này chúng ta sẽ tìm hiểu một thành phần quan trọng trong mô hình MVC của Laravel 8 đó là Controller trong Laravel 8. Đây là nơi chứa các điều khiển, xử lý và trả lại yêu cầu người dùng được đưa vào thông qua view. Không lan man nữa chúng ta đi tìm hiểu Controller trong Laravel 8 ngay và luôn nhé các bạn.

1. Tạo controller trong Laravel.

Trong Laravel 8 tất cả các controller đều kế thừa class Controller App\Http\Controllers\Controller

Có 2 cách tạo mới controller bằng tay và dụng lệnh artisan thế nhưng chúng ta được khuyên sử dụng câu lệnh

php artisan make:controller Ten_Controller

Trong đó

  • Ten_Controller là tên của controller các chúng ta muốn tạo.

Ví Dụ: Mình sẽ tạo mới một controller là User_Controller.

php artisan make:controller User_Controller

Lúc này Laravel sẽ tạo cho các chúng ta một file User_Controller .php nằm trong thư mục app/Http/Controllers có nội dung như sau 

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class User_Controller extends Controller
{
    //
}

Nếu muốn tạo controller trong một thư mục con nằm trong app/Http/Controllers thì các chúng ta chỉ cần điền thêm ControllerName là path chứa thư mục con đó kèm controller name.

Ví Dụ: Tạo mới controller User_Controller trong thư mục app/Http/Controllers/Pages.

php artisan make:controller Pages/User_Controller

Lúc này ở route các chúng ta muốn assign logic cho controller chúng ta truyền tham số thứ 2 là một mảng với tham số đầu tiên là đường dẫn của controller, tham số thứ 2 là method thực thi.

Ví Dụ: Mình sẽ thêm method show vào trong User_Controller vừa tạo ở trên để hiển thị view đồng thời assign vào route với path /user.

- app/Http/Controllers/User_Controller.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ContactController extends Controller
{
    public function show()
    {
        return view('user.form');
    }
}

routes/web.php

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

Route::get('/user', [User_Controller::class, 'show']);

2. Single Action Controller.

Trong một vài trường hợp nếu chúng ta chỉ muốn một controller class thực thi một hành động duy nhất, thì các chúng ta cũng có thể thêm một phương thức như phần trên rồi assign chúng vào route. Hoặc có thể viết chúng trong phương thức __invoke rồi trong route các chúng ta sẽ không cần phải truyền thêm phương thức nữa. 

Ví Dụ: Single action Controller.

app/Http/Controllers/ProvisionServer.php

<?php

namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Models\User;
class ProvisionServer extends Controller
{
    /**
     * Provision a new web server.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function __invoke()
    {
        // ...
    }
}

Khi đăng ký Single Action Controller bạn không cần chỉ định phương thức controller. Thay vào đó, bạn có thể chỉ cần chuyển tên controller cho Route:

use App\Http\Controllers\ProvisionServer;
Route::post('/server', ProvisionServer::class);

Muốn tạo một controller như trên, các bạn có thể truyền thêm option --invokable khi chạy make:controller artisan command.

php artisan make:controller ProvisionServer --invokable

3. Middleware trong Controller.

Trong Laravel 8 chúng ta có thể assign middleware vào trong controller với method middleware.

Ví Dụ: Mình sẽ assigne middleware auth vào trong controller User_Controller.

class User_Controller extends Controller
{
    /**
     * Instantiate a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth');
    }
}

Nếu chúng ta muốn chỉ định middleware hoạt động cho một vài method nào đó trong controller các chúng ta có thể đặt middleware trong method đó. Hoặc sử dụng phương thức only.

Ví Dụ: middleware cho hành động edit trong User_Controller .

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class User_Controller extends Controller
{
    public function __construct()
    {
        $this->middleware('auth')->only('edit');
    }

    public function edit()
    {
        //
    }
}

Hoặc

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class User_Controller extends Controller
{
    public function edit()
    {
        $this->middleware('auth');
    }
}

Nếu chúng ta muốn middleware hoạt động với tất cả action trong controller và bỏ qua một vài action nào đó, các chúng ta có thể sử dụng phương thức except.

Ví Dụ: assign middleware auth cho controller User_Controller và bỏ qua action indexshow.

$this->middleware('auth')->except(['index', 'show']);

// hoặc

$this->middleware('auth')->except('index', 'show');

4. Resource Controller.

Resource controller trong Laravel là một dạng controller cung cấp sẵn các action index, create, store, show, edit, update, destroy để thực thi các hành động CRUD data ( nôm na là các hành động chèn, update, đọc và xóa dữ liệu)

Để tạo resource controller trong Laravel các chúng ta sử dụng command:

php artisan make:controller Ten_Controller --resource

Trong đó: Ten_Controller  là tên của controller các chúng ta muốn tạo.

Ví Dụ: Mình sẽ tạo một resource controller là ImageController.

php artisan make:controller ImageController --resource

Lúc này Laravel 8 sẽ sinh ra cho chúng ta file app/Http/Controllers/ImageController.php có nội dung như sau:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ImageController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        //
    }
    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
    }
    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        //
    }
    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        //
    }
    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        //
    }
    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        //
    }
    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        //
    }
}

Lúc này để assign route cho resource controller chúng ta sử dụng phương thức resource.

Ví Dụ: routes/web.php

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

Route::resource('photos', ImageController::class);

Để xem danh sách các route các chúng ta sử dụng command:

php artisan route:list

Kết quả:

λ php artisan route:list
+--------+-----------+---------------------+----------------+----------------------------------------------+------------+
| Domain | Method    | URI                 | Name           | Action                                       | Middleware |
+--------+-----------+---------------------+----------------+----------------------------------------------+------------+
|        | GET|HEAD  | /                   |                | Closure                                      | web        |
|        | GET|HEAD  | api/greeting        |                | Closure                                      | api        |
|        | GET|HEAD  | api/user            |                | Closure                                      | api        |
|        |           |                     |                |                                              | auth:api   |
|        | GET|HEAD  | photos              | photos.index   | App\Http\Controllers\ImageController@index   | web        |
|        | POST      | photos              | photos.store   | App\Http\Controllers\ImageController@store   | web        |
|        | GET|HEAD  | photos/create       | photos.create  | App\Http\Controllers\ImageController@create  | web        |
|        | GET|HEAD  | photos/{photo}      | photos.show    | App\Http\Controllers\ImageController@show    | web        |
|        | PUT|PATCH | photos/{photo}      | photos.update  | App\Http\Controllers\ImageController@update  | web        |
|        | DELETE    | photos/{photo}      | photos.destroy | App\Http\Controllers\ImageController@destroy | web        |
|        | GET|HEAD  | photos/{photo}/edit | photos.edit    | App\Http\Controllers\ImageController@edit    | web        |
|        | GET|HEAD  | user/{id?}          |                | Closure                                      | web        |
|        | GET|HEAD  | welcome             |                | Closure                                      | web        |
+--------+-----------+---------------------+----------------+----------------------------------------------+------------+

Nhìn vào bảng trên chúng ta cũng đã thấy các action tương ứng với các route name rồi đấy 

Trong trường hợp chúng ta muốn sử dụng thêm route model binding trong route trong resource controller các chúng ta có thể sử dụng command

php artisan make:controller ControllerName --resource --model=ModelName

Trong đó ModelName là model mà chúng ta muốn auto binding.

Xác định action của controller trong route

Trong một số trường hợp, nếu ko muốn sử dụng tất cả các action trong controller thì ở route các chúng ta sử dụng phương thức except để xác định các action không muốn sử dụng.

Ví Dụ: Loại bỏ action indexshow trong controller ImageController 

Route::resource('photos', ImageController::class)->except([
    'index', 'show'
]);

Hoặc các bạn cũng có thể sử dụng phương thức only để xác định các action được phép sử dụng.

Ví Dụ: Xác định chỉ sử dụng action indexshow trong controller ImageController.

Route::resource('photos', ImageController::class)->only([
    'index', 'show'
]);

Bên cạnh đó nếu  muốn thay đổi route name cho một action nào đó trong resource controller chúng ta có thể sử dụng phương thức names.

Ví Dụ: Thay đổi route name cho action create thành photo.build.

Route::resource('photos', ImagegController::class)->names([
    'create' => 'photos.build'
]);

chúng ta cũng có thể thay đổi route parameters cho resource controller, bằng cách sử dụng phương thức parameters.

Ví Dụ: Thay đổi parameter photo thành photo_id.

Route::resource('photos', ImageController::class)->parameters([
    'users' => 'photos_id'
]);

5. API Resource Routes.

Nếu ứng dụng của chúng ta chỉ cần cung cấp các action như một API Resfull. Thì chúng ta có thể sử dụng API Resource route. Lúc này các route sẽ bỏ qua các action create, edit.

Ví Dụ: Chuyển ImageController trên về API resource route.

use App\Http\Controllers\ImageController ;

Route::apiResource('photos', ImageController::class);

Chạy php artisan route:list để xem kết quả:

php artisan route:list                                                                                              
--------+-----------+----------------+----------------+----------------------------------------------+------------+  
 Domain | Method    | URI            | Name           | Action                                       | Middleware |  
--------+-----------+----------------+----------------+----------------------------------------------+------------+  
        | GET|HEAD  | /              |                | Closure                                      | web        |  
        | GET|HEAD  | api/greeting   |                | Closure                                      | api        |  
        | GET|HEAD  | api/user       |                | Closure                                      | api        |  
        |           |                |                |                                              | auth:api   |  
        | GET|HEAD  | photos         | photos.index   | App\Http\Controllers\ImageController@index   | web        |  
        | POST      | photos         | photos.store   | App\Http\Controllers\ImageController@store   | web        |  
        | GET|HEAD  | photos/{photo} | photos.show    | App\Http\Controllers\ImageController@show    | web        |  
        | PUT|PATCH | photos/{photo} | photos.update  | App\Http\Controllers\ImageController@update  | web        |  
        | DELETE    | photos/{photo} | photos.destroy | App\Http\Controllers\ImageController@destroy | web        |  
        | GET|HEAD  | user/{id?}     |                | Closure                                      | web        |  
        | GET|HEAD  | welcome        |                | Closure                                      | web        |  
--------+-----------+----------------+----------------+----------------------------------------------+------------+  

6. Lời kết.

Về controller trong Laravel 8 đến đây là hết rồi. Bài này chỉ là cơ bản các phần sau chúng ta sẽ từ từ ngâm cứu thêm về nó nhé các bạn. Chúc các bạn học tốt.

Bình luận