Класс маршрутизатор в MVC


Ниже то, что я придумал для системы маршрутизатора/диспетчер для моих личных рамок, над которыми я работаю. Можете вы, пожалуйста, комментарий и скажите мне, любые улучшения, которые могут быть сделаны?

Первая часть представляет собой массив Ури -> в метод класса//id_number/page_number с помощью regex. Я включил только частичный список маршрутов, там будет как минимум 50 возможных маршрутов, которые будут иметь, чтобы запустить регулярное выражение. Я думаю, что это очень плохо для производительности, но это, кажется, лучший способ я знаю, чтобы сделать это, так как мне нужно, чтобы соответствовать номер страницы и ID-номера, когда они есть.

Я новичок в MVC, так что это моя первая попытка и я уверен, что вы, ребята, можете дать мне повышение на этой, спасибо за любые советы или помощь!

.С. htaccess файл:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$   index.php?uri=$1    [NC,L,QSA]

Массив карты():

/**
 * Map URI to class/method and ID and Page numbers
 * Must be an array
 */
$uri_route_map = array( 
    //forums
    'forums/' => array(
        'controller' => 'forums',
        'method' => 'index',
        'id_number' => '',
        'page_number' => ''),

    'forums/viewforum/(?<id_number>\d+)' =>  array(
        'controller' => 'forums',
        'method' => 'viewforum',
        'id_number' => isset($id_number),
        'page_number' => ''),  

    'forums/viewthread/(?<id_number>\d+)' =>  array(
        'controller' => 'forums',
        'method' => 'viewthread',
        'id_number' => isset($id_number),
        'page_number' => ''),

    'forums/viewthread/(?<id_number>\d+)/page-(?<page_number>\d+)' =>  array(
        'controller' => 'forums',
        'method' => 'viewthread',
        'id_number' => isset($id_number),
        'page_number' => isset($page_number)),

    // user routes
    // account routes
    // blog routes 
    // mail routes
    // various other routes
);

Класс маршрутизатор, который читает и соответствует выше массиве карте

/**
 * Run URI against our Map array to get class/method/id-page numbers
 */
 class Router
{
    private $_controller = '';
    private $_method = '';
    public $page_number = '';
    public $id_number = '';

    public function __construct($uri, array $uri_route_map)
    {
        foreach ($uri_route_map as $rUri => $rRoute)
        {
            if (preg_match("#^{$rUri}$#Ui", $uri, $uri_digits))
            {
                //if page number and ID number in uri then set it locally
                $this->page_number = (isset($uri_digits['page_number']) ? $uri_digits['page_number'] : null);
                $this->id_number = (isset($uri_digits['id_number']) ? $uri_digits['id_number'] : null);
                $this->_controller = $rRoute['controller'];
                $this->_method = $rRoute['method'];

                // just for debug and testing while working on it / will be removed from final code
                echo '<hr> $page_number = ' . $this->page_number . '<br><br>';
                echo '<hr> $id_number = ' . $this->id_number . '<br><br>';
                echo '<hr> $controller = ' . $this->_controller . '<br><br>';
                echo '<hr> $method = ' . $this->_method . '<br><br>';
                break;
            }else{
                $this->page_number = '';
                $this->id_number = '';
                $this->_controller = '404';
                $this->_method = '404';
            }
        }
    }

    public function getController()
    {
        return $this->_controller;
    }

    public function getMethod()
    {
        return $this->_method;
    }

    public function getPageNumber()
    {
        return $this->page_number;
    }

    public function getIDNumber()
    {
        return $this->id_number;
    }

    /**
     * Call our class and method from values in the URI
     */
    public function dispatch()
    {
        if (file_exists('controller' . $this->_controller . '.php'))
        {
            include ('controller' . $this->_controller . '.php');
            $controllerName = 'Controller' . $this->_controller;
            $controller = new $controllerName($this->getIDNumber(),$this->getPageNumber());
            $method = $this->_method;
            if (method_exists($this->_controller, $this->_method))
            {
                return $controller->$method();
            } else {
                // method does not exist
            }
        } else {
            // Controller does not exist
        }
    }

}

Запустить его

/**
 * Testing the class
 */
$uri = isset($_GET['uri']) ? $_GET['uri'] : null;
$router = new Router($uri, $uri_route_map);
$router->dispatch();

?>


6115
8
задан 11 августа 2011 в 04:08 Источник Поделиться
Комментарии
2 ответа

Если вы можете ограничить Ури структуры с использованием разделителя - / приходит на ум - вы могли бы избежать регулярных выражений.

Вот грубый пример (не с любой конфигурацией, но показывает концепцию):

$uri = 'forums/viewforum/1';
$parts = explode('/', $uri);

$controller = $parts[0];
$method = $parts[1];
$id = parts[2];

Я взгляну на маршрутизаторе реализации ряда популярных фреймворков (моя рекомендация будет ЗФ роутер, но это только для меня) - нет ничего плохого от обучения, как кто-то другой решал такую же проблему.

7
ответ дан 12 августа 2011 в 04:08 Источник Поделиться

Кроме того, проверить 'Силекс' и 'тонкий', которые microframeworks, которые включают маршрутизацию, чтобы увидеть, как они решают эту проблему. Лично я думаю, что просто id_number и page_number носит ограничительный характер. В итоге вам понадобится больше сложность (и, возможно, параметры) передаются в каждом маршруте.

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

2
ответ дан 13 августа 2011 в 07:08 Источник Поделиться