whereNumber('page')->name('articles.page')
if (preg_match('#^/articles/page/([^/]+)$#', $cleanUri, $m)) {
$page = $m[1];
if (preg_match('/^[0-9]+$/', $page)) {
return [
'matched' => true,
'http_code' => 200,
'route_name' => 'articles.page',
'pattern' => '/articles/page/{page}',
'constraint' => "whereNumber('page') // ^[0-9]+$",
'params' => ['page' => (int) $page],
'action' => 'Closure(int $page)',
'output' => "Đang xem danh sách bài viết tại trang số: {$page}",
];
}
return [
'matched' => false,
'http_code' => 404,
'route_name' => 'articles.page (Vi phạm ràng buộc whereNumber)',
'pattern' => '/articles/page/{page}',
'constraint' => "Tham số {page} = '{$page}' không khớp chữ số [0-9]+",
'params' => [],
'action' => 'Abort 404 Not Found',
'output' => "404 Not Found - Tham số {page} chỉ chấp nhận chữ số nguyên dương.",
];
}
// 2. Route: GET /articles/archive/{slug?} -> where('slug', '[a-z0-9-]+')->name('articles.slug')
if (preg_match('#^/articles/archive(?:/([^/]+))?$#', $cleanUri, $m)) {
$slug = $m[1] ?? null;
if ($slug === null || $slug === '') {
return [
'matched' => true,
'http_code' => 200,
'route_name' => 'articles.slug',
'pattern' => '/articles/archive/{slug?}',
'constraint' => "where('slug', '[a-z0-9-]+') (Tham số tùy chọn bỏ trống -> nhận mặc định)",
'params' => ['slug' => 'tat-ca-bai-viet (Mặc định)'],
'action' => 'Closure(?string $slug = "tat-ca-bai-viet")',
'output' => 'Đang tra cứu bài viết theo slug: tat-ca-bai-viet',
];
}
if (preg_match('/^[a-z0-9-]+$/', $slug)) {
return [
'matched' => true,
'http_code' => 200,
'route_name' => 'articles.slug',
'pattern' => '/articles/archive/{slug?}',
'constraint' => "where('slug', '[a-z0-9-]+') // Hợp lệ",
'params' => ['slug' => $slug],
'action' => 'Closure(?string $slug)',
'output' => "Đang tra cứu bài viết theo slug: {$slug}",
];
}
return [
'matched' => false,
'http_code' => 404,
'route_name' => 'articles.slug (Vi phạm Regex)',
'pattern' => '/articles/archive/{slug?}',
'constraint' => "Slug '{$slug}' vi phạm Regex [a-z0-9-]+ (chứa chữ hoa hoặc ký tự đặc biệt)",
'params' => [],
'action' => 'Abort 404 Not Found',
'output' => "404 Not Found - Slug '{$slug}' không hợp lệ theo biểu thức chính quy [a-z0-9-]+.",
];
}
// 3. Route Group prefix('admin')->name('admin.')
if ($cleanUri === '/admin/dashboard') {
return [
'matched' => true,
'http_code' => 200,
'route_name' => 'admin.dashboard',
'pattern' => '/admin/dashboard',
'constraint' => "Route::prefix('admin')->name('admin.')",
'params' => [],
'action' => 'Closure (Admin Dashboard)',
'output' => 'Trang bảng điều khiển Quản trị viên (Admin Dashboard)',
];
}
if ($cleanUri === '/admin/articles') {
return [
'matched' => true,
'http_code' => 200,
'route_name' => 'admin.articles',
'pattern' => '/admin/articles',
'constraint' => "Route::prefix('admin')->name('admin.')",
'params' => [],
'action' => 'ArticleController@index',
'output' => 'Hiển thị danh sách bài viết trong phân hệ Quản trị (Admin Articles)',
];
}
return [
'matched' => false,
'http_code' => 404,
'route_name' => 'N/A',
'pattern' => 'Không khớp route nào',
'constraint' => 'N/A',
'params' => [],
'action' => 'Symfony\Component\HttpKernel\Exception\NotFoundHttpException',
'output' => "404 NOT FOUND - Không tìm thấy định tuyến cho đường dẫn '{$cleanUri}'",
];
}
$result = matchLaravelRoute($testUrl);
$routesCode = file_get_contents(__DIR__ . '/../routes/web.php');
$presetUrls = [
'/articles/page/2' => 'Hợp lệ: Tham số {page} = 2',
'/articles/page/abc' => 'Lỗi 404: {page} không phải là số',
'/articles/archive' => 'Hợp lệ: Bỏ trống {slug?} tùy chọn',
'/articles/archive/lam-chu-laravel-routing-nang-cao' => 'Hợp lệ: {slug?} khớp Regex [a-z0-9-]+',
'/articles/archive/Slug_Khong_Hop_Le!' => 'Lỗi 404: {slug?} chứa chữ hoa & ký tự _!',
'/admin/dashboard' => 'Hợp lệ: Route Group prefix admin/dashboard',
'/admin/articles' => 'Hợp lệ: Route Group prefix admin/articles',
];
?>
Bài 01: Routing nâng cao, Regex, Named Routes & Route Group - Lab 07
-
-
Chọn nhanh các kịch bản thử nghiệm:
HTTP = $result['http_code'] ?> = $result['matched'] ? 'OK (Route Matched)' : 'Not Found' ?>
= htmlspecialchars($testUrl) ?>
| Mẫu Route (URI) |
= htmlspecialchars($result['pattern']) ?> |
| Named Route |
= htmlspecialchars($result['route_name']) ?> |
| Ràng buộc / Group |
= htmlspecialchars($result['constraint']) ?> |
| Tham số thu được |
= htmlspecialchars(json_encode($result['params'], JSON_UNESCAPED_UNICODE)) ?> |
| Đích xử lý (Action) |
= htmlspecialchars($result['action']) ?> |
Response Output: = htmlspecialchars($result['output']) ?>
| URI Pattern |
Named Route |
Ràng buộc |
/articles/page/{page} |
articles.page |
whereNumber('page') |
/articles/archive/{slug?} |
articles.slug |
where('slug', '[a-z0-9-]+') |
/admin/dashboard |
admin.dashboard |
prefix('admin') |
/admin/articles |
admin.articles |
prefix('admin') |
= htmlspecialchars($routesCode) ?>