Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Php route parser end of the URL

Tags:

php

router

I wrote a little php url parser for my own php-mvc-framework and i need little help in the following code:

<?php
class Route{

private $routes = [];

public function __construct(){}

public function addRoute($method, $url, $callback){
    $this->routes[] = array('method' => $method, 
                          'url' => $url, 
                          'callback' => $callback);
}

public function doRouting(){
    $reqUrl = $_SERVER['REQUEST_URI'];
    $reqMet = $_SERVER['REQUEST_METHOD'];
    foreach($this->routes as  $route) {

        // convert urls like '/users/:uid/posts/:pid' to regular expression      
        $pattern = "@^" . preg_replace('/\\\:[a-zA-Z0-9\_\-]+/', '([a-zA-Z0-9\-\_]+)', preg_quote($route['url'])) . "$@D";
        $matches = array();

        if($reqMet == $route['method'] && preg_match($pattern, $reqUrl, $matches)) {

            // remove the first match
            array_shift($matches);
            // call the callback with the matched positions as params
            return call_user_func_array($route['callback'], $matches);
        }
    }
}

$route = new Route();

$route->addRoute('GET', '/', function(){
     echo 'root';
});

 $route->addRoute('GET', '/users/', function(){
     echo 'users';
 });
 $route->addRoute('GET', '/users/:uid/posts/:pid/', function($uid, $pid){
     echo $uid.'<br/>'.$pid;
 });

 $route->addRoute('GET', '/users/:uid/posts/:pid/edit', function($uid, $pid){
     echo 'users posts edit';
 });


 $route->doRouting();

I want allow an optional / at the end of the URL. For example, in this current routes definition when REQUEST_URI is /users/123/posts/456 i want same result(function call) when REQUEST_URI is /users/123/posts/456/.

Also, /users/123/posts/456/edit call new function.

like image 730
Vlatko Avatar asked Nov 02 '22 09:11

Vlatko


1 Answers

Strip trailing slashes from your route if needed:

$route['url'] = rtrim($route['url'], '/');

And then terminate your route's pattern accordingly:

$pattern = preg_replace('/\\\:[a-zA-Z0-9\_\-]+/', '([a-zA-Z0-9\-\_]+)', preg_quote($route['url'], '@'));
$pattern = "@^$pattern/?$@D";
like image 72
Denis de Bernardy Avatar answered Nov 09 '22 15:11

Denis de Bernardy