带参数的PHP API路由
我在一个PHP路由类中有如下路由:
$router->add('/public/bookings/get/{id}', array(
'controller' => 'Bookings',
'action' => 'getBookingId'
));
如何在Router类中实现用于路由选择的正则逻辑?我有如下代码,但它没有匹配:
foreach ($this->routes as $route => $params) {
$pattern = str_replace(['{id}','/'], ['([0-9]+)', '\/'],$route);
if(preg_match($pattern, $url['path'])) {
$this->params = $params;
}
}
解决方案
foreach ($this->routes as $route => $params) {
$pattern = str_replace('{id}', '([0-9]+)', $route);
// Wrap the pattern in delimiters (#) and add anchors (^ and $)
// so it matches the entire url, not just a subset.
$regex = '#^' . $pattern . '$#';
if (preg_match($regex, $url['path'], $matches)) {
$this->params = $params;
// Small Bonus: The actual ID matched will be in $matches[1]
$this->params['id'] = $matches[1];
break; // Stop looping once we find a match
}
}
备选方案
为 {id} 专门设计的正则看起来比较局限。最好有一个通用的匹配,将 {name} 模式替换成一个命名正则
foreach ($this->routes as $route => $caller) {
$pattern = "#^" . preg_replace('/\{([a-zA-Z0-9_]+)\}/', '(?P<$1>[^/]+)', $path) . "$#";
if (preg_match($pattern, $url['path'], $matches)) {
// Filter out numeric keys from preg_match to keep only named params
$params = array_filter($matches, 'is_string', ARRAY_FILTER_USE_KEY);
return [$caller['controller'],$caller['action']](...$params);
}
}
在这里,相应的类和方法被称为 $caller,而URL中提供的参数被称为 $params。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。