@QNA-1976

Как организовать ЧПУ роутинг?

Роутер

<?php


namespace core;


use Error;

class Router
{
    private static $routes = [];
    private static $route = [];

    private static function removeQueryString($url)
    {
        if ($url) {
            $params = explode('&', $url, 2);
            if (strpos($params[0], '=') === false) {
                return rtrim($params[0], '/');
            }
        }
        return '';
    }

    private static function upperCamelCase($name)
    {
        return str_replace(' ', '', ucwords(str_replace('-', ' ', $name)));
    }

    private static function lowerCamelCase($name)
    {
        return lcfirst(self::upperCamelCase($name));
    }

    private static function matchRoute($url)
    {
        foreach (self::$routes as $pattern => $route) {
            if (preg_match("@{$pattern}@i", $url, $matches)) {
                foreach ($matches as $k => $v) {
                    if (is_string($k)) {
                        $route[$k] = $v;
                    }
                }
                if (!isset($route['action'])) {
                    $route['action'] = 'index';
                }
                self::$route['controller'] = self::upperCamelCase($route['controller']);
                self::$route['action'] = self::lowerCamelCase($route['action']);
                return true;
            }
        }
        return false;
    }

    public static function add($regex, $route = [])
    {
        self::$routes[$regex] = $route;
    }

    public static function dispatch($url)
    {
        if (self::matchRoute(self::removeQueryString($url))) {
            $controller = 'app\controllers\\' . self::$route['controller'] . 'Controller';
            if (class_exists($controller)) {
                $cObj = new $controller(self::$route);
                $action = self::$route['action'] . 'Action';
                if (method_exists($cObj, $action)) {
                    $cObj->$action();
                    $cObj->getView();
                } else {
                    throw new Error("Метод {$controller}::{$action} не найден", 404);
                }
            } else {
                throw new Error("Контроллер {$controller} не найден", 404);
            }
        } else {
            throw new Error('Страница не найдена', 404);
        }
    }
}


.htaccess
DirectorySlash off

RewriteEngine on

RewriteCond %{HTTPS}_%{HTTP_HOST} ^(?|off_(?:www\.)?(.*)|on_www\.(.*)) [NC]
RewriteRule .* https://%1/$0 [R=301,L]

RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{DOCUMENT_ROOT}/public/$0 !-f
RewriteCond %{DOCUMENT_ROOT}/public/$0 !-d
RewriteRule .* /public/index.php?$0 [L,QSA]

RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule .* /public/$0 [L]

дефолтные правила
Router::add('^$', ['controller' => 'Main']);
Router::add('^(?P<controller>[a-z-]+)/?(?P<action>[a-z-]+)?$');

Как организовать ссылки вида:
/controller/2 вместо /controller?page=2
/controller/action/2 вместо /controller/action?page=2
Что тут нужно сделать? Никогда не делал ЧПУ раньше.
  • Вопрос задан
  • 187 просмотров
Решения вопроса 1
Kulaxyz
@Kulaxyz
Могу лучше
Также разбивать по слешу и проверять второй параметр. В зависимости он чисто или строка вызывать соответствующий метод.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы