Роутер (mvc+ооп)

AllReady

Новичок
Доброй ночи форумчане.
Недавно начал изучать MVC и ООП, и смотрел уроки, пытался понять как все устроено. Получился вот такой вот роутер. Оцените пожалуйста.
В папке app есть файл/класс роутера. И файл index.php где подключается роутер.
Какие важные замечания есть ? Что поправить ? С какими трудностями столкнусь в будущем ? Знаю что столкнусь, просто до реализации дальнейшей не доходят руки. Хотел попробовать написать легкий блог с авторизацией и регистрацией. Так сказать хочу попрактиковаться и стартануть изучать какой-нибудь не сложный фреймворк. Сейчас кроме как вывода новостей я ни на что не рассчитывал..
Вот ссылка: http://rghost.ru/7KXYj268B (ps архив)
Вот сам класс роутера:
PHP:
<?php

class Router {
    // массив с роутами
    private $routes = [];

    // отформатированный uri
    private $uri;

    // контроллер по умолчанию
    private $defaultController = 'ErrorController';

    // контроллер по умолчанию
    private $defaultControllerFile = 'ErrorController.php';

    // контроллер по умолчанию
    private $defaultAction = 'indexAction';

    // Magic construct передаем массиву все роуты
    public function __construct($uri) {
        $this->uri = $uri;
    }

    public function addRoute($uri, $controller_action) {
        if (!array_key_exists($uri, $this->routes)) {
            $this->routes[$uri] = $controller_action;
        } else {
            throw new Exception("Uri: '".$uri."' is already configured on the controller");
        }
    }

    // запуск роутера. если найден маршрут, то проверяется есть ли файл, и метод.
    // если все в порядке то в экшен передаем оставшиеся параметры после controller/action/$1/$2/$3...
    public function run() {
        $segments = [];
        foreach ($this->routes as $key => $value) {
            if (preg_match('#'.$key.'#', $this->uri)) {
                $formattedUri = preg_replace('#'.$key.'#', $value, $this->uri);
                $segments = explode('/', $formattedUri);
                $this->defaultController = ucfirst(array_shift($segments)).'Controller';
                $this->defaultControllerFile = $this->defaultController.'.php';
                $this->defaultAction = ucfirst(array_shift($segments)).'Action';
                break;
            }
        }

        if (file_exists(ROOT.'/app/controllers/'.$this->defaultControllerFile)) {
            include(ROOT.'/app/controllers/'.$this->defaultControllerFile);
            if (class_exists($this->defaultController)) {
                $controller = new $this->defaultController;
                if (method_exists($controller, $this->defaultAction)) {
                    call_user_func_array([$controller, $this->defaultAction], $segments);
                } else {
                    throw new Exception("Method not found: <b>".$this->defaultAction."</b> in ".$this->defaultController."");
                }
            } else {
                throw new Exception("Class not found: <b>".$this->defaultController."</b> in '/app/controllers/".$this->defaultControllerFile);
            }
        } else {
            throw new Exception("File not found: <b>'/app/controllers/".$this->defaultControllerFile."</b>");
        }
       
    }

}
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
Ну, уже могу сказать, что автолоад/composer ты не осилил. Минус.
 

AllReady

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

PHP:
spl_autoload_register(function ($name) {
    include ROOT.'/app/controllers/' . $name . '.Controller.php';
});
Кстати прошу прощения за прошлую тему, спешил и затупил..
 
Последнее редактирование:

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
Вообще обычно index.php - это точка входа, куда ты подключаешься свой bootstrap, в который уже подрубается autoload. Либо автолоадер сразу в index и т.д. Как там тебе удобнее. Не стоит зацикливаться на этом, вопрос был именно в применении благ цивилизации в лице composer и иже с ним.
 

AllReady

Новичок
Вообще обычно index.php - это точка входа, куда ты подключаешься свой bootstrap, в который уже подрубается autoload. Либо автолоадер сразу в index и т.д. Как там тебе удобнее. Не стоит зацикливаться на этом, вопрос был именно в применении благ цивилизации в лице composer и иже с ним.
Я действительно про это впервые слышу. Максимум что я делал компосером, так это скачивал фреймворки/библиотеки. В этом я тоже не разбираюсь. Пытаюсь разобраться...
А как связан композер с самими сайтами ?
 

Redjik

Джедай-мастер
@AllReady, ты уж определись или camelCase или snake_case, а так вполне сносно для учебы.
 

AllReady

Новичок
@AllReady, ты уж определись или camelCase или snake_case, а так вполне сносно для учебы.
стараюсь придерживаться camelCase. Сейчас реализовал добавление роутов:
index.php:
PHP:
ini_set('display_errors', 1);
error_reporting('E_ALL');
define('ROOT', dirname(__FILE__));

// подключаем файл с классом роутер
include(ROOT.'/app/Router.php');

// форматируем строку запроса
$formattedUri = trim($_SERVER['REQUEST_URI'], '/');

spl_autoload_register(function ($name) {
    include ROOT.'/app/controllers/' . $name . '.Controller.php';
});

// создаем объект и передаем в конструктор форматированную строку и массив с роутами
$router = new Router($formattedUri);
try {
    // todo перенести добавление роутов в отдельный файл, пока оставил для отладки
    $router->addRoute('news/([A-z]+)/([0-9]+)', 'news/getById/$1/$2');
    $router->addRoute('news/toplist', 'news/toplist');
    $router->addRoute('news', 'news/index');
    $router->addRoute('films', 'films/index');
    $router->run();
} catch (Exception $e) {
    echo $e->getMessage();
}
Класс роутера:
PHP:
class Router {
    // массив с роутами
    private $routes = [];

    // отформатированный uri
    private $uri;

    // контроллер по умолчанию
    private $defaultController = 'ErrorController';

    // контроллер по умолчанию
    private $defaultControllerFile = 'ErrorController.php';

    // контроллер по умолчанию
    private $defaultAction = 'indexAction';

    // Magic construct передаем массиву все роуты
    public function __construct($uri) {
        $this->uri = $uri;
    }

    public function addRoute($uri, $controller_action) {
        if (!array_key_exists($uri, $this->routes)) {
            $this->routes[$uri] = $controller_action;
        } else {
            throw new Exception("Uri: '".$uri."' is already configured on the controller");
        }
    }

    // запуск роутера. если найден маршрут, то проверяется есть ли файл, и метод.
    // если все в порядке то в экшен передаем оставшиеся параметры после controller/action/$1/$2/$3...
    public function run() {
        $segments = [];
        foreach ($this->routes as $key => $value) {
            if (preg_match('#'.$key.'#', $this->uri)) {
                $formattedUri = preg_replace('#'.$key.'#', $value, $this->uri);
                $segments = explode('/', $formattedUri);
                $this->defaultController = ucfirst(array_shift($segments)).'Controller';
                $this->defaultControllerFile = $this->defaultController.'.php';
                $this->defaultAction = ucfirst(array_shift($segments)).'Action';
                break;
            }
        }

            if (class_exists($this->defaultController)) {
                $controller = new $this->defaultController;
                if (method_exists($controller, $this->defaultAction)) {
                    call_user_func_array([$controller, $this->defaultAction], $segments);
                } else {
                    throw new Exception("Method not found: <b>".$this->defaultAction."</b> in ".$this->defaultController."");
                }
            } else {
                throw new Exception("Class not found: <b>".$this->defaultController."</b> in '/app/controllers/".$this->defaultControllerFile);
            }
        } 
      
    }

}
 
Сверху