PHP:MVC路由函数解析请求视图的好解决方案?
可能重复: 我想实现MVC设计结构,目前正在努力寻找一个好的解决方案来解析请求的视图 在我的路由文件中,我有以下代码:PHP:MVC路由函数解析请求视图的好解决方案?,php,model-view-controller,design-patterns,Php,Model View Controller,Design Patterns,可能重复: 我想实现MVC设计结构,目前正在努力寻找一个好的解决方案来解析请求的视图 在我的路由文件中,我有以下代码: public function parseRequestedView() { $this->ressource_requested = explode('/', trim($_GET['view'], '/')); // e.g.: http://www.foo.com/article/{id}/comments/show if (!empty($
public function parseRequestedView() {
$this->ressource_requested = explode('/', trim($_GET['view'], '/'));
// e.g.: http://www.foo.com/article/{id}/comments/show
if (!empty($this->ressource_requested[3])) {
// Format: [0] viewpoint (article), [1] child (comments), [2] action (show), [3] reference ({id}),
// [4] additional information (from $_POST)
return array($this->ressource_requested[0], $this->ressource_requested[2], $this->ressource_requested[3],
$this->ressource_requested[1], $_POST);
// e.g.: http://www.foo.com/article/{id}/show
} elseif (!empty($this->ressource_requested[2])) {
return array($this->ressource_requested[0], NULL, $this->ressource_requested[2], $this->ressource_requested[1],
$_POST);
// e.g.: http://www.foo.com/archive/show
} else {
return array($this->ressource_requested[0], NULL, $this->ressource_requested[1], NULL, NULL);
}
}
其思想是,无论访问者在浏览器中键入什么,函数都会解析请求并始终返回相同的格式化数组/输出。主机名后面的URL的第一段始终是主视点,例如:article。最后,我通过另一个名为includeTemplateFile的函数包含视图。这些文件具有以下命名约定:
viewpoint.child.action.template.php
e.g.: article.comments.show.template.php
我现在的问题是:有没有更优雅的解决方案?我读了一些关于这个主题的文章,例如:但我不喜欢大多数解决方案,因为它们设计得不好
以下是.htaccess文件的内容:
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?view=$1 [L,QSA]
提前感谢。好的,我首先要说我不是PHP专家,我建议使用symphony之类的框架来完成路由,但这里有一个可能的解决方案,您可以使用
function regexPath($path)
{
return '#' . str_replace([":int:", ":string:"], ["\d+", ".+"], $path) . '#';
}
function parseRequestedView($url)
{
$ressource_requested = explode('/', trim($url, '/'));
// define our routes, and the indices that each route will use (from the exploded url)
// this could be defined as another parameter or as a member of the class
$routes = [
regexPath("article/:int:/comments/show") => [0, 2, 3, 1], // will return array(resource[0], resource[2], resource[3], resource[1]), etc
regexPath("article/:int:/show") => [0, -1, 2, 1], // -1 will return a null
regexPath("archive/show") => [0, -1, 1, -1]
];
// go through each route, checking to see if we have a match
foreach ($routes as $regex => $indices)
{
if (preg_match($regex, $url))
{
// it matched, so go over the index's provided and put that data into our route array to be returned
foreach ($indices as $index)
{
$route[] = $index > -1 ? $ressource_requested[$index] : null;
}
// include the post data (not really nessesary)
$route[] = $_POST; // unnessesary to pass $_POST data through function, because it is global
return $route;
}
}
return null; // or some default route maybe?
}
$route = parseRequestedView("article/13/comments/show");
echo '<pre>';
print_r($route);
echo '</pre>';
/* returns:
Array
(
[0] => article
[1] => comments
[2] => show
[3] => 13
[4] => Array // this is our $_POST data
(
)
)
*/
首先,非常感谢你的回答。但让我指出,我的问题不是重复的,因为我在问我的解决方案设计得好还是有更好的。我对路由库没有任何问题。还是我看错了张贴的问题?非常感谢。你的解决方案比我的好得多。遗憾的是,我不能使用任何第三方框架规则。还有一件事:您能解释一下str_中的[:int:,:string:]和[\d+,.+]替换[:int:,:string:,[\d+,.+],$path到底是做什么的吗?非常感谢。这基本上只是为了方便。它将可读性更强的字符串转换为正则表达式模式。网上有很多关于它的好资源。