2013-03-19 32 views
2

我有以下类不能让PHP路由器发送正确的头

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匹配时,循环继续。

有谁知道什么是错的?

回答

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(...) 
} 
+0

工程就像一个魅力。感谢您帮助我理解Php。第一个真正的项目只是一个初学者。 – Dany 2013-03-19 18:16:49