我有以下类(class)
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();
访问根目录时一切正常,但是当我访问带有链接“/testing/test”或“/testing”的页面时,会出现 404 消息,但用户函数执行正常。
当我删除以下部分时
else{ header("HTTP/1.0 404 Not Found"); }
该函数正常执行,但如果找不到页面,我将无法发送 header 。还有其他解决方法吗?
主要问题似乎是break语句。当 key 与请求 uri 匹配时,循环继续。
有人知道哪里出了问题吗?
最佳答案
仅当循环结束但未找到匹配项时,才需要发送 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(...)
}
关于php - 无法让 Php 路由器发送正确的 header ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15497812/