Định tuyến
Quy tắc định tuyến mặc định
Quy tắc định tuyến mặc định của webman là http://127.0.0.1:8787/{bộ điều khiển}/{hành động}
.
Bộ điều khiển mặc định là app\controller\IndexController
, hành động mặc định là index
.
Ví dụ truy cập:
http://127.0.0.1:8787
sẽ mặc định truy cập vào phương thứcindex
của lớpapp\controller\IndexController
http://127.0.0.1:8787/foo
sẽ mặc định truy cập vào phương thứcindex
của lớpapp\controller\FooController
http://127.0.0.1:8787/foo/test
sẽ mặc định truy cập vào phương thứctest
của lớpapp\controller\FooController
http://127.0.0.1:8787/admin/foo/test
sẽ mặc định truy cập vào phương thứctest
của lớpapp\admin\controller\FooController
(tham khảo Nhiều ứng dụng)
Thêm vào đó, webman từ phiên bản 1.4 bắt đầu hỗ trợ các định tuyến mặc định phức tạp hơn, chẳng hạn như
app
├── admin
│ └── v1
│ └── v2
│ └── v3
│ └── controller
│ └── IndexController.php
└── controller
├── v1
│ └── IndexController.php
└── v2
└── v3
└── IndexController.php
Khi bạn muốn thay đổi một định tuyến yêu cầu nào đó, hãy thay đổi tệp cấu hình config/route.php
.
Nếu bạn muốn tắt định tuyến mặc định, hãy thêm cấu hình sau vào dòng cuối cùng trong tệp cấu hình config/route.php
:
Route::disableDefaultRoute();
Định tuyến Closure
Thêm mã định tuyến sau vào config/route.php
use support\Request;
Route::any('/test', function (Request $request) {
return response('test');
});
Lưu ý
Do hàm Closure không thuộc về bất kỳ bộ điều khiển nào, nên$request->app
,$request->controller
,$request->action
đều là chuỗi rỗng.
Khi địa chỉ truy cập là http://127.0.0.1:8787/test
, sẽ trả về chuỗi test
.
Lưu ý
Đường dẫn định tuyến phải bắt đầu bằng/
, ví dụ:
use support\Request;
// Cách sử dụng sai
Route::any('test', function (Request $request) {
return response('test');
});
// Cách sử dụng đúng
Route::any('/test', function (Request $request) {
return response('test');
});
Định tuyến lớp
Thêm mã định tuyến sau vào config/route.php
Route::any('/testclass', [app\controller\IndexController::class, 'test']);
Khi địa chỉ truy cập là http://127.0.0.1:8787/testclass
, sẽ trả về giá trị trả về của phương thức test
trong lớp app\controller\IndexController
.
Tham số định tuyến
Nếu trong định tuyến có tham số, hãy sử dụng {key}
để khớp, kết quả khớp sẽ được truyền vào các tham số tương ứng trong phương thức bộ điều khiển (bắt đầu từ tham số thứ hai), ví dụ:
// Khớp /user/123 /user/abc
Route::any('/user/{id}', [app\controller\UserController::class, 'get']);
namespace app\controller;
use support\Request;
class UserController
{
public function get(Request $request, $id)
{
return response('Nhận tham số '.$id);
}
}
Nhiều ví dụ hơn:
use support\Request;
// Khớp /user/123, không khớp /user/abc
Route::any('/user/{id:\d+}', function (Request $request, $id) {
return response($id);
});
// Khớp /user/foobar, không khớp /user/foo/bar
Route::any('/user/{name}', function (Request $request, $name) {
return response($name);
});
// Khớp /user /user/123 và /user/abc [] biểu thị tùy chọn
Route::any('/user[/{name}]', function (Request $request, $name = null) {
return response($name ?? 'tom');
});
// Khớp bất kỳ yêu cầu nào có tiền tố /user/
Route::any('/user/[{path:.+}]', function (Request $request) {
return $request->path();
});
// Khớp tất cả các yêu cầu options : sau đó là biểu thức chính quy, biểu thị quy tắc chính quy cho tham số được đặt tên này
Route::options('[{path:.+}]', function () {
return response('');
});
Tóm tắt cách sử dụng nâng cao
[]
cú pháp trong định tuyến Webman chủ yếu được sử dụng để xử lý các phần đường dẫn tùy chọn hoặc khớp các định tuyến động, cho phép bạn xác định cấu trúc đường dẫn và quy tắc khớp phức tạp hơn cho các định tuyến
: được sử dụng để chỉ định biểu thức chính quy
Nhóm định tuyến
Đôi khi, định tuyến chứa nhiều tiền tố giống nhau, lúc này chúng ta có thể sử dụng nhóm định tuyến để đơn giản hóa định nghĩa. Ví dụ:
Route::group('/blog', function () {
Route::any('/create', function (Request $request) {return response('create');});
Route::any('/edit', function (Request $request) {return response('edit');});
Route::any('/view/{id}', function (Request $request, $id) {return response("view $id");});
});
Tương đương với
Route::any('/blog/create', function (Request $request) {return response('create');});
Route::any('/blog/edit', function (Request $request) {return response('edit');});
Route::any('/blog/view/{id}', function (Request $request, $id) {return response("view $id");});
Sử dụng lồng nhóm nhóm
Route::group('/blog', function () {
Route::group('/v1', function () {
Route::any('/create', function (Request $request) {return response('create');});
Route::any('/edit', function (Request $request) {return response('edit');});
Route::any('/view/{id}', function (Request $request, $id) {return response("view $id");});
});
});
Middleware định tuyến
Chúng ta có thể thiết lập middleware cho một định tuyến hoặc một nhóm định tuyến.
Ví dụ:
Route::any('/admin', [app\admin\controller\IndexController::class, 'index'])->middleware([
app\middleware\MiddlewareA::class,
app\middleware\MiddlewareB::class,
]);
Route::group('/blog', function () {
Route::any('/create', function () {return response('create');});
Route::any('/edit', function () {return response('edit');});
Route::any('/view/{id}', function ($request, $id) {response("view $id");});
})->middleware([
app\middleware\MiddlewareA::class,
app\middleware\MiddlewareB::class,
]);
# Ví dụ sử dụng sai (cách sử dụng này hiệu quả khi webman-framework >= 1.5.7)
Route::group('/blog', function () {
Route::group('/v1', function () {
Route::any('/create', function (Request $request) {return response('create');});
Route::any('/edit', function (Request $request) {return response('edit');});
Route::any('/view/{id}', function (Request $request, $id) {return response("view $id");});
});
})->middleware([
app\middleware\MiddlewareA::class,
app\middleware\MiddlewareB::class,
]);
# Ví dụ sử dụng đúng
Route::group('/blog', function () {
Route::group('/v1', function () {
Route::any('/create', function (Request $request) {return response('create');});
Route::any('/edit', function (Request $request) {return response('edit');});
Route::any('/view/{id}', function (Request $request, $id) {return response("view $id");});
})->middleware([
app\middleware\MiddlewareA::class,
app\middleware\MiddlewareB::class,
]);
});
Định tuyến kiểu tài nguyên
Route::resource('/test', app\controller\IndexController::class);
//Định tuyến tài nguyên chỉ định
Route::resource('/test', app\controller\IndexController::class, ['index','create']);
//Định tuyến tài nguyên không định nghĩa
// Ví dụ truy cập notify sẽ là định tuyến kiểu any /test/notify hoặc /test/notify/{id} đều được, routeName là test.notify
Route::resource('/test', app\controller\IndexController::class, ['index','create','notify']);
Động từ | URI | Hành động | Tên định tuyến |
---|---|---|---|
GET | /test | index | test.index |
GET | /test/create | create | test.create |
POST | /test | store | test.store |
GET | /test/{id} | show | test.show |
GET | /test/{id}/edit | edit | test.edit |
PUT | /test/{id} | update | test.update |
DELETE | /test/{id} | destroy | test.destroy |
PUT | /test/{id}/recovery | recovery | test.recovery |
Tạo URL
Lưu ý
Tạm thời không hỗ trợ tạo URL cho nhóm lồng ghép
Ví dụ định tuyến:
Route::any('/blog/{id}', [app\controller\BlogController::class, 'view'])->name('blog.view');
Chúng ta có thể sử dụng phương pháp sau để tạo URL cho định tuyến này.
route('blog.view', ['id' => 100]); // Kết quả là /blog/100
Khi sử dụng URL của định tuyến trong giao diện, bạn có thể sử dụng phương pháp này, điều này sẽ tránh việc phải thay đổi rất nhiều tệp giao diện do sự thay đổi của quy tắc định tuyến.
Lấy thông tin định tuyến
Thông qua đối tượng $request->route
, chúng ta có thể lấy thông tin định tuyến hiện tại, ví dụ
$route = $request->route; // Tương đương với $route = request()->route;
if ($route) {
var_export($route->getPath());
var_export($route->getMethods());
var_export($route->getName());
var_export($route->getMiddleware());
var_export($route->getCallback());
var_export($route->param());
}
Lưu ý
Nếu yêu cầu hiện tại không khớp với bất kỳ định tuyến nào trong tệp cấu hình config/route.php, thì$request->route
sẽ là null, có nghĩa là khi thực hiện định tuyến mặc định,$request->route
sẽ là null
Xử lý 404
Khi định tuyến không tìm thấy, mặc định sẽ trả về trạng thái 404 và xuất nội dung liên quan đến 404.
Nếu lập trình viên muốn can thiệp vào quy trình doanh nghiệp khi không tìm thấy định tuyến, có thể sử dụng phương pháp Route::fallback($callback)
mà webman cung cấp. Ví dụ, logic mã dưới đây là khi không tìm thấy định tuyến sẽ chuyển hướng về trang chính.
Route::fallback(function(){
return redirect('/');
});
Ví dụ khác là khi định tuyến không tồn tại sẽ trả về dữ liệu json, điều này rất hữu ích khi webman hoạt động như một giao diện API.
Route::fallback(function(){
return json(['code' => 404, 'msg' => '404 không tìm thấy']);
});
Thêm middleware cho 404
Yêu cầu 404 mặc định sẽ không chạy qua bất kỳ middleware nào, nếu cần thêm middleware cho yêu cầu 404, hãy tham khảo mã dưới đây.
Route::fallback(function(){
return json(['code' => 404, 'msg' => '404 không tìm thấy']);
})->middleware([
app\middleware\MiddlewareA::class,
app\middleware\MiddlewareB::class,
]);
Liên kết liên quan Tùy chỉnh trang 404 500
Vô hiệu hóa định tuyến mặc định
// Vô hiệu hóa định tuyến mặc định của dự án chính, không ảnh hưởng đến plugin ứng dụng
Route::disableDefaultRoute();
// Vô hiệu hóa định tuyến của ứng dụng admin trong dự án chính, không ảnh hưởng đến plugin ứng dụng
Route::disableDefaultRoute('', 'admin');
// Vô hiệu hóa định tuyến mặc định của plugin foo, không ảnh hưởng đến dự án chính
Route::disableDefaultRoute('foo');
// Vô hiệu hóa định tuyến mặc định của ứng dụng admin trong plugin foo, không ảnh hưởng đến dự án chính
Route::disableDefaultRoute('foo', 'admin');
// Vô hiệu hóa định tuyến mặc định của bộ điều khiển [\app\controller\IndexController::class, 'index']
Route::disableDefaultRoute([\app\controller\IndexController::class, 'index']);
Ghi chú vô hiệu hóa định tuyến mặc định
Chúng ta có thể sử dụng ghi chú để vô hiệu hóa định tuyến mặc định của một bộ điều khiển, ví dụ:
namespace app\controller;
use support\annotation\DisableDefaultRoute;
#[DisableDefaultRoute]
class IndexController
{
public function index()
{
return 'index';
}
}
Tương tự, chúng ta cũng có thể sử dụng ghi chú để vô hiệu hóa định tuyến mặc định của một bộ điều khiển, ví dụ:
namespace app\controller;
use support\annotation\DisableDefaultRoute;
class IndexController
{
#[DisableDefaultRoute]
public function index()
{
return 'index';
}
}
Giao diện định tuyến
// Thiết lập định tuyến cho yêu cầu bất kỳ phương thức nào với $uri
Route::any($uri, $callback);
// Thiết lập định tuyến cho yêu cầu get với $uri
Route::get($uri, $callback);
// Thiết lập định tuyến cho yêu cầu post với $uri
Route::post($uri, $callback);
// Thiết lập định tuyến cho yêu cầu put với $uri
Route::put($uri, $callback);
// Thiết lập định tuyến cho yêu cầu patch với $uri
Route::patch($uri, $callback);
// Thiết lập định tuyến cho yêu cầu delete với $uri
Route::delete($uri, $callback);
// Thiết lập định tuyến cho yêu cầu head với $uri
Route::head($uri, $callback);
// Thiết lập định tuyến cho yêu cầu options với $uri
Route::options($uri, $callback);
// Cùng lúc thiết lập nhiều loại yêu cầu bằng định tuyến
Route::add(['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'], $uri, $callback);
// Nhóm định tuyến
Route::group($path, $callback);
// Định tuyến tài nguyên
Route::resource($path, $callback, [$options]);
// Vô hiệu hóa định tuyến
Route::disableDefaultRoute($plugin = '');
// Định tuyến rơi, thiết lập đường dẫn dự phòng cho định tuyến mặc định
Route::fallback($callback, $plugin = '');
// Lấy tất cả thông tin định tuyến
Route::getRoutes();
Nếu uri không có định tuyến tương ứng (bao gồm cả định tuyến mặc định), và định tuyến rơi cũng chưa được thiết lập, thì sẽ trả về 404.
Nhiều tệp cấu hình định tuyến
Nếu bạn muốn sử dụng nhiều tệp cấu hình định tuyến để quản lý định tuyến, ví dụ như trong trường hợp Nhiều ứng dụng khi mỗi ứng dụng cần có tệp cấu hình định tuyến riêng, bạn có thể sử dụng cách require
để tải các tệp cấu hình định tuyến bên ngoài.
Ví dụ trong tệp config/route.php
<?php
// Tải cấu hình định tuyến dưới ứng dụng admin
require_once app_path('admin/config/route.php');
// Tải cấu hình định tuyến dưới ứng dụng api
require_once app_path('api/config/route.php');