Пожалуйста, рассмотрите следующие очень элементарные «контроллеры» (функции в данном случае для простоты):
function Index() {
var_dump(__FUNCTION__); // show the "Index" page
}
function Send($n) {
var_dump(__FUNCTION__, func_get_args()); // placeholder controller
}
function Receive($n) {
var_dump(__FUNCTION__, func_get_args()); // placeholder controller
}
function Not_Found() {
var_dump(__FUNCTION__); // show a "404 - Not Found" page
}
И следующая основанная на регулярных выражениях Route()
функция :
function Route($route, $function = null)
{
$result = rtrim(preg_replace('~/+~', '/', substr($_SERVER['PHP_SELF'], strlen($_SERVER['SCRIPT_NAME']))), '/');
if (preg_match('~' . rtrim(str_replace(array(':any', ':num'), array('[^/]+', '[0-9]+'), $route), '/') . '$~i', $result, $matches) > 0)
{
exit(call_user_func_array($function, array_slice($matches, 1)));
}
return false;
}
Теперь я хочу сопоставить следующие URL-адреса (конечные слэши игнорируются) с соответствующими «контроллерами»:
/index.php -> Index()
/index.php/send/:NUM -> Send()
/index.php/receive/:NUM -> Receive()
/index.php/NON_EXISTENT -> Not_Found()
Это та часть, где все становится сложнее, яУ меня две проблемы, которые я не могу решить ... Я полагаю, что я не первый, у кого есть эта проблема, поэтому кто-то там должен иметь решение.
Поймать 404 (Решено!)
Я не могу найти способ различить запросы к корню (index.php
) и запросы, которые не должны существовать, например (index.php/notHere
).Я заканчиваю тем, что обслуживаю маршрут по умолчанию index.php
для URL, которые в противном случае должны обслуживаться на странице ошибки 404 - Not Found
. Как я могу решить эту проблему?
РЕДАКТИРОВАТЬ - Решение просто мелькнуло у меня в голове:
Route('/send/(:num)', 'Send');
Route('/receive/(:num)', 'Receive');
Route('/:any', 'Not_Found'); // use :any here, see the problem bellow
Route('/', 'Index');
Заказ маршрутов
Если я настрою маршруты в «логическом» порядке, например:
Route('/', 'Index');
Route('/send/(:num)', 'Send');
Route('/receive/(:num)', 'Receive');
Route(':any', 'Not_Found');
Все URL-запросы отлавливаются контроллером Index()
, начиная с пустого регулярного выражения (помните: завершающие косые черты игнорируются ) соответствует всему.Однако, если я определяю маршруты в «хакерском» порядке, например:
Route('/send/(:num)', 'Send');
Route('/receive/(:num)', 'Receive');
Route('/:any', 'Not_Found');
Route('/', 'Index');
Все кажется работать так, как должно. Существует ли элегантный способ решения этой проблемы?
Маршруты не всегда могут быть жестко запрограммированы (извлечены из БД или чего-то в этом роде), и мне нужно убедиться, что он победил 'не игнорировать любые маршруты из-за порядка, в котором они были определены. Любая помощь приветствуется!