Php路由解析器URL的结尾

时间:2013-12-06 21:27:03

标签: php router

我为自己的php-mvc-framework编写了一个小的php url解析器,我在以下代码中需要一些帮助:

<?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();

我希望在网址末尾添加一个可选的/。例如,在REQUEST_URI/users/123/posts/456时的当前路由定义中,当REQUEST_URI/users/123/posts/456/时,我希望获得相同的结果(函数调用)。

此外,/users/123/posts/456/edit调用新功能。

3 个答案:

答案 0 :(得分:2)

如果需要,从您的路线中删除尾部斜杠:

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

然后相应地终止你的路线模式:

$pattern = preg_replace('/\\\:[a-zA-Z0-9\_\-]+/', '([a-zA-Z0-9\-\_]+)', preg_quote($route['url'], '@'));
$pattern = "@^$pattern/?$@D";

答案 1 :(得分:0)

在进行路由之前,你可以rtrim $_SERVER['REQUEST_URI']

$reqUrl = $_SERVER['REQUEST_URI'];
$reqUrl = rtrim($reqUrl, '/');

但是这样做不要在路径定义中添加斜杠:

$route->addRoute('GET', '', ...
$route->addRoute('GET', '/users/:uid/posts/:pid', ...

答案 2 :(得分:0)

将此代码放在您验证网址的当前代码中

$url="some/url/";
$slash=substr($url, -1); // returns "/"
//remove the '/' from end of the url
if($slash=="/") {
trim($slash, "/"); //many alternatives can be used for this function
}

上面的代码,它会检查你的网址,如果它在网址中则会删除'/',所以基本上它会做一个与没有斜线的网址相同的东西。
希望有所帮助