KO3:HMVCとルーティング

少し前に、このフレームワークの3番目のバージョンがリリースされました。 リリース前でも、私は新機能の短いレビューをしました。 それからルーティングとHMVCのトピックを調べましたが、今日は改善する準備ができています。



パート1、ルーティング



そのため、ルーティングは大きく変わりました。 設定は構成ファイルには保存されなくなりましたが、次の構文の静的Route :: setメソッドを使用してブートストラップファイルコードに設定されます。

/**

* Stores a named route and returns it.

*

* @param string route name

* @param string URI pattern

* @param array regex patterns for route keys

* @return Route

*/

public static function set ($name, $uri, array $regex = NULL)


* This source code was highlighted with Source Code Highlighter .






このメソッドはルートを返します。これは、 URLから取得する必要があるパラメーターに関する情報を格納するオブジェクトであり、thisまたはそのurlを処理できるかどうかを判断できます。 ほとんどのURLアドレスを特定のコントローラーメソッドにマッピングするために使用されていた基本的なルールは、デフォルトルートになりました。これは、 ブートストラップファイルの例として簡単に削除および設定できます。

Route:: set ( 'default' , '(<controller>(/<action>(/<id>)))' )

->defaults(array(

'controller' => 'welcome' ,

'action' => 'index' ,

));


* This source code was highlighted with Source Code Highlighter .






特定のルートurlの対応を決定するとき、ルートは追加の順序でテストされるため、よりプライベートなルールの後に、より一般的なルールを追加する必要があることに注意してください。 この場合、 デフォルトルートは非常に一般的であり、それを残すことにした場合は、その前に他のすべてのルートを追加することをお勧めします。



Route ::のオプションをより慎重に設定してください。 最初のパラメーター$ nameは、ルートをさらに識別するために使用されます。特に、 Route :: getメソッドはそれを渡す必要があります。 次のパラメーター$ uriは、このルートに適したURLの外観を決定するテンプレートです。 このテンプレートでは、すべてのパラメーターは三角括弧で示されている必要があります(デフォルトルートのコントローラーアクションID )。 キャプチャされたすべてのパラメーターは、 Request-> param($ name、$ default)から利用できますURLの一部がオプション(パラメーターを含む)である場合は、括弧で囲む必要があります。 Route :: setメソッドの最後のパラメーターは、パラメーターをテストする正規表現を含む$ regex配列です。 デフォルトでは、すべてのパラメーターは式「[^ /。、;?] ++」でテストされます。 この式が適切でないパラメーターがある場合は、パラメーター名に対応する配列のキーを持つ適切な式を$ regex配列に渡す必要があります。 たとえば、デフォルトルートの場合、このような配列を設定することは論理的です。

Route:: set ( 'default' , '(<controller>(/<action>(/<id>)))' , array(

'id' => '\d{1,10}' ,

))


* This source code was highlighted with Source Code Highlighter .






各パラメーターについて、シャロンのパラメーターがオプションとして指定され、 urlに存在しない場合に使用されるデフォルト値を設定できます。 これは、 Routesオブジェクトに適用され、 Route :: setメソッドの$ regexパラメーターと同じ原理で構築された配列を引数として取るdefaultsメソッドを使用して行われます。



urlおよびdefaultsメソッドを介して渡すことができるパラメーターの中には、特別な値を持つ3つのパラメーターがあります。 それらの名前はcontrolleraction 、およびdirectoryです。 これらのパラメーターは、 Request-> paramメソッドから取得することはできませんが、 Requestオブジェクトから直接利用できます。 つまり Request-> controllerRequest-> action 、およびRequest-> directory

コントローラーパラメーター 3つのうちの唯一の必須です。 直接URLにするか、 Route-> defaultsメソッドで設定する必要があります。 名前はそれ自体を物語っています。

アクションパラメーター 名前を話す別のパラメーター。 指定されていない(または空の文字列として示されている)場合、デフォルト値の「インデックス」が使用されます。

ディレクトリパラメータ 目的のコントローラーを検索するコントローラーディレクトリのサブディレクトリを指定します。 ファイルがcontroller / tools / sidebars / bottomにある場合、クラス名はController_Tools_Sidebars_Bottomであり、パラメーターはcontroller = 'bottom'、directory = 'tools / sidebars'である必要があります。



このアプローチでどのような可能性が開かれるかを明確にするために、ルーティングルールの例をいくつか示します。



例1

Route:: set ( 'wigets' , 'wigets(/<action>(/<id>))' )

->defaults(array(

'controller' => 'wiget' ,

));


* This source code was highlighted with Source Code Highlighter .






このルートに一致するには、アドレスはウィジットから開始する必要があります。スラッシュを使用して2つの任意のパラメーターを指定できます。 URLからコントローラーを変更する方法はないため、ルートは1つのwigetコントローラーのみを提供します。



例2

Route:: set ( 'articles' , 'articles(/<action>(/<sorting>/<page>))' , array(

'sorting' => '(?:asc|desc)' ,

'page' => '\d{1,5}'

))


* This source code was highlighted with Source Code Highlighter .






アドレスは記事で始まる必要があります。その後、オプションのアクションパラメーターと2つのパラメーターは、指定された正規表現を持つ1つの括弧のみで囲まれます。 括弧内の式は、完全に省略するか、受け入れることができます。 この場合、これは、アドレスが/ articles / list / asc /という形式である場合、ascパラメータは受け入れられないことを意味します。括弧内には、何にも対応しない別のパラメータがあるためです。



例3

Route:: set ( 'articles' , 'articles(/<action>((/<id>)/<sorting>(<page>)))' , array(

'sorting' => '(?:name|date|age)' ,

'page' => '\d{1,5}' ,

))


* This source code was highlighted with Source Code Highlighter .






そして、ここでは、一般に、驚くべきことが実証されています。 まず、idパラメーターはオプションであり、式の最後にありません。 これは、住所/記事/リスト/ 154 /日付および/記事/リスト/日付が正しいことを意味します。 さらに、ソートはページごとにセパレーターで区切られていないため、url / articles / list / date20も受け入れられます。



例4

Route:: set ( 'articles' , 'articles(,<action>((,<id>),<sorting>(<page>)))' , array(

'sorting' => '(?:name|date|age)' ,

'page' => '\d{1,5}' ,

))


* This source code was highlighted with Source Code Highlighter .






同じこと、区切り文字のみがコンマです。 想像力の境界はありません:)



一般に、ルートについて言えば、古いバージョンのように1つの一般的なルールに依存するのではなく、より安全なプライベートな記述を作成することをお勧めします。 確かに、アプリケーションの起動時に各ルートに対して正規表現が生成されるため、小さな待ち伏せがあります。 もちろん、これは数十のルートではあまり速くないため、ルートをキャッシュする必要があります。

if ( ! Route::cache())

{

Route:: set ( /*…*/ );



Route:: set ( /*…*/ );



Route::cache(TRUE);

}


* This source code was highlighted with Source Code Highlighter .








ルーティングアドレスに加えて、ルートには別の重要な目的があります。それらの助けを借りて、同じアドレスを生成できます。 これを行うには、 Route-> uri($ params)メソッドがあります。このメソッドは、欠落しているパラメーターを連想配列の形式で受け取り 、完成したuriを返します。



パート2、HMVC



多くの人は、新しいコハナがHMVCパラダイムに基づいていることを既に聞いています。これは、通常のMVCとは異なり、コンポーネントはいずれも、httpプロトコルをバイパスして、必要に応じてコントローラに別のリクエストを起動できます。 これは例で簡単に説明できます。

/*

* id 12

*/

Request::factory( '/wigets/advert/client12' )

->execute()


* This source code was highlighted with Source Code Highlighter .






url文字列はファクトリメソッドに渡され、ルーティングサイクルを再度通過します。



実際、httpを介して到着するメインリクエストの処理は、上記のリクエストとそれほど変わりません。

/**

* Execute the main request. A source of the URI can be passed, eg: $_SERVER['PATH_INFO'].

* If no source is specified, the URI will be automatically detected.

*/

echo Request::instance()

->execute()

->send_headers();


* This source code was highlighted with Source Code Highlighter .






唯一の違いは、シングルトン(メインリクエスト)またはファクトリーを介してリクエストオブジェクトを作成する方法です。 どちらの場合でも、 Request-> responseプロパティで答えを取得します(これは名前のあるトートロジーです)。 Requestオブジェクトを文字列に変換しようとすると(2番目の例のechoステートメントのように)、 $ this->応答が返されます。



Requestオブジェクトを取得する方法のこの違いから、3番目のKohanaを使用する場合は1つの厳密なルールに従います。クエリ変数を取得して結果を返すには、どのRequestオブジェクトにアクセスする必要があるかを明確に理解する必要があります。 アプリケーション全体のリクエストはRequest :: instance()で常に利用でき、現在のルートのリクエストはController-> requestで利用できます。 コントローラー$ this->リクエストで。



実際、そのようなアプローチの必要性は長い間待ち望まれています。 大規模なサイトでは、そのデザインにあらゆる種類のウィジェット、サイドバー、その他のブロックがあり、そのコンテンツはページのメインコンテンツに弱く依存しますが、その表示にはコントローラーの操作が必要です。 以前は、1つのコントローラー内でブロックが必要な場合は、別のメソッドが作成され、賢明でなければなりませんでした。 より多くのコントローラーの場合、ブロックの複雑さに応じて、モデルまたはビューに転送されました。 これで終わりです。次のようなビューで、ためらうことなく任意のURLを呼び出すことができます。

<div class = "sidebar" >

<?= Request::factory( '/wigets/voting' )->execute() ?>

</div>


* This source code was highlighted with Source Code Highlighter .






そして今、追加のボーナス:このブロックにデータを送信するフォームがある場合(たとえば、投票用紙)、ajaxリクエストを直接/ wigets / votingに送信し、追加のチェックなしでこのブロックのテキストを受信できます。あったかどうか。



コンテンツブロックに関するすべてはもちろん素晴らしいことですが、これはkohanでのHMVCの使用に限定されません。 事実、返されるデータの形式を選択する際に誰も私たちを制限しません。 Request-> responseには任意のタイプのデータを書き込むことができ、反対側でそれを受け入れるのは非常に簡単です。 これがなぜ必要なのかはまだわかりませんが、どのコントローラーやビューでもデータを取得できるという事実は非常に喜ばしいことです。



リクエストで気付いたもう1つの機能は、1つのオブジェクトのexecute()メソッドを何度でも呼び出すことができることです。 さらに、kokhanのリクエスト間で、応答プロパティを使用した操作(クリアなど)を行いません。 これはバグと機能の両方です。 まず、注意して、自分で応答をリセットし、次に、リクエスト間でデータを蓄積できることに注意してください(もちろん、 Requestオブジェクトが変更されない場合)。



パート3、最適なルーティングとHMVCの統合



さて、今、個人的に私からいくつかの推論。 Request :: factory( 'url')オブジェクトを作成するための提案された方法は良くありません。 実際、常によりスマートに行う必要があります。

Request::factory(Route:: get ( 'wigets' )->uri(array(

'action' => 'userslist' ,

'sorting' => 'name' ,

)));


* This source code was highlighted with Source Code Highlighter .






つまり アドレスを手動で作成するのではなく、ルートから生成します。



そして、ここで、私の意見では、アーキテクチャに小さな欠陥があります。 実際には、uri文字列を取得するためにルートにパラメーターを渡し、Requestでパラメーターを取得するために文字列を渡します。 これを呼び出すと、パフォーマンスが低下します。

-uri文字列生成の損失(コントローラーを実行する必要はありません)

-ルートとの一致の不必要なチェック(ルートは事前にわかっています)

-パラメータのuriの解析



次のようなことができたら素晴らしいと思います。

Request::factory( 'wigets' , array(

'action' => 'userslist' ,

'sorting' => 'name' ,

));


* This source code was highlighted with Source Code Highlighter .






Request :: factoryメソッドと重複するモジュールを考えて書いた。 このモジュールは、上記のクエリ作成インターフェイスを補完します。 さらに、空のクエリ実行時間は半分になります。 最初のパラメーターはルートの名前で、2番目はパラメーターの配列です。 2番目のパラメーターが指定されていない場合、前述のように最初のパラメーターはuri文字列と見なされます。 つまり 機能が中断することはありません。



モジュールをダウンロードします。



この表記を使用する場合の唯一の副作用は、 Request-> uri行に、ルートで指定された実際のuriが含まれず、/ route / controller / actionという形式の行が含まれることです。 特に、これはプロファイラーの出力で確認できます。



ご清聴ありがとうございました。



ウクライナ語の専門家への大きなリクエストは控えてください。 すべてはすでに知っています。



All Articles