2013-03-19 34 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