2011-06-28 41 views
1

我試圖創建一個基於註釋的路由系統(類似於Recess Framework)。PHP路由系統

<?php 

class MyController extends ActionController { 

    /** !Route GET /hello/$firstname/$lastname **/ 
    public function helloAction($firstname, $lastname) { 
     echo('Hello '.$firstname.' '.$lastname); 
    } 
} 

?> 

如果我去http://domain.com/hello/James/Bond我得到

Hello James Bond 

所以我有兩個問題:

1)這是個好主意嗎?優點和缺點vs集中式路由系統(如Zend Framework)。也許我沒有看到我後來用這種路由技術產生的問題。

2)如何檢查重複的路線,如果有正則表達式的路線

<?php 

class MyController extends ActionController { 

    /** 
    *!Route GET /test/$id = { 
    * id: [a-z0-9] 
    *} 
    **/ 
    public function testAction($id) { 
     echo($id); 
    } 

    /** 
    *!Route GET /test/$id = { 
    * id: [0-9a-z] 
    *} 
    **/ 
    public function otherTestAction($id) { 
     echo($id); 
    } 
} 

?> 

我得到兩條路線:/test/[a-z0-9]//test/[0-9a-z]/,如果我去http://domain.com/test/a12/兩條路線都是有效的。

謝謝:)

回答

1

缺點:

  • 可能難以保持在你的服務器上的所有方法URL映射的概述。
  • 要更改URL必須更改源代碼,映射不會與應用程序分離。

如果方法簽名和映射總是如你可以使用反射來提取其中helloAction被拾起爲/映射你好和每個方法參數的例子是相關的這些都在一個子目錄訂單,因爲它們的定義。

然後註釋就不需要複製URL,只有一個事實,即該方法是一個終點,是這樣的:

<?php 
    class MyController extends ActionController { 

     /** !endpoint(method=GET) **/ 
     public function helloAction($firstname, $lastname) { 
      echo('Hello '.$firstname.' '.$lastname); 
     } 
} 
+0

+1爲有趣的想法。我會考慮它。謝謝 – Tomas

0
  1. 我認爲這是一個好主意/解耦代碼和切入點似乎相當多的使用,隨處可見

  2. 通常你不檢查它:相匹配的第一個勝。

+0

難道不難發現一個錯誤,那麼重複的路線,你會得到比你預期的其他行動執行嗎? – Tomas

+0

對我來說這並不解耦代碼端點,因爲代碼包含端點。 – Kwebble

+0

@thomas:通常在調試時你應該能夠檢測到執行了哪個動作,所以它不應該是一個問題 – Arend

0

這樣做是一個好主意,只要你在生產緩存編譯後的路線。在路由時解析文件會產生相關成本,所以您不想在開發時避免這種情況。

至於檢查重複,不要通過比較聲明來檢查。只需檢查路由。如果兩個規則匹配,則拋出一個DuplicateRouteException。所以,在路由http://domain.com/test/a12/時,您會看到兩條路線都是有效的並拋出異常。

+0

我不認爲這是當路由是一個好主意時檢查重複路由,因爲當它很難測試所有路由並且在生產模式下用戶不應該看到'DuplicateRouteException'。 – Tomas

+0

@Tomas:這是在正則表達式'/ test/[0-9] +'和'/ test/[az] * [0-9] +'的情況下測試重複項的唯一可能方式。 - 可能導致重複路由的等效正則表達式。在生產中,您的錯誤處理程序可以將流量路由到錯誤頁面('「Oups,出錯了。」)。記錄異常。 –

2

嘗試使用Java annotation format這應該是更容易均勻解析。

它看起來是這樣的:

<?php 
class MyController extends ActionController { 

    /** 
     @Route(get=/hello/$firstname/$lastname) 
     @OtherVal(var1=2,var2=foo) 
     @OtherVal2 
    **/ 
    public function helloAction($firstname, $lastname) { 
     echo('Hello '.$firstname.' '.$lastname); 
    } 
} 
?> 

和分析你的註釋了具有以下的正則表達式:

@(?P<annotation>[A-Za-z0-9_]*)(\((?P<params>[^\)]*))? 

當然,這些緩存儘可能地避免重複解析。