【发布时间】:2015-08-17 23:47:54
【问题描述】:
我正在为我的 PHP MVC 应用程序编写一个路由器,我目前需要找到一种方法来使用路由中的匹配项作为控制器和操作的变量。
例如,如果我有以下路线:/users/qub1/home
我想使用类似这样的正则表达式:\/users\/(?!/).*\/(?!/).*
然后我想指定这样的操作:$2(在示例中,这将是 home)
传递给动作的参数如下:$1(在示例中,这将是 qub1)。
这将执行类似于以下的代码:
$controller = new UsersController();
$controller->$2($1);
配置的路线是这样存储的:
public function setRoute($route, $regex = false, $controller = 'Index', $action = 'index', $parameters = array()) {
if(!$regex) {
$route = preg_quote($route, '/');
}
$this->routes[] = [
'route' => $route,
'controller' => $controller,
'action' => $action,
'parameters' => $parameters
];
}
上述示例的存储位置如下:$router->setRoute('\/users\/(?!/).*\/(?!/).*', true, 'User', '$2', [$1]);
所以本质上,我想使用一个正则表达式中的匹配组作为变量来替换另一个正则表达式(如果这有意义的话)。
我希望我已经足够准确地描述了我的问题。感谢您的帮助。
编辑:
我目前用来解析路由的代码(它不起作用,但它应该说明我想要实现的目标):
public function executeRoute($route) {
// Loop over available routes
foreach($this->routes as $currentRoute) {
// Check if the current route matches the provided route
if(preg_match('/^' . $currentRoute['route'] . '$/', '/' . $route, $matches)) {
// If it matches, perform the current route's action
// Define names
$controllerClass = preg_replace('\$.*\d', $matches[str_replace('$', '', '$1')], ucfirst($currentRoute['controller'] . 'Controller'));
$actionMethod = preg_replace('\$.*\d', $matches[str_replace('$', '', '$1')], strtolower($currentRoute['action']) . 'Action');
$parameters = preg_replace('\$.*\d', $matches[str_replace('$', '', '$1')], join(', ', $currentRoute['parameters']));
// Create the controller
$controller = new $controllerClass();
$controller->$actionMethod($parameters);
// Return
return;
}
}
}
【问题讨论】:
-
嗨,你可以试试 strstr();在 php php.net/strstr
-
路由的重点是隐藏内部实现,这样可以很容易地添加新的路由。你真的让它变得更复杂,它需要是
-
@KarthikKeyan 我用过 strtr 并且它有效。我首先必须将匹配数组转换为关联数组(在索引前加上'$'),然后我将其用作针头参数。我现在可以使用以下方式轻松设置路由:
$router->setRoute('\/users\/([^\/]*)', true, 'Users', 'index', ['$1']);,它将在幕后执行类似的操作:UsersController->indexAction($1)其中 $1 将是用户名。
标签: php regex model-view-controller router