PHP自定义URL路由

时间:2013-12-19 15:03:19

标签: php regex url router

我正在开发一个自定义的PHP URL路由类,但我需要一些关于正则表达式的帮助。 我希望用户添加这样的路线:

$router->addRoute('users/:id', 'users/view/');

添加路由后,脚本需要检查请求的URL是否与定义的格式(users /:id)匹配,并调用users控制器的view方法。还需要将id作为参数传递给view方法。

我的addRoute方法如下所示:

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

处理路由的方法如下所示:

public function routes()
{
    foreach($this->routes as  $route) {

        $pattern = $route['url'];

        // Check if the route url contains :id
        if (strpos($route['url'], ':id'))
        {
            // Build the pattern
            $pattern = str_replace(':id','(\d+)', $pattern);
        }

        echo $pattern . '<br />' . $this->_url;

        if (preg_match_all('~' . $pattern . '~u', $this->_url, $matches))
        {
            $this->url_parts = explode('/', $route['target']);
            $this->_params = $matches;
        }
    }
}

目前,脚本循环遍历路由并检查URL是否包含:id。如果是这样,它将被(\d+)替换。

然后脚本检查请求的url是否与模式匹配并设置一些变量。

到目前为止一切正常,但经过一些测试后,匹配网址存在一些问题。

我希望脚本只允许格式为/users/:id的网址,但是当我调用以下网址时,它会传递给/users/1/test

如何阻止脚本允许此网址,并且只允许它与定义的格式匹配?

2 个答案:

答案 0 :(得分:0)

尝试以下方法:

$router->addRoute('users/(\d+)$', 'users/view/');

答案 1 :(得分:0)

我自己解决了这个问题。 我必须在表达式之前添加^,在它之后添加+ $。 所以函数看起来像这样:

private function routes()
{
    // Loop through the routes
    foreach($this->routes as  $route) 
    {
        // Set the pattern to the matching url
        $pattern = $route['url'];

        // Check if the pattern contains :id
        if (strpos($route['url'], ':id'))
        {
            // Build the pattern
            $pattern = str_replace(':id','([0-9]+)', $pattern);
        }

        // Check if the requested url matches the pattern
        if (preg_match_all('~^' . $pattern . '+$~', $this->_url, $matches))
        {
            // If so, set the url_parts var
            $this->url_parts = explode('/', $route['target']);

            // Remove the first index of the matches array
            array_shift($matches);

            // Set the params var
            $this->_params = $matches;
        }
    }
}