Thay vì viết một tuyến đường để khớp với bất kỳ thứ gì ngoài các chuỗi tĩnh nhất định, tôi thấy rõ ràng hơn khi viết hai tuyến đường: một tuyến đường khớp với các chuỗi tĩnh nhất định và một tuyến đường khác để khớp với mọi thứ khác.
// route that matches forbidden static strings, optionally with a postfix slug
$router->get('/{forbidden}/{optional_path?}', function () {
return response('Not found', 404);
})->where([ 'forbidden' => '(?:string1|string2)', 'optional_path' => '.*' ]);
// route that matches anything else (order of definition matters, must be last)
// might also consider using Route::fallback(), but I prefer to leave that
// alone in case my future self changes this below and opens up a hole
$router->get('/{anything?}', function () {
return response('Found', 200);
})->where([ 'anything' => '.*' ]);
Kết quả nào trong * :
domain
=> 200 Tìm thấy
domain/
=> 200 Tìm thấy
domain/abc
=> 200 Tìm thấy
domain/string1
=> 404 Không tìm thấy
domain/string1/
=> 404 Không tìm thấy
domain/string1/abc
=> 404 Không tìm thấy
domain/string10
=> 200 Tìm thấy
domain/string10/
=> 200 Tìm thấy
domain/string10/abc
=> 200 Tìm thấy
domain/string2
=> 404 Không tìm thấy
domain/string2/
=> 404 Không tìm thấy
domain/string2/abc
=> 404 Không tìm thấy
domain/string20
=> 200 Tìm thấy
domain/string20/
=> 200 Tìm thấy
domain/string20/abc
=> 200 Tìm thấy
Tôi thấy điều này rõ ràng hơn, vì tôi không phải suy nghĩ về các loại trừ. Thay vào đó, tôi có thể nghĩ đến việc khớp chính xác những gì tôi muốn cấm, sau đó để cho Laravel phản ứng với mọi thứ khác (thất bại trong chính sách mở). Điều này có thể không đáp ứng các tiêu chí thiết kế của bạn, nhưng tôi tin rằng nó dẫn đến mã rõ ràng hơn.
Ngoài ra, mã là hiệu suất hơn. ?!
phải quay lại, theo định nghĩa là đắt hơn so với kết hợp chuyển tiếp.
Tôi không có môi trường Laravel trong tay, nhưng tôi sẽ đoán xem tại sao những nỗ lực của bạn không hiệu quả. Laravel sử dụng Symfony Router, không hỗ trợ nhìn trên sên . IIRC, khi phát hiện ra một cái nhìn, Symfony áp dụng giao diện đó cho toàn bộ URL, chứ không phải con sên mà bạn đã ràng buộc mẫu. Điều này gây rối với ý tưởng của nhà phát triển về cách các ký tự meta (^, $) và meta (*) tham lam hoạt động. Điều này có thể dẫn đến một trải nghiệm tồi tệ khi cố gắng làm cho nó hoạt động, vì nhà phát triển hoạt động theo một giả định nhưng các thư viện cơ bản hoạt động trên một cái khác.
* Tiết lộ đầy đủ, tôi đã viết cái này cho Lumen sau đó chuyển đổi nó thành định dạng Laravel. Có thể có một số lỗi dịch thuật. Đây là Lumen gốc:
$router->get('/{forbidden:(?:string1|string2)}[/{optional_path:.*}]', function () {
return response('Not found', 404);
});
$router->get('{anything:.*}', function () {
return response('Found', 200);
});