2

我有以下课程

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"); } 

该函数正常执行,但如果找不到页面,我将无法发送标题。还有其他解决方法吗?

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

有谁知道出了什么问题?

4

1 回答 1

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(...)
}
于 2013-03-19T14:23:50.010 回答