A
A
alestro2016-05-02 15:30:57
PHP
alestro, 2016-05-02 15:30:57

php routing. Why is this option bad?

There is a small class that implements routing in the application.

namespace http;
class Router{
  private $routes=[];
  private $args=[];
  private $wildcards=['/{id}/'=>'([0-9]+)','/{name}/'=>'(.+)'];
  private $requestedUri;
  public function get($route, callable $callback){
    $this->routes['GET'][$route]=$callback;
  }
  public function post($route, callable $callback){
    $this->routes['POST'][$route]=$callback;
  }
  private function dispatch(){
    $uri = reset(explode('?', $_SERVER["REQUEST_URI"]));
      	$this->requestedUri = empty(urldecode(rtrim($uri, '/')))? '/':urldecode(rtrim($uri, '/'));
    $callback=$this->routes[$_SERVER['REQUEST_METHOD']][$this->requestedUri];
    if(is_callable($callback)){
      return $this->execute($callback);
    }
    foreach($this->routes[$_SERVER['REQUEST_METHOD']] as $route=>$callback){
      if($route==='/'){continue;}
      $pattern=preg_replace(array_keys($this->wildcards), $this->wildcards, $route);
      if(preg_match('~'.$pattern.'~',$this->requestedUri)===1){
        $this->args=array_diff(explode('/',$this->requestedUri),explode('/',$pattern));
        return $this->execute($callback);
      }
    }
  
  
  }
  
  private function execute(callable $callback){
      return call_user_func_array($callback,$this->args);
  }
  
  public function run(){
    return $this->dispatch();
  }
}

$router=new \http\Router();
$router->get('/path/{id}/self/{name}', function($id, $name){echo 'id : '.$id.'
name : '.$name;}); An example of using a router with a closure function.
I would like to hear the opinion of the public. What should be changed, what should be added. Or maybe not at all.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
I
index0h, 2016-05-02
@index0h

You do not check the inserted route, but what if I put an object there instead of a string? If something went wrong, throw an exception.
Don't use super globals. First, create a Request object and work with it already.
It's not clear why trims, urldecodes, etc. are needed. If something did not come as it should, the route was not found, and nothing more. This is not a problem with the router, that it can be thrown into it.
callable is pretty specific crap. It can be an array of two strings, a function, an object with a string, just a string. Fuck this shit. Use then already \Closure.
If you still have regular expressions everywhere, it makes sense to use named sequences:

|(?P<id>\d+)|
|(?P<name>[a-Z]+)|

It makes sense to do pattern substitutions when inserting a route, and not at the time of the dispatch.
Formatting... gqBbWeuzy9E.jpg
Read about PSR-2
З.Ы. When you've played enough - take ready-made and high-quality ones in Symfony / Silex))

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question