2
\$\begingroup\$

I'm trying to come up with a simple router class. I considered using a Request class, but I think that will turn something simple into something overly complex. That is why I did not consider creating one for my framework.

class Router {

    private $uri;
    private $controller;
    private $action;
    private $params;

    public function __construct($uri) {
        $this->uri = $uri;
        $this->action = 'index';
        $this->params = array();
    }

    public function map() {
        $uri = explode('/', $this->uri);
        if (empty($uri[0])) {
            $c = new Config('app');
            $this->controller = $c->default_controller;
        } else {
            $this->controller = array_shift($uri);
            if (!empty($uri[1]))
                $this->action = array_shift($uri);
            if(!empty($uri[2]))
                $this->params = $uri;
        }
    }

    public function getController() {
        return $this->controller;
    }

    public function getAction() {
        return $this->action;
    }

    public function getParams() {
        return $this->params;
    }
}

In the bootstrap, I did this to map the url:

$uri = filter_var(rtrim(isset($_GET['url']) ? $_GET['url'] : null, '/'), FILTER_SANITIZE_URL);
$router = new Router($uri);
$router->map();

What can I do to improve this?

\$\endgroup\$
4
\$\begingroup\$

What is a router used for?

Translate one address to another one connection two different network to eahc other depending on rules. It will never instantita a browser to display for example a HTTP request.

Your class doing to much and much lesser than it should

Your router should only deal with the input address and not instantiating a controller and other stuff. How should it work?

  1. need a collection of rules, call RouteTable (will store Route instances)
  2. rule: how to translate an url to a usefull address in the framwork (how to get named parameters like controller or action and so on)
  3. the Router it self which is containing the logic

Rules, Routes

A rule should contain the following stuffs:

  • a pattern, say: "{controller}/{action}/{id}"

This will mean that if we have an url like book/details/5 then the framework somewhere will instantiate the book controller and call it's details method with parameter 5.

  • set up default values are always good practise becouse a route can work without having all parts set

For example an id is not always mandatory it can be optional or we could define a pattern like "veryimportanturl" but the framwork can handle like: controller => lottery, action => getthisweekwinningnumbers, id => 5

  • a good to have feature is to attach a unique name to our routes so they could be used for generating urls or form action parameters
  • a powerfull weapon could be if we can say to a route: "hey you have a handler, so if you are used to handle one request then you should tell how can we do that"

We can create different handlers for different routes: can have one for handling an MVC task, another one so serve special images (so we do not need to go through a complete MVC cycle can be create a thinner logic).

These rule should be mapped into our RouteTable which will be the responsible to store these and for example keep the unique route names.

Router

A router will need two things:

  • the current request data (rewritten url and maybe query string)
  • the RouteTable

The router is responsible to pick the correct one from the collection can be done different ways but here is my solution:

  1. ordering the available routes: by the static parts (fix parameters not pattern elements ({})) and by the constraints (in a route i can set up constraint like the id onyle can be in the range of 0-5) [static length descending, constraints' numbers descending]
  2. iterating through the ordered rules collection and trying to find out which one will be the first mach by using regular expression (the Route contains it's pattern translated into regular expression), if a match found i try to fill the pattern with data; if everything is in place i've founded otherwise continuing the search.

If the correct route has been found my routing engine returns it to the other parts of the framework but not just the pure route but mapped all the values came from the request. If nothing has found i face with an exception.

The way i see the router above does nearly nothing compared to a real router but do things what should not be done by it. Beside this it's unflexible (fixed array indexes, has a hard dependency on a Config class and a default controller (why?)).

\$\endgroup\$
  • \$\begingroup\$ You see that I am relatively new to this thing and trying to figure things out, giving an example would make your answer better, but I will try to learn from what you have just said. thank you! \$\endgroup\$ – Joey Hipolito May 16 '13 at 3:16
  • \$\begingroup\$ Isee but first you have to plan what do you want to achieve with your rouing mechanism. The above is just a heads up for what can be done in a router and in the surrounding objects. But your question is not simple becouse a lots of stuff depends on the other parts of your framework. \$\endgroup\$ – Peter Kiss May 16 '13 at 8:05
  • \$\begingroup\$ I will consider all the things written above and I will return and ask for another review. Thank you! \$\endgroup\$ – Joey Hipolito May 16 '13 at 12:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.