我正在构建一个PHP框架来完成我的课程,并且我坚持使用一些解决方案来匹配一些自定义路由和标准路由。
我的框架路线在Zend Framework 1的路线上类似。
符合
的标准路线/module/controller/action/param/value/param2/value2/paramn/valuen
URI的一部分是可选的,/ route导致应用程序模块,索引控制器和索引操作没有参数和值。
我陷入了一些自定义路线,我用这种方式定义:
/blog/:postname/
/admin/logout/
/blog/posts/:year/:category/
/about/
这些路由必须与此示例URI请求匹配。
/blog/my-first-post/
/blog/my-first-post/referenced/facebook/
/admin/logout/
/admin/logout/session-id/246753/action
/blog/posts/2013/turism/
/blog/posts/2013/turism/page/2/
但不必匹配标准路线。自定义路由必须位于标准路由之前。 标准路线的一些例子。例子:
/
/application/
/application/index/
/application/index/index/
/blog/posts/view/id/3/
/admin/login/
/admin/login/logout (that one are the
/admin/blog/posts/edit/id/3/
/admin/blog/posts/edit/id/3/success/false/
我发现这样做的方式是使用RegEx进行比赛,但是我试图学习RegEx一个多月而且没有完全掌握。
PS:匹配当前路线后,我必须将:变量与REQUEST_URI中的相关位置绑定。
感谢您的帮助。
答案 0 :(得分:0)
虽然很有诱惑力,但在这种特殊情况下我不会使用正则表达式。即使我通常这样做。一个简单的循环和匹配就行了,除非你的课程设置了一些你必须遵循的限制。
我把一个应该完成工作并在控制台中运行的示例放在一起,只是为了表明我的意思。
function get_route($uri){
$routes = [
'blog#show' => 'blog/:postname',
'admin#logout' => 'admin/logout',
'blog#category' => 'blog/posts/:year/:category',
'home#about' => 'about'
];
$params = [];
$uri = preg_replace('/#|\?.+/', '', $uri); // remove hash or query strings
$uri = preg_replace('/(^\/)?(\/$)?/', '', $uri); // trim slashes
$uri = explode('/', $uri);
$action = null;
foreach ($routes as $this_action => $this_route) { // loop through possible routes
$fractions = explode('/', $this_route);
if (sizeof($fractions) !== sizeof($uri)) continue; // did not match length of uri
for ($i=0; $i<sizeof($uri); $i++) { // compare each part of uri to each part of route
if (substr($fractions[$i], 0, 1) !== ':' && $fractions[$i] !== $uri[$i]) break; // not a match and not a param
if ($i === sizeof($uri)-1) { // made it to the last fraction!
$ii = 0;
foreach ($fractions as $fraction) {
if (substr($fraction, 0, 1) == ':') { // it's a param, map it!
$params[substr($fraction,1)] = $uri[$ii];
}
$ii++;
}
return ['action'=>$this_action, 'params'=>$params];
}
}
}
return false;
}
答案 1 :(得分:0)
我可以通过此代码满足我的需求,已经过了很多测试。
public function matchCustomRoute($uri)
{
if($uri == '')
{
return null;
}
$customRoutes = $this->getRoutes();
$explodeUri = explode('/', $uri);
$arrayUri = array();
foreach($explodeUri as $uriPart)
{
if($uriPart == '')
{
continue;
}
$arrayUri[] = $uriPart;
}
$countUri = count($arrayUri);
foreach($customRoutes as $key => $value)
{
$explodeRoute = explode('/',$value['route']);
$arrayRoute = array();
foreach($explodeRoute as $routePart)
{
if($routePart == '')
{
continue;
}
$arrayRoute[] = $routePart;
}
$countRoute = count($arrayRoute);
if($countRoute > $countUri)
{
continue;
}
$matches = 0;
for($i = 0 ; $i < $countRoute ; $i++)
{
$match = preg_match('/'.$arrayUri[$i].'/', '/'.$arrayRoute[$i].'/');
if($match == 0)
{
if(substr($arrayRoute[$i], 0, 1) == ':')
{
$value['params'][substr($arrayRoute[$i], 1)] = $arrayUri[$i];
}
else
{
continue;
}
}
$matches++;
}
if($matches == $countRoute)
{
return $value;
}
}
return null;
}
感谢您的帮助。