我为自己的phpmvc框架编写了一个小的phpurl解析器,在以下代码中我几乎不需要帮助:
<?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();
我希望在URL的末尾允许一个可选的/
。例如,在这个当前路由定义中,当REQUEST_URI
是/users/123/posts/456
时,我希望在REQUEST_URI
是/users/123/posts/456/
时得到相同的结果(函数调用)。
此外,/users/123/posts/456/edit
调用新函数。
如果需要,从您的路线上删除尾随斜线:
$route['url'] = rtrim($route['url'], '/');
然后相应地终止您的路线模式:
$pattern = preg_replace('/''':[a-zA-Z0-9'_'-]+/', '([a-zA-Z0-9'-'_]+)', preg_quote($route['url'], '@'));
$pattern = "@^$pattern/?$@D";
在执行路由之前,您可以只rtrim
和$_SERVER['REQUEST_URI']
:
$reqUrl = $_SERVER['REQUEST_URI'];
$reqUrl = rtrim($reqUrl, '/');
但这样做时,不要在路由定义中添加斜杠:
$route->addRoute('GET', '', ...
$route->addRoute('GET', '/users/:uid/posts/:pid', ...
将此代码放在当前代码中,以便验证URL
$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
}
在上面的代码中,它会检查你的url,如果它在url中,就会删除"/",所以基本上它会做与url相同的事情,最后没有斜杠
希望对有所帮助