4

私は基本的なMVCフレームワークをphpの学習プロジェクトとして開発しました。これは実際には2番目のバージョンであり、最初のバージョンでは不十分だった2つの側面を改善しようとしています。

  • リクエストルーティング:リクエストのマッピング(例:/ controller / action / [params])
  • モジュール:アプリケーションを拡張するように設計されたドロップインアプリケーション(CMSなど)。

これは私が今いるところです:

  1. リクエストを受け取り、それをさまざまな部分(コントローラー、アクション、引数など)に解析できます。これらは、対応するコントローラークラス/ファイル(「/ foo / bar」など)にマップされます-> FooController :: bar() -これらはすべて、RequestRouterクラスで実行され、Requestオブジェクトにカプセル化されています。

    • アプリケーションファイルへの分類された参照(コントローラー、libなど)を含むマニフェストオブジェクトを維持しています。マニフェストは私のオートローダーメソッドで使用されます。
    • マニフェストはキャッシュされるため、新しいファイル/クラスを追加するたびに再構築されます。これは、新しいモジュールが追加/削除されるときに当てはまります。
  2. Controller :: methods()は、正しいビューを適切にレンダリングします。

  3. 次に、コアが構造化されているように編成されたモジュールがあります(/ root / raspberry / vendors / core / module)

問題

私が現在抱えている問題は、モジュールが関係するルーティング/リクエスト処理の組み合わせです。

  • project.dev/adminをリクエストすると、 AdminController :: index()にマップされます-これは正しいです
  • ただし、project.dev / admin / editorを参照すると、AdminController :: editor()が取得されます。ここで、本当に必要なのはEditorController :: index()です。

いくつかの調査の結果、フロントコントローラーパターンを実装し、特定のコントローラーをラップするデコレーターを作成できると思います。デコレータは、リクエストを再解析して/ editorをコントローラにし、残りのセグメント(/ editor / action / args)を再マップすることができます。

これらはすべて正常に機能するように見えますが、フローの早い段階で基本的なもの(RequestRouter)が欠落しているように感じます。私はここSOで他の同様の質問を調査し、HMVCを読みました。原則として、それは私の質問に答えるかもしれないようですが、フレームワーク主導よりもインターフェース主導のようです(それが理にかなっている場合)。コハナのような他のフレームワークも調べましたが、それらのモジュールシステムと同じモジュール内の複数のコントローラーへのルーティングがどのように機能するかを完全には把握していません。

フロントコントローラーを導入したり、リクエストを再解析したりせずにモジュールシステムを効果的に実装する方法についての洞察や提案をいただければ幸いです。または、モジュールを別の方法で再構築する必要がある場合は、その方法を理解したいと思います。

追加情報:

私のRequestRouterは、事前に定義したルートのリストを保持しています(デフォルトのメソッドを含む)。これらの事前定義されたルートを使用して、 / admin/editorにアクセスしてEditorController::index()を取得できますが、モジュール内のコントローラーに送信されるすべてのコントローラーとリクエストのルートを定義する必要があります。これは良いデザインではないと思います。これが私のルートのサンプルです:

Array
(
    [/foo] => Array
        (
            [controller] => FooController
            [method] => bar
            [path] => /core
        )

    [/admin] => Array
        (
            [controller] => AdminController
            [method] => index
            [path] => /vendors/admin
        )

    [/admin/editor] => Array
        (
            [controller] => EditorController
            [method] => index
            [path] => /vendors/admin
        )

)

これは私のRequestオブジェクトがどのように見えるかです:

Request Object
(
    [properties:Request:private] => Array
        (
            [url] => /admin/editor
            [query] => 
            [uri] => /admin/editor
            [controller] => admin
            [action] => editor
            [args] => 
            [referrer] => Array
                (
                    [HTTP_REFERER] => 
                    [REMOTE_ADDR] => 127.0.0.1
                    [HTTP_VIA] => 
                    [HTTP_X_FORWARDED_FOR] => 
                )

            [get] => 
        )

    [request_status:Request:private] => 200
)

これは私のマニフェストのサンプルです:

[controller] => Array
    (
        [icontroller] => /htdocs/raspberry/raspberry/core/controller/icontroller.class.php
        [index] => /htdocs/raspberry/raspberry/core/controller/index.php
        [serviceerror] => /htdocs/raspberry/raspberry/core/controller/serviceerror.controller.php
        [admin] => /htdocs/raspberry/raspberry/vendors/core/admin/controller/admin.controller.ph
        [composer] => /htdocs/raspberry/raspberry/vendors/core/admin/controller/composer.controller.php
    )

これはアプリケーションファイルシステムです。

http://s11.postimage.org/pujb2g9v7/Screen_shot_2012_10_09_at_8_45_27_PM.png

4

1 に答える 1

3

この問題は、ルーティングメカニズムが単純化されすぎていることが原因のようです。私が得た印象はexplode()、URLからパラメーターを収集するために単純に使用しているということです。これは基本的な例ではうまく機能しますが、もう少し高度なルーティングスキームを使用しようとすると、セットアップは失敗します。

で文字列を分割する代わりに、/正規表現パターンと照合する必要があります。基本的に、照合するパターンのリストを定義し、最初の照合を使用してRequestインスタンスにデータを入力します。

あなたの状況では、2つのパターンが定義されます。

  • '#admin/(:?(:?/(?P<controller>[^/\.,;?\n]+))?/(?P<action>[^/\.,;?\n]+))?#'
  • '#(:?(:?/(?P<controller>[^/\.,;?\n]+))?/(?P<action>[^/\.,;?\n]+))?#'

最初のものが失敗した場合、2番目のものが一致します。

PSコントローラーは出力をレンダリングすることを想定していないことを知っておく必要があります。応答の生成は、ビューインスタンスの責任です。ビューは、プレゼンテーションロジックを含み、複数のテンプレートからの応答を構成できる完全に機能するオブジェクトである必要があります。

于 2012-10-10T02:09:44.453 に答える