Как правильно настроить роутинг в своём проекте?

245
19 августа 2018, 15:00

Я пишу свой небольшой учебный проект с нуля, не используя фреймворк. К сожалению, не смог найти какой то однозначной информации, по поводу того как правильно настроить роутинг.

В принципе, при ожидаемом поведении - всё работает.
Но если, например, обратится к файлу index.php напрямую - возникнет ошибка(ровно как и к любому другому php фалу). Если обратится к какой-либо папке - то доступ в неё тоже будет, а значит уже возможно будет посмотреть структуру проекта.
Даже при написании просто случайных символов в адресую строку - роутер попытается выполнить соответствующий метод.

Хотелось бы избавится от этих недочётов, что бы при обращении к несуществующим или не указанным в маршрутах файлам папкам перебрасывало, например, на главную страничку.

Ниже прикладываю содержимое роутера, маршрутов и .htaccess.

routes.php:

return array(
    'ajax/delFile/([0-9]+)' => 'ajax/delFile/$1',
    'ajax/delMessage/([0-9]+)' => 'ajax/delMessage/$1',
    'ajax/addPost/([0-9]+)' => 'ajax/addPost/$1',
    'ajax/addPost' => 'ajax/addPost',
    'editMessage/([0-9]+)' => 'message/editMessage/$1',
    'message/search' => 'message/searchMessage',
    'logout' => 'logout/logout',
    'ajax/register' => 'ajax/registerUser',
    'ajax/login' => 'ajax/loginUser',
    'sign-up' => 'signup/show',
    'message/([0-9]+)' => 'message/show/$1',
    '' => 'index/showAllMessages',
);

Router:

class Router
{
    private  $routes;
    public function __construct()
    {
        $routesPath = __DIR__ . '/../../App/Config/routes.php';
        $this->routes = require_once ($routesPath);
    }
    /**
     * Получаем строку запроса
     *
     * @return bool|string Строка запроса, либо false если строка запроса отсутствует
     */
    private function getURI()
    {
        if (!empty($_SERVER['REQUEST_URI'])) {
            return trim(str_replace('mvcguestbook', '', $_SERVER['REQUEST_URI']), '/');
        } else {
            return false;
        }
    }

    public function run()
    {
        $uri = $this->getURI();
        //Проверяем наличие запроса в routes.php
        foreach ($this->routes as $uriPattern => $path) {
            //Ищем в URI совпадение с регулярным выражением uriPattern
            if(preg_match("~$uriPattern~i", $uri)) {
                //Формируем из URI внутренний маршрут
                $internalRoute = preg_replace("~$uriPattern~i", $path, $uri);
                //Определяем контроллер, экшн и параметры
                $segments = explode('/', $internalRoute);
                $controllerName = 'App\\Controllers\\' . ucfirst(array_shift($segments) . 'Controller');
                $actionName = 'action'. ucfirst(array_shift($segments));
                $controllerObject = new $controllerName;
                $result = $controllerObject->$actionName($segments);
                if ($result != null) {
                    break;
                }
            }
        }
    }
}

.htaccess:

AddDefaultCharset utf-8
RewriteEngine on
RewriteBase /mvcguestbook
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php
Answer 1

Приходим к выводу, для других может быть полезно:

1) удалить последний, пустой роутер, и обрабатывать его отдельно через }else{...} - если тело цикла не было выполнено.

2) например пустой контроллер у вас сейчас = '', переделать его в '(.*)', а саму регулярку переделать в : "~^$uriPattern$~i"

P.S.

Обычно, у фреймов существует такое понятие как системные роуты, обычно они задаются в одном месте где и остальные (и их стоит сразу отделять от кастомных).

default_controller (обычно выводится на пустую уришку, для главной)

404 (если роут не был найден)

error (если были ошибки в скриптах, то вызывают этот контроллер, обычно для этого используют set_error_handler(), set_exception_handler(), register_shutdown_function())

Вот пример 3-ех системных роутов, их может быть больше.

READ ALSO
Каким образом очистить кэш страницы?

Каким образом очистить кэш страницы?

В файлеhtaccess прописано кэширование данных

205
Получение файла из <input type='file'>

Получение файла из <input type='file'>

Я сделал стилизованную загрузку файлов вот так:

188
Ошибка в Debian (version `GLIBCXX_3.4.21&#39; not found)

Ошибка в Debian (version `GLIBCXX_3.4.21' not found)

Хочу создать сервер для игрыПри запуске сервера пишет

204
Почему не распаковывается phar архив?

Почему не распаковывается phar архив?

'Fatal error: Uncaught UnexpectedValueException: phar "D:\sites\mysitelocal\mvc

203