Я сейчас использую Symfony2, а старые проекты на самописном
фреймворке, где свой роутер используется, но он у меня получился
как-то намного проще, и работает без проблем, например запрос:
example.com/bla
запустит контроллер
Controller_Bla и экшн
indexAction
example.com/bla/blum
Проверит, есть ли контроллер
Controller_Bla и метод в нем
blumAction
Если нет, то проверит, есть ли контроллер
Controller_Bla_Blum и метод в нем
indexAction
(последовательность может и другая, не суть, в коде видно будет)
Суть: я не прописываю нигде пути больше.
Если я создал Controller_Example и в нем testAction (ну плюс еще фреймворк проверяет шаблон для этого экшна),
то страница /example/test появляется у меня автоматом.
Вот код роутера:
public static function run()
{
$obj = null;
$action = false;
$pathCtrl = TS_CODE_DIR . '/Controller/';
$classCtrl = 'Controller_';
$redirect = isset($_SERVER['REDIRECT_URL']) ? $_SERVER['REDIRECT_URL'] : '';
if ( empty ($redirect) ) {
Ts_App::showMain();
}
$items = explode('/', $redirect);
$els = array();
for ($i=0; $i < count($items); $i++) {
if ( !empty($items[$i]) ) {
if ( !preg_match('/^[a-zA-Z0-9]+$/', $items[$i]) ) {
Ts_App::show404();
}
$els[] = ucfirst(strtolower($items[$i]));
}
}
$cnt = count($els);
for ($i=0; $i < $cnt; $i++) {
if ( $i < ($cnt - 1) ) {
$pathCtrl .= $els[$i] . '/';
$classCtrl .= $els[$i] . '_';
} else {
$pathCtrl .= $els[$i] . '.php';
$classCtrl .= $els[$i];
}
}
if ( file_exists($pathCtrl) && !is_dir($pathCtrl) ) {
$obj = new $classCtrl();
} else {
// проверка наличия экшна в родительском контроллере
preg_match('~(^.+)_([^_]+)$~', $classCtrl, $_crm);
if ( isset($_crm[1]) && isset($_crm[2]) ) {
$pathCtrl = preg_replace("~\/{$_crm[2]}\.php$~", '.php', $pathCtrl);
if ( file_exists($pathCtrl) ) {
$action = strtolower($_crm[2]);
$obj = new $_crm[1]();
}
}
}
if ( empty($obj) ) {
Ts_App::show404();
}
$obj->run($action);
}
Роутинг получается автоматическим.
Если есть нужный контроллер и экшн, то больше нигде ничего прописывать не нужно.
Точка входа приложения:
Ts_App::run();