I understand that there is a sore subject, and there are many (very many) examples on the Internet.

The fact is that I have routes, but they are curves (the code itself is bad). The view is as follows:

array(new Route('/url','className','methodName')); 

and an array through new Router;

The bottom line is that everything works, I also need to create a separate file and write two methods there:

 __construct($args=[]) {$this->args = $args} 

and a method for creating an instance of a class with a class name, parameters, and an action.

In any case, what is higher is not quite important.

The bottom line is that this is my experience in writing routing, and this method has been forced into my head forcibly, alas.

How can I write a similar system? Without using additional classes, that is: two classes Route, Router:

 $router = [new Route('/','main','index')]; new Router($router); 

Ps: I do not ask for me to write, just "push" to think. Thank)

Closed due to the fact that it is necessary to reformulate the question so that it was possible to give an objectively correct answer by the participants of Streletz , user194374, dirkgntly , aleksandr barakin , Vartlok Aug 9 '16 at 13:09 .

The question gives rise to endless debates and discussions based not on knowledge, but on opinions. To get an answer, rephrase your question so that it can be given an unambiguously correct answer, or delete the question altogether. If the question can be reformulated according to the rules set out in the certificate , edit it .

    1 answer 1

    Greetings

    MVC - means that you have controllers for working with the site, models that provide data, and views to display them.

    In theory, the directory structure for scripts can be something like:

     \Core //базовые классы Controller.php Model.php View.php //и роутер Route.php \Controllers //тут должны лежать контроллеры, для примера положу блог.пхп для блога blog.php error404.php \Models //тут должны лежать модели, для примера положу модель блог.пхп для блога blog.php \Views //тут должны лежать вьюхи, для примера положу пару вьюх для блога //я тут показал файлы html, но тут могут быть и файлы php blog_index.html blog_post.html error404.html \More //в этой папке пускай будут лежать какие-нибудь дополнительные классы 

    First of all, we need to register an autoloader so that we do not reinvent the wheel and include classes at will (we need to include it in the index file):

    autodoader.php *

     <?php spl_autoload_register(function($class){ $file = SITE_DIR.'/'.str_replace('\\', '/', $class).'.php'; if (file_exists($file)) require_once $file; }); 

    Base classes (in them, in theory, you need to define some basic functionality):

    \ Core \ Controller.php

     <?php namespace Core; abstract class Controller { public View = null; public function __construct() { $this->init(); } abstract function init(); } 

    \ Core \ Model.php

     <?php namespace Core; abstract class Model { } 

    \ Core \ View.php

     <?php namespace Core; class View { public function addTemplate($template) { //тут нужно описать процедуру подгрузки шаблона } public function addView($view) { //тут нужно описать процедуру подгрузки вьюхи } public function show() { //тут нужно сделать вывод контента } } 

    In fact, your View class can be a wrapper over some template engine for more convenient work with it. In this case, I highly recommend not to write your template maker, but to use something ready. Of the finished ones, I like Twig the most.

    Next, you need to take the resulting URL and extract the path from it to call the desired controller:

    \ Core \ Route.php

     <?php namespace Core; class Route { static public $routes = null; static function start() { if (self::$routes == null) { $url = explode('?', substr(strtolower($_SERVER['REQUEST_URI'], 1))); self::$routes = explode('/', $url[0]); } $controller_name = 'main'; $action_name = 'index'; if (!empty(self::$routes[0])) { $controller_name = self::$routes[0]; } if (!empty(self::$routes[1])) { $action_name = self::$routes[1]; } $controller_class = '\\Controllers\\'.$controller_name; $action_name = 'action_'.$action_name; $controller = new $controller_class; if(method_exists($controller, $action_name)) { $controller->$action_name(); } else { Route::Error404(); } } public static function Error404() { $protocol = 'http'; if ($_SERVER['SERVER_PORT']==443) $protocol = 'https'; $host = $protocol.'://'.$_SERVER['HTTP_HOST']; header('HTTP/1.1 404 Not Found'); header("Status: 404 Not Found"); header('Location:'.$host.'/error404'); } } 

    \ Controllers \ error404.php

     <?php namespace Controllers; class error404 extends \Core\Controller { public function init() { } public function action_index() { $this->View->addTemplate('basic'); $this->View->addView('error404'); $this->View->show(); } } 

    \ Views \ error404.html

     <h1>Ошибка 404</h1> <p>Страница не доступна или не существует.</p> 

    And, actually, you should have some kind of index.php (or some other file) that will initiate everything.

     <?php include "autoloader.php"; \Core\Route()::start(); 

    IMPORTANT! Although I got into some details, I just wanted to push you to some kind of automation idea. You can also implement routing using files (by setting paths to a certain file / routing file, you can see Symfony as an example). In any case, I wrote the code right here without checking its performance. I also do not insist on its ideality.

    I would be glad if I could somehow help.

    • Just out of curiosity - why are the directory names (Core, Controllers, etc.) capitalized? - Vladimir Gamalyan
    • one
      It is possible and with a little, of course. I just read psr once (these are standards or, otherwise, rules of good tone) ... Read it yourself, look at the examples given (the first link that the search engine issued) svyatoslav.biz/misc/psr_translation - Stanislav
    • I see, thanks. Just thought that, other things being equal, the option with the title is an extra press shift. - Vladimir Gamalyan
    • Yes, in psr2 there is a class naming standard, without a namespace, they were more precisely written to the class name. For example, the class named Core_App_Abstract is in the Core/App/Abstract.php file as well and the namespace Core\App\AbstractClass will be in Core/App/AbstractClass.php so intuitively clear where to find the file with the class. In the latter, I replaced Abstract with AbstractClass because Abstract is a keyword in php. @VladimirGamalian - Naumov
    • ps By the way in php there is a constant DIRECTORY_SEPARATOR and it is better to use it in the autoloader. - Naumov