1

PHP MVC 設計構造のチュートリアルのほとんどでは、ルーター クラスを使用してユーザー入力を取得し、その入力を正確に処理するために適切なコントローラーを検索します。入力は通常、url の形式を取ります。たとえばhttp://example.com/foo/bar/、ルーターに foo という名前のコントローラーを見つけて、メソッド bar を起動するように依頼します。

PHP には、クラスに使用する一貫した命名システムを必要とする自動インクルード機能もあります。たとえば、クラス Foo のインスタンスを取得したい場合、ファイルを Foo.php という名前にする必要があり、その中に Foo という名前のクラスがあります。

残念なことに、これらのメカニズムは相まって、命名システムに競合する要求を課します。URL は非常に「前面」であるため、クライアントは特定のページのコンテンツを反映するために必要になることがよくあります。たとえば、会場への道順を示すページがある場合、クライアントはこのページが にあることを必要とする場合がありますhttp://example.com/venues/directions/。後でコンテンツが変更される可能性があり、会場の数が 1 に減り、クライアントは URL を読み取ろうとしますhttp://example.com/venue/directions/。明らかに、これは非常に些細な例ですが、時々 URL を変更する必要があることは明らかだと思います。

URL はコントローラー クラスに非常に密接に関連付けられているため、URL を変更すると、クラス ファイル名、クラス名自体、およびそのクラスのインスタンスをすべて変更する必要があります。より複雑なシステムの場合、これは非常に時間がかかるように思えます。

この問題にはどのような解決策がありますか? URL とコントローラーの関係が保存され、いずれかの名前に関係なく任意の URL を使用して任意のコントローラーを呼び出すことができるようなディレクトリが必要になるように私には思えます。したがって、会場コントローラーと会場 URL があり、クライアントが URL の変更を要求すると、新しい「会場」を「会場」に変換するディレクトリを変更するだけです。

これを行う最善の方法はデータベース テーブルにあると思いますが、これにはユーザー リクエストごとに追加のクエリが必要です。データベースはディレクトリを実装する正しい方法ですか? ディレクトリは上記の問題を解決する最良の方法ですか? そもそもこの問題は問題なのでしょうか???

4

2 に答える 2

4

これに対するいくつかの解決策は、コントローラー/アクションへのルーティング「接続」を明示的に指定することです。

たとえば、NiceDogでは、次のようなルートを指定できます

R('venues?/directions')
  ->controller('VenueController')
  ->action('directionsAction')
  ->on('GET');

URL に一致する正規表現を許可します。(上記の式はvenue/directionsorに一致venues/directionsします) 私はこの方法が好きです。なぜなら、この方法はコントローラーの命名スキームを URL の命名スキームから分離するからです。

別のより構成ベースのアプローチは、ある種の明示的なマッピングを行うことです。

$routes = array(
    'venues?' =>
      array('controller'=>'VenueController','action'=>'indexAction'),
    'venues?/directions' =>
      array('controller'=>'VenueController','action'=>'directionsAction')
);

そして、簡単なディスパッチ関数:

function dispatch($url,$routes) {
    foreach ($routes as $pattern=>$map) {
        if (preg_match($pattern,$url,$matches)) {
            $controller = new $map['controller']();
            $action = $map['action'];
            call_user_func_array(
              array($controller,$action),
              array_slice($matches,1)
            );
            return true;
        }
    }
    throw new Exception('Route not found.');
}
于 2010-06-21T13:55:21.450 に答える
0

この問題を解決する良い方法は、MVC フレームワークで独自のルーティング ルールを指定できるようにすることです。たとえば、CodeIgniter フレームワークのドキュメントのURI ルーティングを参照してください。

あなたの例に沿って、これにより to のリクエストを再マップでき/venues/ます/venue

于 2010-06-21T13:35:09.860 に答える