我正在尝试构建一个路由器函数来正确匹配传入的URI,并将它们与存储系统URI的数组相匹配。我也有类似于CodeIgniter的通配符'(:any)'和'(:num)'。
基本上,我试图让'admin / stats /(:num)'条目在'admin / stats'和admin / stats / 1'上匹配。
当脚本启动时,我从一个单独的数组中获取所有路径并使用foreach来保存每个路径:
route('admin/stats/(:num)', array('#title' => 'Statistics',...));
功能是:
function route($path = NULL, $options = NULL) {
static $routes;
//If no arguments are supplied, return all routes stored.
if(!isset($path) && !isset($options)) {
return $routes;
}
//return options for path if $path is set.
if(isset($path) && !isset($options)) {
//If we have an exact match, return it.
if(array_key_exists($path, $routes)) {
return $routes[$path];
}
//Else, we need to use RegEx to find the correct route options.
else {
$regex = str_replace('/', '\/', $path);
$regex = '#^' . $regex . '\/?$#';
//I am trying to get the array key for $route[$path], but it isn't working.
// route_replace('admin/stats/(:num)') = 'admin/stats/([0-9]+)'.
$uri_path = route_replace(key($routes[$path])); //route_replace replaces wildcards for regex.
if(preg_match($regex, $uri_path)) {
return $routes[$path];
}
}
}
$routes[$path] = $options;
return $routes;
}
路线替换功能:
function route_replace($path) {
return str_replace(':any', '.+', str_replace(':num', '[0-9]+', $path));
}
$ routes数组中的键/值对如下所示:
[admin/stats/(:num)] => Array
(
[#title] => Statistics //Page title
[#access] => user_access //function to check if user is authorized
[#content] => html_stats //function that returns HTML for the page
[#form_submit] => form_stats //Function to handle POST submits.
)
感谢您的帮助。这是我的第一台路由器,我对制作正确的Regex并不熟悉。
答案 0 :(得分:1)
'admin / stats /(:num)'永远不会匹配'admin / stats',因为在你的“模式”中需要斜杠。在pseduo-regex中,您需要执行类似'admin / stats(/:num)'的操作。
您的代码中似乎也存在一些错误。这一行
$uri_path = route_replace(key($routes[$path]));
当$ path不是$ routes中存在的密钥时,位于执行的块中。
我试图重写它,这似乎有用(这只是else子句):
foreach( array_keys( $routes ) as $route ) {
$regex = '#^' . $route . '?$#';
//I am trying to get the array key for $route'$path', but it isn't working.
// route_replace('admin/stats/(:num)') = 'admin/stats/('0-9'+)'.
$uri_path = route_replace($regex); //route_replace replaces wildcards for regex.
if(preg_match($uri_path,$path)) {
return $routes[$route];
}
}
但这需要'admin / stats /(:num)'为'admin / stats(/:num)'。
顺便说一句,如果你还没有,你应该得到一个调试器(Zend和xDebug是PHP最常见的两个)。它们在解决这类问题方面具有无可估量的价值。
另外,问问自己是否需要写一个路由器,或者你是否不能只使用其中一个非常好的路由器......