2013-12-19 153 views
1

我正在处理自定义PHP URL路由类,但我需要一些正则表达式的帮助。 我希望用户添加路由是这样的:PHP自定义URL路由

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

添加脚本需要的路线,以检查请求的URL定义格式(用户/:ID)匹配后,并调用用户控制器的视图的方法。还需要将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是否匹配模式并设置一些变量。

到目前为止,一切正常,但经过一些测试后,与匹配url有一些问题。

我希望脚本只允许格式为/users/:id的网址,但是当我呼叫以下网址时,它将传递到/users/1/test

我怎样才能防止脚本允许这个URL,只让它匹配定义的格式?

回答

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; 
     } 
    } 
} 
0

尝试以下操作:

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