19

それで、私が取り組んでいるいくつかのアプリのベースにしたいフレームワークを書いています(フレームワークはそこにあるので、作業する環境と、たとえば単一のアプリケーションを使用できるシステムがあります入社する)

私はこのフレームワークを作りたいと思っており、そのアプリはリソース指向アーキテクチャを使用しています。

今、私は APP ライターによって拡張可能な URL ルーティング クラスを作成したいと考えています (おそらく CMS アプリ ユーザーによっても拡張可能ですが、それは将来的には WAYYYYY になります)。他のアプリがそれを行う方法。

4

8 に答える 8

14

常識であるため、独自の形式を作成するよりも正規表現を使用する方が好きです。これらの正規表現ルーティングテーブルをネストできるようにする小さなクラスを作成しました。以前は継承によって実装されたものと似たものを使用していましたが、継承は必要なかったので書き直しました。

キーに対して正規表現を実行し、自分の制御文字列にマップします。以下の例を見てください。訪問する/api/related/joeと、ルータークラスが新しいオブジェクトを作成し、そのApiControllerメソッドを呼び出しますrelatedDocuments(array('tags' => 'joe'));

// the 12 strips the subdirectory my app is running in
$index = urldecode(substr($_SERVER["REQUEST_URI"], 12)); 

Route::process($index, array(
    "#^api/related/(.*)$#Di"    => "ApiController/relatedDocuments/tags",

    "#^thread/(.*)/post$#Di"    => "ThreadController/post/title",
    "#^thread/(.*)/reply$#Di"   => "ThreadController/reply/title",
    "#^thread/(.*)$#Di"         => "ThreadController/thread/title",

    "#^ajax/tag/(.*)/(.*)$#Di"  => "TagController/add/id/tags",
    "#^ajax/reply/(.*)/post$#Di"=> "ThreadController/ajaxPost/id",
    "#^ajax/reply/(.*)$#Di"     => "ArticleController/newReply/id",
    "#^ajax/toggle/(.*)$#Di"    => "ApiController/toggle/toggle",

    "#^$#Di"                    => "HomeController",
));

エラーを抑えて単純化するために、テーブルを細分化することができます。このようにして、ルーティングテーブルをそれが制御するクラスに配置できます。上記の例では、3つのスレッド呼び出しを1つにまとめることができます。

Route::process($index, array(
    "#^api/related/(.*)$#Di"    => "ApiController/relatedDocuments/tags",

    "#^thread/(.*)$#Di"         => "ThreadController/route/uri",

    "#^ajax/tag/(.*)/(.*)$#Di"  => "TagController/add/id/tags",
    "#^ajax/reply/(.*)/post$#Di"=> "ThreadController/ajaxPost/id",
    "#^ajax/reply/(.*)$#Di"     => "ArticleController/newReply/id",
    "#^ajax/toggle/(.*)$#Di"    => "ApiController/toggle/toggle",

    "#^$#Di"                    => "HomeController",
));

次に、ThreadController::routeを次のように定義します。

function route($args) {
    Route::process($args['uri'], array(
        "#^(.*)/post$#Di"    => "ThreadController/post/title",
        "#^(.*)/reply$#Di"   => "ThreadController/reply/title",
        "#^(.*)$#Di"         => "ThreadController/thread/title",
    ));
}

また、右側のルーティング文字列に必要なデフォルトを定義できます。それらを文書化することを忘れないでください。そうしないと、人々を混乱させることになります。右側に関数名が含まれていない場合は、現在インデックスを呼び出しています。これが私の現在のコードです。好みのエラーやデフォルトのアクションを処理するように変更することをお勧めします。

于 2008-09-24T17:44:40.417 に答える
2

さらに別のフレームワーク? - とりあえず...

ルーティングの秘訣は、ルーティングコントローラーにすべて渡すことです。

おそらく、私がここで文書化したものと同様のものを使用したいと思うでしょう:

http://www.hm2k.com/posts/friendly-urls

2 番目のソリューションでは、Zend Framework と同様の URL を使用できます。

于 2009-04-16T21:01:23.510 に答える
1

正規表現のリストを使用して、使用するオブジェクトを一致させます

例えば

^/users/[\w-]+/bookmarks/(.+)/$
^/users/[\w-]+/bookmarks/$
^/users/[\w-]+/$

長所: 素晴らしくシンプルで、ルートを直接定義できます 短所: 注文する必要があり、新しいものを簡単に追加できません (非常にエラーが発生しやすい)

これは、私の知る限り、Djangoが行う方法です

于 2008-09-24T07:18:15.133 に答える
0

多くのフレームワークは、Apacheのmod_rewriteとフロントコントローラーの組み合わせを使用していると思います。mod_rewriteを使用すると、次のようなURLを使用できます:/ people / get / 3次のように:index.php?controller = people&method = get&id=3。Index.phpは、指定されたパラメーターに基づいてページ要求をルーティングするフロントコントローラーを実装します。

于 2008-09-24T11:53:07.843 に答える
0

ご想像のとおり、それを行う方法はたくさんあります。

たとえば、Slim Frameworkでは、ルーティング エンジンの例は次のようになります (パターンに基づく${OBJECT}->${REQUEST METHOD}(${PATTERM}, ${CALLBACK})):

$app->get("/Home", function() {
    print('Welcome to the home page');
}

$app->get('/Profile/:memberName', function($memberName) {
    print( 'I\'m viewing ' . $memberName . '\'s profile.' );
}

$app->post('/ContactUs', function() {
    print( 'This action will be fired only if a POST request will occure');
}

したがって、初期化されたインスタンス ( $app) は、リクエスト メソッド (get、post、put、delete など) ごとにメソッドを取得し、最初のパラメーターとしてルートを取得し、2 番目のパラメーターとしてコールバックを取得します。

ルートはトークンを取得できます。トークンは、実行時に一部のデータ (メンバー名、記事 ID、組織の場所名など、すべてのルーティング コントローラーと同様) に基づいて変更される「変数」です。

個人的には、この方法は好きですが、高度なフレームワークに十分な柔軟性があるとは思いません。

私は現在 ZF と Yii を使用しているので、私が働いている会社のフレームワークの一部として作成したルーターの例があります。

ルート エンジンは正規表現 (@gradbot のものと同様) に基づいていますが、双方向の会話が行われるため、クライアントが mod_rewrite (Apache で) を実行できない場合や、サーバーに書き換えルールを追加できない場合は、従来の URL とクエリ文字列を引き続き使用できます。

ファイルには配列が含まれており、それぞれが次の例のようになっています。

$_FURLTEMPLATES['login']    =   array(
    'i' => array( // Input - how the router parse an incomming path into query string params
        'pattern' => '@Members/Login/?@i',
        'matches' => array( 'Application' => 'Members', 'Module' => 'Login' ),
    ),
    'o' => array( // Output - how the router parse a query string into a route
        '@Application=Members(&|&)Module=Login/?@' => 'Members/Login/'
    )
);

次のような、より複雑な組み合わせを使用することもできます。

$_FURLTEMPLATES['article']  =   array(
    'i' => array(
        'pattern' => '@CMS/Articles/([\d]+)/?@i',
        'matches' => array( 'Application' => "CMS",
            'Module' => 'Articles',
            'Sector' => 'showArticle',
            'ArticleID' => '$1' ),
    ),
    'o' => array(
     '@Application=CMS(&|&)Module=Articles(&|&)Sector=showArticle(&|&)ArticleID=([\d]+)@' => 'CMS/Articles/$4'
    )
);

要するに、私が思うに、可能性は無限大です。それは、フレームワークをどれだけ複雑にしたいか、それを使って何をしたいかによって異なります。

たとえば、それが Web サービスまたは単純な Web サイト ラッパーであることを意図している場合は、Slim フレームワークの記述スタイルに従ってください。非常に簡単で見栄えの良いコードです。

ただし、それを使用して複雑なサイトを開発したい場合は、正規表現が解決策になると思います。

幸運を!:)

于 2012-07-01T09:28:18.057 に答える
-1

Zend の MVC フレームワークは、デフォルトで次のような構造を使用します。

/router/controller/action/key1/value1/key2/value2

ここで、 はルーター ファイルです ( を介してrouterマッピングされます。は、 という名前のコントローラー内のメソッドから派生して参照するクラスによって定義されるコントローラー アクション ハンドラーからのものです。キーと値のペアは任意の順序で実行でき、アクションで使用できます。連想配列としてのメソッド。mod_rewritecontrollerZend_Controller_ActionactionactionAction

私は自分のコードで過去に似たようなものを使用しましたが、これまでのところかなりうまく機能しています。

于 2008-09-24T13:41:34.993 に答える
-4

MVCパターンを見てみてください。
たとえば、Zend Framework はそれを使用しますが、CakePHP、CodeIgniter なども使用します。

個人的には MVC モデルは好きではありませんが、ほとんどの場合、「View for Web」コンポーネントとして実装されています。

決定はかなり好みに依存します...

于 2008-09-24T10:11:11.223 に答える