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();

ルートにアクセスするとすべてが正常ですが、リンク「/ tests /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 に答える