Intereting Posts
Как преобразовать время mysql Проверьте, была ли еще вызвана функция Ошибка «Regular Expression is too large» в PHP Обновить все строки в базе данных с хэш-значением Ошибка CakePHP Bake Shell: соединение с базой данных «Mysql» отсутствует или не может быть создано PHP ORM: Доктрина против Propel PHP Если заявление с несколькими условиями Каков наилучший способ отразить результаты из базы данных в html-код в PHP? phpunit mock метод несколько вызовов с разными аргументами Как сохранить дату в базе данных на основе разных календарей? что является основной причиной «ошибки выхода из сегментации pid 10708« Ошибка сегментации (11) »? Показать случайный результат mysql Найти все hrefs на странице и заменить ссылку, поддерживающую предыдущую ссылку – PHP MySQL – получение таблицы HTML из базы данных – обратная косая черта перед символом котировки Неоднозначная колонка в инструкции INNER JOIN

как построить хороший маршрутизатор для php mvc

Я экспериментирую с php mvc, и у меня возникла следующая проблема. Мои классы запросов и маршрутизаторов очень просты, и я хотел бы расширить тему, чтобы обрабатывать вызовы контроллеров из подпапок и к классам контроллеров, функции должны быть в состоянии забрать URL-адреса, посылать их, чтобы получить и отправить.

мой маршрутизатор выглядит так, как следует

class Router{ public static function route(Request $request){ $controller = $request->getController().'Controller'; $method = $request->getMethod(); $args = $request->getArgs(); $controllerFile = __SITE_PATH.'/controllers/'.$controller.'.php'; if(is_readable($controllerFile)){ require_once $controllerFile; $controller = new $controller; if(!empty($args)){ call_user_func_array(array($controller,$method),$args); }else{ call_user_func(array($controller,$method)); } return; } throw new Exception('404 - '.$request->getController().'--Controller not found'); } } 

и класс запроса

  private $_controller; private $_method; private $_args; public function __construct(){ $parts = explode('/',$_SERVER['REQUEST_URI']); $this->_controller = ($c = array_shift($parts))? $c: 'index'; $this->_method = ($c = array_shift($parts))? $c: 'index'; $this->_args = (isset($parts[0])) ? $parts : array(); } public function getController(){ return $this->_controller; } public function getMethod(){ return $this->_method; } public function getArgs(){ return $this->_args; } } 

Проблема в том, что когда я пытаюсь отправить бросил ajax, переменные к методу контроллера не распознаются из-за структуры URL-адреса. Например

 index/ajax?mod_title=shop+marks&domain=example 

принимается, только если он выглядит

 index/ajax/shop+mark/example 

Ваш код содержит так называемую уязвимость LFI и опасен в текущем состоянии.
Вы должны использовать белый список того, что может использоваться как ваш $controller , так как в противном случае злоумышленник может попытаться указать что-то, используя NUL-байты, и, возможно, переместиться в каталог, чтобы включить файлы, которые НЕ ДОЛЖНЫ быть включены, например /etc/passwd , config файл, что угодно.

Ваш маршрутизатор небезопасен для использования; берегитесь!

edit: пример по белым спискам

 $safe = array( 'ajax', 'somecontroller', 'foo', 'bar', ); if(!in_array($this->_controller, $safe)) { throw new Exception(); // replace me with your own error 404 stuff } 

Поскольку ваш класс Request использует подход сегментов URI для идентификации контроллера, действия и аргументов, глобальные переменные, такие как $ _GET или $ _REQUEST, не учитываются в вашем запросе.

Что вам нужно сделать, так это сделать некоторые дополнения к вашему коду запроса. В частности:

Удалите строку:

 $this->_args = (isset($parts[0])) ? $parts : array(); 

И добавьте следующее:

 $all_parts = (isset($parts[0])) ? $parts : array(); $all_parts['get'] = $_GET; $this->_args = $all_parts; 

Таким образом, переменные $ _GET (т.е. переменные, переданные через url) будут доступны в вызванных действиях, поскольку они будут в $ args (они будут доступны как $ args ['get'] на самом деле, что является массивом, который содержит $ _GET vars, так что вы сможете получить доступ к domain = example, используя $ args ['get'] ['domain']).

Конечно, вы можете добавить еще один метод в свой класс запроса (например, запрос), который может выглядеть так:

 public function query($var = null) { if ($var === null) { return $_GET; } if ( ! isset($_GET[$var]) ) { return FALSE; } return $_GET[$var]; } 

Таким образом, вы можете получить одну переменную из url (например, запрос $ request-> ('domain')) или весь массив $ _GET ($ request-> query ()).

Это потому, что php автоматически поместит «? Mod_title = …» в массив $_GET . getArgs() должна проверяться на $_GET , $_POST или $_REQUEST .

Если вы пытаетесь использовать минимальный подход MVC, посмотрите пример rasmus: http://toys.lerdorf.com/archives/38-The-no-framework-PHP-MVC-framework.html

Если ваш вариант использования будет более сложным, посмотрите, как Zend (http://framework.zend.com/manual/en/zend.controller.html) или Symfony (https://github.com/symfony / symfony / tree / master / src / Symfony / Component / Routing) делают свой материал.

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