无法让Php路由器发送正确的标头

时间:2013-03-19 11:08:56

标签: php regex 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();

访问root时一切都很好,但是当我访问带有“/ testing / test”或“/ testing”链接的页面时,会出现404消息,但用户函数执行正常。

当我删除以下部分时

else{ header("HTTP/1.0 404 Not Found"); } 

该函数正常执行,但如果找不到页面,则无法发送标题。还有另一种解决方法吗?

主要问题似乎是break语句。当密钥与请求uri匹配时,循环继续。

有谁知道出了什么问题?

1 个答案:

答案 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(...)
}