Правильно ли?

Viktor86

Новичок
Здравствуйте. Относительно недавно начал изучать PHP. Вот дошло дело до единой точки входа. Написал (кое-что скопировал :)) FrontController. Работает!

Подскажите, пожалуйста, правильно ли все написал, если нет, скажите как лучше сделать:
PHP:
namespace main;

class Application {
   
    private $controller    = "index";
    private $action        = "index";
    private $model;
    private $params = array();

    public function __construct($config) {
       
        $path = $this->getUri();
       
        $request = explode("/", $path, 3);
       
        // Выбор контроллера
        if (!empty($request[0])) {
            $this->controller = $request[0];
        }
       
        // Выбор действия
        if (!empty($request[1])) {
            $this->action = $request[1];
        }

        // Выбор параметров
        if (!empty($request[2])) {
            $this->setParams($request[2]);
        }

        // Добавление префиксов
        $this->controller = ucfirst($this->controller) . 'Controller';
        $this->model = ucfirst($this->controller) . 'Model';
        $this->action = 'action' . ucfirst($this->action);
       
        $basePath = $config['basePath'];
        $dir = DIRECTORY_SEPARATOR;
       
        // Абсолютный путь к классу
        $controllerPath = $basePath . $dir . 'controllers' . $dir . $this->controller . '.php';
        $modelPath = $basePath . $dir . 'models' . $dir . $this->controller . '.php';
               
        // Подключаем контроллер
        if (file_exists($controllerPath)) {
           
            require_once $controllerPath;
           
            // Подключаем модель
            if (file_exists($modelPath)) {
                require_once $modelPath;
            }
           
            $cont = "app\controllers\\".$this->controller;
           
            $controller = new $cont;
            $action = $this->action;
           
            if (method_exists($controller, $action)) {
                $controller->$action($this->params);
            } else {
                // ИСКЛЮЧЕНИЕ
                die($this->action . " не существует!");
            }
        } else {
            // ИСКЛЮЧЕНИЕ
            die($this->controller . " не существует!");
        }
    }

    private function getUri() {
        $uri = trim($_SERVER["REQUEST_URI"],"/");
        return preg_replace('/[^a-zA-Z0-9]\//', "", $uri);
    }
   
    private function setParams($param) {
        $split = explode('/', $param);
       
        $key = array();
        $value = array();
               
        for($i=0;$i<count($split);$i++) {
            if($i % 2 == 0) {
                $key[] = $split[$i];
            } else {
                $value[] = $split[$i];
            }
        }
        $this->params = array_combine($key, $value);
    }
}
PS:
Не пишу фреймворк, не пишу сайт - написал для практики!!!

Заранее спасибо
 

AnrDaemon

Продвинутый новичок
Их не надо изучать, их надо применять.

throw new Exception('Description', code);

Так сложно, что ли?…
 

antson

Новичок
Партнер клуба
$uri = trim($_SERVER["REQUEST_URI"],"/");
return preg_replace('/[^a-zA-Z0-9]\//', "", $uri);

в таком виде у тебя следующие траблы
1)
http://sait/a-a/b-b/
идентично
http://sait/aa/bb/

в аргументах нельзя использовать русские буквы и знак процента. Поиск с постраничной навигацией как будем делать?

2)
Жестко зашита структура сайта в именах классов и методов
исходный ури нужно прогонять еще через роутер
чтобы вместо
Н-р: /n/blabla.html на анализ шло news/viewbyslug/blabla

в плане безопасности нет ничего.

В общем еще очень сыро

3) на счет die в таком виде ты покажешь страшную страницу с кодом 200 , а нужно всего один раз обработать исключение и отрисовать 404 или 500 .
 
Последнее редактирование:

AnrDaemon

Продвинутый новичок
Ой, про getUri() я вообще боюсь начинать…
Это одна большая ошибка.
Вместо него должен был быть setUri() на самом деле.
А getUri простой геттер из проперти.
 

antson

Новичок
Партнер клуба
учитывая, что все вызовы контролеров и моделей идут из конструктора . сеттер не удастся вызвать .
 

Viktor86

Новичок
Их не надо изучать, их надо применять.

throw new Exception('Description', code);

Так сложно, что ли?…
Дело не в сложности. Просто, мне на данный момент интересен конкретно данный класс, а исключения - это уже второстепенно (не рабочий же проект)

$uri = trim($_SERVER["REQUEST_URI"],"/");
return preg_replace('/[^a-zA-Z0-9]\//', "", $uri);

в таком виде у тебя следующие траблы
1)
http://sait/a-a/b-b/
идентично
http://sait/aa/bb/
Как лучше реализовать данную функцию?

в аргументах нельзя использовать русские буквы и знак процента. Поиск с постраничной навигацией как будем делать?
С постраничный навигацией как быть, особо не задумывался (т.к. понятия не имею, что да как). Была мысль через параметры

2)
Жестко зашита структура сайта в именах классов и методов
исходный ури нужно прогонять еще через роутер
чтобы вместо
Н-р: /n/blabla.html на анализ шло news/viewbyslug/blabla
Как сделать роутер подробного описания не нашел.

в плане безопасности нет ничего.
Что посоветуете по поводу защиты?

Этот пример слепил из нескольких статей, что нашел более менее (по отзывам) нормальное

PS
В общем как лучше сделать все это дело?
Если есть хорошие примеры единой точки входа с роутером, автозагрузкой классов, и правильной защитой - буду очень благодарен. Ведь на всех сайтах пишут - "у нас правильно", я думаю вам виднее как правильно!!!
 

Adelf

Administrator
Команда форума
Ну вот тебе примерчик:

https://github.com/yiisoft/yii2/blob/master/framework/web/Request.php

Этот класс занимается разбором веб-запроса. Класс Application просто его использует. Каждый класс должен заниматься специфичной задачей. Роутинг на контроллеры - тоже отдельная задача. И ее надо делать в другом классе. Разумеется тебе пока сложно красиво все это декомпозировать. Но учись потихоньку.

P.S. Что в классе Request в Yii2 делает обработка csrf токена и еще пара левых вещей?
 

Adelf

Administrator
Команда форума
Ой, блин. Эксперты-перфекционисты. Для новичка любой пример более-менее пригодного фреймворка - полезный опыт. И разницы большой нет - есть там мелкие огрехи или нет.

Я просто глядел Yii2 и дал попутно ссылку.
 
Сверху