As a training I write a site in php using mvc. Rested at the time of creation of the controller for blog entries. The news has url site / news / test_article Already implemented the functionality of saving an article from the admin in the database, translated the title (title), saved it as an alias. So how to describe the controller for the article? According to my logic, route reads the url, the first part after the domain name is the controller name, the second is the action. But what if you use aliases for the url of each entry? Here it is written for the news page:

<?php class NewsController extends Controller { public function indexAction(){ $news = new News(); $data = $news->get_news(); $this->view->render("news/index", ["news"=>$data]); } } 

Route.php

 <?php class Route // Для разбора одрессной строки { // Стартовая функция public static function start(){ // Autoload models spl_autoload_register(function($models){ if(file_exists("app/models/".$models.".php")){ include_once "app/models/".$models.".php"; } }); $baseController = "Index"; // Дефолтный controller $baseAction = "index"; // Дефолтный action $routs = explode("/", $_SERVER["REQUEST_URI"]); // Принимаем url и разбиваем его по слешам // Проверка части url после первого слеша (отвечающего за controller) if(!empty($routs[1])){ $baseController = $routs[1]; // Переопределение controller } // Преобразование строки в нижний регистр + Преобразование первого символа строки в верхний регистр + "Controller" $baseController = str_replace("-", "_", $baseController); $baseController = ucfirst(strtolower($baseController)) . "Controller"; $controllerPath = "app/controllers/" . $baseController . ".php"; // Полный путь к controller // Проверка части url после второго слеша (отвечающего за action) if(!empty($routs[2])){ $baseAction = $routs[2]; // Переопределение action } // Преобразование строки в нижний регистр $baseAction = str_replace("-", "_", $baseAction); $baseAction = strtolower($baseAction) . "Action"; // Проверка наличия файла if(file_exists($controllerPath)){ include_once $controllerPath; } else { self::error404(); } // Создание объекта controller $controller = new $baseController; // Проверка существования метода if(method_exists($controller, $baseAction)){ $controller->$baseAction(); } else { self::error404(); } } public static function error404(){ $host = "http://" . $_SERVER["HTTP_HOST"] . "/"; // Адрес сайта header("HTTP/1.1 404 Not Found"); // Заголовок header("Status 404 Not Found"); // Статус header("Location: " . $host . "error404"); // Редирект } } 
  • It seems to me there will be a lot to write .... two or three lines will not be limited to .... I would just advise to download yii2 and look at their core ... in the UrlManager and UrlRule - just figure out how they do it. To apply it to yourself - Alexey Shimansky

1 answer 1

Let's start with errors

According to my logic, route reads url,

The Router object should do just that, just a little deeper - it's not easy to read the URL and do the URL + POST + COOKIES + .. conversion -> Request object, the router also calculates the name of the controller and the action. When constructing and calling the controller, the Request object is passed to the controller.

But what if you use aliases for the url of each entry?

That is, how does the router choose the controller and the action? This is usually done by the URL recognition configuration - which is given to the router. An example from my favorite framework Zend2

 [ 'offers_default' => [//универсальный роут модуля Offers 'type' => '\Engine\Mvc\Router\Http\Segment', 'options' => [ 'route' => '/offers/:controller[/:action]*', 'constraints' => array( 'controller' => '[a-zA-Z][a-zA-Z0-9_-]*', 'action' => '[a-zA-Z][a-zA-Z0-9_-]*', ), 'defaults' => [ '__NAMESPACE__' => 'Offers\Controller', 'action' => 'index' ], ], 'priority' => -1000, ], 'home' => [//роут для главной страницы 'type' => 'Zend\Mvc\Router\Http\Literal', 'options' => [ 'route' => '/', 'defaults' => [ 'controller' => 'Application\Controller\Index', 'action' => 'index', ], ], ] ] 

Self-writing MVC is only useful for self-development. You can spy on - how it works in frameworks.

Directly the answer to the question :

It is necessary to make the URL parsing adjustable cofig, the config should be arranged in such a way that it can be matched with a certain algorithm using the URL => MCA (action controller module) algorithm. Then you can redirect any address to the desired controller. Flexibility of the config - is responsible for its volume in order to enter all the desired URLs: if the configuration is flexible, then it is capacious, readable and extensible.

  • Thank you for such a detailed response, I will understand. - korg