Tìm hiểu Laravel Routing - Toàn tập về định tuyến trong Laravel

Written by admin
Posted on Sun, 08/29/2021 - 05:56
19 views

Share Everywhere

Table of contents

Chắc hẳn mỗi khi bắt đầu tìm hiểu về Laravel thì các kiến thức cơ bản như Routing, Middleware, Controllers, Requests, Responses, Views là những khái niệm đầu tiên bạn cần phải biết để có thể sử dụng và làm quen với Laravel.

Trong bài viết này, mình sẽ đi sâu vào tìm hiểu về việc định tuyến trong Laravel. Đầu tiên, mục đích của Routing là để định tuyến các request của người dùng sẽ được đưa đến 1 Controller cụ thể nào đó để xử lý. Ở trong Laravel ta có thể hoàn toàn xử lý các dữ liệu đó trong phần Router.
Router được viết ở đâu?

Phiên bản Laravel 5.2 trở về trước router được viết vào file routes.php nằm ở app/Http/routes.php. Kể từ phiênbản Laravel 5.3 router được tách ra 1 thư mục riêng có tên là routes và đồng thời chia nhỏ (api, channels, console, web) các loại router để dễ quản lý.

  • routes\web.php: định nghĩa các router trên trình duyệt web, sử dụng cookie, session, bảo vệ csrf,...
  • routes\api.php: định nghĩa các restful API
  • routes\channels.php: dùng cho việc broadcasting
  • routes\console.php: là nơi để bạn định nghĩa tất cả các Closure based console commands

1. Router cơ bản

Các router Laravel cơ bản nhất chấp nhận một URI và một Closure, cung cấp một phương thức xác định rất đơn giản và rõ ràng:
    
// http://chungnguyen.xyz/hello
Route::get('hello', function () {
    return 'Hello World';
});

Router Laravel có hỗ trợ các phương thức giống với http request method như GET, POST, PUT, PATCH, DELETE, OPTIONS, ...

Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);

Ngoài ra, laravel cũng hỗ trợ ta định nghĩa một route mà có thể xử lý nhiều loại method với chung một response bằng cách sử dụng phương thức match và any.

// Gửi http request get hoặc post đều trả về kết quả là match
Route::match(['get', 'post'], '/match', function () {
    return 'match';
});

// Gửi bất kỳ http request method nào cũng đều trả về kết quả là any
Route::any('any', function () {
    return 'any';
});

1.1 Bảo vệ CSRF

Tất cả các router được phủ bởi web middleware sẽ được bảo vệ CSRF với các method POST, PUT, DELETE. Khi bạn gửi request POST, PUT, DELETE lên server mà không kèm theo crsf token thì sẽ bị server từ chối vì lý do bảo mật, các bạn lưu ý nhé. Để chèn crsf token vào form các bạn làm như sau:

<form method="POST" action="/profile">
    @csrf
    ...
</form>

1.2 Chuyển hướng Routes

Mục đích là chuyển hướng routes, chẳng hạn bạn không dùng routes đó nữa hoặc chuyển sang địa chỉ mới..

Route::redirect('/dia-chi-cu', '/dia-chi-moi', $statusCode = 301);

1.3 View Routes

Nếu route của bạn chỉ đơn thuần muốn trả về 1 view mà không có xử lý logic gì hết thì đây là cách đơn giản hơn là phải trỏ về controller rồi controller lại trả về view.

Route::view('/welcome', 'welcome');
Route::view('/welcome', 'welcome', $datas = ['name' => 'ABC Nguyễn']);

2. Route có tham số

Route có tham số là tập hợp 1 số route có cùng logic xử lý, phù hợp cho tính linh động trong PHP.
Tham số route luôn luôn phải nằm trong dấu ngoặc nhọn {} và các tham số route không được phép chứa ký tự - nhé.

Route có tham số có 2 loại là:

  • Bắt buộc: {ten_tham_so} không truyền tham số khi gọi sẽ bị báo lỗi.
  • Không bắt buộc (thêm dấu ? sau tên của parameter): {ten_tham_so?} bạn hãy chắc chắn rằng đã khai báo giá trị mặc định
// ví dụ về Route không có tham số
Route::get('hello/chung', function() {
    return 'hello chung';
});
Route::get('hello/nguyen', function() {
    return 'hello nguyen';
});
Route::get('hello/blog', function() {
    return 'hello blog';
});

// Route có tham số bắt buộc
Route::get('hello/{name}', function($name) {
    return 'hello ' . $name;
});

// Route có tham số không bắt buộc
Route::get('hello/{name?}', function($name = 'Abc') {
    return 'hello ' . $name;
});

3.1 Ràng buộc biểu thức chính quy cho tham số

Rõ ràng với tham số truyền vào, chúng ta muốn giới hạn quy tắc cho tham số để ràng buộc bằng method where  

Route::get('user/{name}', function ($name) {
    // giới hạn tên là chữ cái hoa, thường.
})->where('name', '[A-Za-z]+');

Route::get('user/{id}', function ($id) {
    // giới hạn id chỉ được là số từ 0 - 9
})->where('id', '[0-9]+');

Route::get('user/{id}/{name}', function ($id, $name) {
    // ràng buộc cả id và name như đã giải thích ở trên
})->where(['id' => '[0-9]+', 'name' => '[a-z]+']);

Ràng buộc biểu thức chính quy toàn cục (Global)

Giả sử bạn muốn hễ tham số là id thì phải là số từ 0-9 bạn không thể copy-paste mãi như vậy

Bạn nên định nghĩa ràng buộc trong hàm boot của app\Providers\RouteServiceProvider.php:

/**
 * Define your route model bindings, pattern filters, etc.
 *
 * @return void
 */
public function boot()
{
    Route::pattern('id', '[0-9]+');
    Route::pattern('name', '[A-Za-z]+');
    parent::boot();
}

4. Đặt tên cho các Route

Việc đặt tên cho các route rất có ý nghĩa và hữu dụng khi bạn muốn thay đổi URI mà không phải thay đổi quá nhiều code. Ví dụ: link đăng nhập trang web là https://abc.xyz/login và ở thời điểm nào đó mình thay đổi thành https://abc.xyz/dang-nhap như vậy mình sẽ phải đi lùng hết trong code chỗ nào có /login mình phải đổi thành /dang-nhap. Mình khuyên các bạn đặt name cho toàn bộ route, và gọi output route bằng name để quản lý chặt chẽ các liên kết trên website của mình.

Để đặt tên một route ta sử dụng phương thức name

Route::get('user/profile', function () {
    //
})->name('profile');

Tạo URL từ route đã đặt tên

Một khi route đã được đặt tên, ta có thể sử dụng tên này qua phương thức route:

// Tạo URLs...
$url = route('profile');

// Tạo Redirects...
return redirect()->route('profile');

Nếu tên route được định nghĩa với tham số, bạn phải khai báo một đối số thứ hai trong phương thức route. Các đối số sẽ được chèn vào theo đúng thứ tự chính xác trên URLs:

Route::get('user/{id}/profile', function ($id) {
    //
})->name('profile');

// Tạo URL profile

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

Kiểm tra route hiện tại

Một khi route đã được đặt tên bạn hoàn toàn có thể kiểm tra request đang gửi tới có thuộc name nào? và code logic theo yêu cầu

Ví dụ: bạn có thể kiểm tra name route hiện tại từ middleware:

/**
 * Handle an incoming request.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Closure  $next
 * @return mixed
 */
public function handle($request, Closure $next)
{
    if ($request->route()->named('profile')) {
        //
    }

    return $next($request);
}

5. Nhóm route

Khi các route có chung tiền tố, chung middle, chung namespace, ... thì các bạn nên gom chúng lại với nhau mà không cần định nghĩa lại chúng trên mỗi route riêng. 

Ví dụ chung middleware

Route::middleware(['first', 'second'])->group(function () {
    Route::get('/', function () {
        // Uses first & second Middleware
    });

    Route::get('user/profile', function () {
        // Uses first & second Middleware
    });
});

Ví dụ chung namespace

Route::namespace('User')->group(function () {
    // controller sẽ sử dụng App\Http\Controllers\User làm namespace
});

Ví dụ chung tiền tố:

Route::prefix('admin')->group(function () {
    Route::get('users', function () {
        // https://chungnguyen.xyz/admin/users
    });
    Route::get('settings', function () {
        // https://chungnguyen.xyz/admin/settings
    });
});

Ví dụ chung tiền tố name route

Route::name('admin.')->prefix('admin')->group(function () {
    Route::get('users', function () {
        // Tạo url: $url = route('admin.users')
    })->name('users');
    Route::get('settings', function () {
        // Tạo url: $url = route('admin.settings')
    })->name('settings');
});

6. Truy cập route hiện tại

Bạn có thể sử dụng phương thức current, currentRouteName, và currentRouteAction trên Route facade để truy cập thông tin về resquest route xử lý đang đến:  

$route = Route::current();

$name = Route::currentRouteName();

$action = Route::currentRouteAction();

Add new comment

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.
CAPTCHA
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.
3 + 15 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.
Profile picture for user admin
Câu nói tâm đắc: “Điều tuyệt với nhất trong cuộc sống là làm được những việc mà người khác tin là không thể!”