2011-05-02 105 views
4

我目前正在框架上創建一個CMS。我有我的.htaccess文件,它看起來像這樣:支持多語言的PHP路由

<IfModule mod_rewrite.c> 
RewriteEngine On 

RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 

RewriteRule ^([A-Za-z]+)/(.*)$ index.php?url=$1 [PT,L] 

</IfModule> 

我的問題是,認爲:

1)我的頁面可以與正常的MVC URL訪問: http://example.com/pages/view/ {了,shorttag-的最頁}

2)我的網頁也與路由訪問: http://example.com/p/ {的-shorttag的最頁}

我真正需要實現的是,我可以訪問它有兩種方法:與語言支持 http://example.com/ {的-shorttag的最頁} 或者 http://example.com/ {語言}/{在-shorttag的最頁}

我的問題是,我不想改變mod_rewrite - 我寧願在PHP中創建路由,但我找不到解決方案,如何路由到PageController-> view()方法,而沒有在上面的示例中有一個靜態字母(「p」)條件。

你明白我的問題嗎? 你有一些提示,可能會導致我在正確的方向嗎?

回答

1

這聽起來像你需要實現某種形式的路由器。

我面對我自己,這是我如何做它的工作相當不錯:

有些路由器類解析URL。它將URL部分(/en/controller/action/param1/paramval1/)分解成幾部分。它決定語言代碼(如果未提供,則默認),控制器,操作等。 路由器還向系統的其他部分提供信息(控制器,操作名稱,參數),儘管您可以爲此目的實現特殊類別(例如請求)。

現在系統的不同部分可以通過路由器或請求類訪問給定的信息。從這裏開始,應該很容易實現多語言網站。

再一次,重要的部分是將URL映射到控制器和操作。當然,如果你不需要像/controller/action/parameter1這樣的URL,你應該有一些映射表(XML文檔/數據庫表),它將一個存根(頁面短標籤)映射到控制器和操作。它是讀取該表並根據給定規則確定控制器,操作和其他參數的路由器。

希望沒有複雜太多了:)

更新:使用XML文件

至於我自己,我已經實現映射。讓我進一步解釋一下:路由器負責解析URL。通常情況下,您的URL將包含控制器和操作名稱(在您的情況下,是控制器,視圖是操作)。

現在你的情況,你只需要一個存根,所以路由器必須以某種方式獲得有關哪個控制器和動作被調用的信息。這是映射的目的,將存根映射到適當的控制器和操作。

我已經實現了這個靜態路由,手動寫入XML文件,但您可以例如使用某種類型的插件類來檢查存根實際上是否與頁面相關。如果沒有,那可能意味着兩件事:它是一個控制器或請求是無效的。

讓我進一步討論碰撞:如果存根與任何控制器的名稱相同,就會發生碰撞。您是否應該使用給定的存根渲染頁面,或者調用控制器?這需要以某種方式解決,也許你可以通過編程方式限制用戶使用那種存根的頁面。另外,下次你用PHP進行應用程序開發時,我建議你使用一些着名的PHP框架(如果你還沒有,例如)。 Zend,Kohana或CodeIgniter。他們都提供路由器和許多其他組件,使開發應用程序變得更容易,更快速,更安全。

+0

最後一部分有點複雜 - 爲什麼我應該有一個映射數據庫?這是什麼目的?這是我第一次面對語言支持問題,所以它不是我最擅長的。 – 2011-05-02 16:15:28

+0

更新了答案,更詳細地解釋了關於映射 – usoban 2011-05-02 18:10:26

+0

Usoban:我現在更加註意你的想法。但是我需要提出一個小問題:這是否意味着我必須從數據庫中獲取所有短標籤,並檢查這些標籤是否在URL中。如果沒有,那麼我應該創建一個調度程序,該路由指向控制器(如果存在)。如果這些都不存在,則轉到錯誤頁面。 這是正確的嗎? – 2011-05-02 21:01:08

1

我這樣做是通過將域後的整個字符串傳遞給索引頁,並在php中處理它,而不是在.htaccess中處理。我不是一個.htaccess專家,但是這是爲我工作:

RewriteEngine On 
RewriteCond %{SCRIPT_FILENAME} !-d 
RewriteCond %{SCRIPT_FILENAME} !-f 

RewriteRule ^.*$ ./index.php 

我在安裝時指定,如果該網站會或不會使用郎的支持,我覺得既支持在同一個站點可能很難執行。

如果您需要更多詳細信息,請諮詢我。

修訂

丹尼斯,我讀@usoban後,我可以說我有一個類似的方法。正如我所說的,我從.htaccess到我的application類的域後獲得完整路徑並將其解析爲數組。如果在配置中指定'多語言',我將獲取第一個數組元素併爲該語言加載'別名'表。

在「別名」表是一個關聯數組地圖別名控制器,像這樣:

$lang_mods = array(
    'home'  => 'Home', 
    'contact' => 'Contact', 
    'sitemap' => 'Sitemap', 
    'about'  => 'Section/about', 
    'terms'  => 'Section/terms', 
); 

以這種方式,我可以有一個完全轉變的URL,即:

http://www.example.com/en/contact 和: http://www.example.com/es/contacto

因此,從url數組中刪除第一個語言元素後,我檢查下一個元素對別名表。表中的最後兩個項目是可以爲了簡化URL中使用的特殊情況下,收到

http://www.example.com/en/about 代替 http://www.example.com/en/section/about 看起來更好,但都指向同一個Section控制器。

刪除語言和別名後,數組中的其餘元素(如果有)傳遞給控制器​​。例子中的'about'或'terms',被前置於參數數組中。根據控制器的不同,第一個參數可以是動作或不動作。

如果在此過程的某個步驟中,某些內容與允許的值不匹配,則會將其重定向到主頁。

好吧,在你的情況下,也許如果第一個參數(或第二個,如果網站是多語言)可以檢查可用的控制器,如果它不存在,你可以路由到一個'默認'然後檢查您的數據庫中可用的頁面。通過這種方式,您可以避免在url中增加/p/

我想清楚,對不起,英語不是我的母語;)

+0

這就是我現在要做的。我的問題是,我需要PHP代碼來實現它。 我製作了一張帶語言的表..如果有多種語言,那麼應該有語言支持 – 2011-05-02 16:00:19

+0

我在我的框架中完成它,但我不能給你一個簡短的答案,因爲我的語言支持與許多其他功能。稍後我會盡量簡要介紹一下。 (對不起,我的英語) – morgar 2011-05-02 16:10:04

+0

這聽起來真的很棒!這是我在CMS中的最後一個腦袋......我真的不想讓som成爲「OOOPS」:P – 2011-05-02 16:10:56