我有以下课程
class Route{
private $urls = array();
public function add($url, $function){
$this->urls[str_replace('/', '\/', $url)] = $function;
}
public function dispatch(){
ksort($this->urls);
foreach ($this->urls as $url => $function) {
if (preg_match('/^' . $url . '$/', $_SERVER['REQUEST_URI'], $match)){
call_user_func($function, $match);
break;
} else{
header("HTTP/1.0 404 Not Found");
}
}
}
}
使用像这样的课程时
$route = new Route();
$route->add('/', function(){
echo 'test';
});
$route->add('/([a-zA-Z]+)', function($match){
echo 'test <pre>';
print_r($match);
});
$route->add('/([a-zA-Z]+)/([a-zA-Z]+)', function($match){
echo 'test <pre>';
print_r($match);
});
$route->dispatch();
访问root时一切都很好,但是当我访问带有“/ testing / test”或“/ testing”链接的页面时,会出现404消息,但用户函数执行正常。
当我删除以下部分时
else{ header("HTTP/1.0 404 Not Found"); }
该函数正常执行,但如果找不到页面,则无法发送标题。还有另一种解决方法吗?
主要问题似乎是break语句。当密钥与请求uri匹配时,循环继续。
有谁知道出了什么问题?
答案 0 :(得分:2)
只有在循环结束而没有找到匹配项时才需要发送404。在循环之后移动header
调用并返回而不是中断。
foreach ($this->urls as $url => $function) {
if (preg_match('/^' . $url . '$/', $_SERVER['REQUEST_URI'], $match)){
call_user_func($function, $match);
return;
}
}
header("HTTP/1.0 404 Not Found");
或者如果在任何一种情况下都需要发生其他逻辑,你可以在循环中设置一个像$found
这样的变量。
$found = false;
foreach (...) {
if (...) {
call_user_func(...);
$found = true;
}
}
if (!$found) {
header(...)
}