ThinkPHP仿58同城一站多城市路由配置技巧及二級域名部署技巧

ThinkPHP在PATHINFO的URL模式下,URL的格式相似於http://www.domain.com/appName/module/actionphp

即:http://www.domain.com/分組名/模塊名/方法名html

或者:http://www.domain.com/模塊名/方法名thinkphp

然而在有些相似於58同城這樣的應用中,須要分城市展現不一樣的頁面內容,咱們但願在網站域名後面緊跟一個城市目錄,也即這種格式:數據庫

http://www.domain.com/城市名/模塊名/方法名,根據不一樣的城市展現當地的信息內容cookie

這裏你們可能最容易想到也是最暴力的一個方法就是:爲每個城市創建一個單獨的分組,而後把相同的代碼copy N份......這顯然違背了軟件設計中代碼重用的原則,並且不夠靈活,因此咱們不提倡。app

那麼下面我要介紹的是利用Thinkphp的URL路由來實現這一功能:dom

若是你還不知道怎麼配置URL路由的話,建議你先暫停一下,戳下面的連接先了解一下:(只看規則路由部分就好了,先無視正則路由。。)函數

Thinkphp 3.1.3手冊-URL路由部分:http://doc.thinkphp.cn/manual/url_route.html網站

Thinkphp 3.1快速入門(6)路由:http://www.thinkphp.cn/info/118.htmlurl

我先去喝杯茶。。。。

好了歡迎回來,在使用URL路由以前,咱們不妨先考慮這樣一個問題:若是不考慮城市名在URL中的位置,怎麼實現一站多城市呢?很簡單,咱們能夠把城市名做爲get參數放置在URL方法名的後面,像這樣,http://www.domain.com/模塊名/方法名/city/hangzhou,有了這個get參數就好辦了,咱們能夠創建一個CommonAction控制器,其它控制器都繼承它,在CommonAction控制器的_initialize()方法中對$_GET['city']作一下判斷,能夠查詢一下數據庫,檢測是否存在這個城市,若是存在則顯示這個城市的內容,爲了防止沒必要要的重複查詢數據庫,你還能夠將城市名保存到cookie裏,這個就很少說了。

好了,下面咱們就好開始進行URL的乾坤大挪移了,咱們的目標是把URL中的模塊名和方法名日後移一個「位置」,騰出一個位置來放置城市名,像這樣:http://www.domain.com/hangzhou/模塊名/方法名

這裏咱們須要知道,URL中的分組、模塊、方法本質上都是get參數,分別爲g,m,a(TP3.2版本爲m,c,a),知道這個就好辦了,咱們在config文件中配置URL路由規則以下:

'URL_ROUTE_RULES'=> array(

':city^Home|Admin|Index|Public|User|detail/:m/:a' => 'Home',//city做爲get參數,注意這裏排除了分組名和控制器名(以及你下面的路由規則),若是一級目錄不是城市,即直接爲正常路由

//TP3.2版本爲':city^-Index-Public-User-detail/:m/:a' => 'Home',

'detail/:id\d$'    => 'team/detail',//其它路由規則

),

(補充:3.2.1版本的規則排除分隔符爲「-」,把上面代碼中的「|」修改成「-」就好了,同時注意把m改爲c,下同)

這裏的:city,:m,:a都是隱式傳入的GET參數,^Home|Admin|Index|Public|User|detail這串內容的做用是排除Home、Admin、Index、Public、User、detail這些關鍵字,他們都是分組名、模塊名或者咱們後面定義的路由規則的開頭字符串,這樣就兼容了正常的URL模式,若是一級目錄不是城市,即直接轉爲正常路由或匹配下面的路由項。

到此爲止,咱們的路由規則已經基本配置完成了,實現了「http://www.domain.com/城市名/模塊名/方法名」這種格式的路由匹配。

可是還有一些小問題,就是默認控制器和默認操做方法的問題,若是咱們訪問這個URL:「http://www.domain.com/城市名,咱們但願訪問的完整URL是:「http://www.domain.com/城市名/Index/index,一樣,若是咱們訪問這個URL:「http://www.domain.com/城市名/模塊名」,咱們但願訪問的完整URL是:「http://www.domain.com/城市名/模塊名/index」,爲了考慮這些狀況,咱們在原有路由規則之上再加兩條路由規則:

'URL_ROUTE_RULES'=> array(

':city^Home|Admin|Index|Public|User|detail$' => 'Home',

':city^Home|Admin|Index|Public|User|detail/:m$' => 'Home',

':city^Home|Admin|Index|Public|User|detail/:m/:a' => 'Home',//city做爲get參數,注意這裏排除了分組名和控制器名(以及你下面的路由規則),若是一級目錄不是城市,即直接爲正常路由

'detail/:id\d$'    => 'team/detail',//其它路由規則

),

這樣就解決了上述問題,固然目前還沒法支持「http://www.domain.com/城市名/分組名/模塊名/方法名」這樣的URL,相信實現原理相似,但會複雜不少。

以上就是一站多城市路由配置技巧。若是你有本身的域名,那麼實現一站多城市更fashion的方式莫過於爲每一個城市部署二級域名了,像這樣:http://hangzhou.domain.com/模塊名/方法名,下面扯一下怎麼爲每一個城市部署二級域名,基本原理實際上是同樣的,這裏要用到ThinkPHP二級域名部署,詳見手冊:http://doc.thinkphp.cn/manual/sub_domain_deploy.html

咱們在config文件裏部署二級域名:

'APP_SUB_DOMAIN_DEPLOY'=>1, // 開啓子域名配置

/*子域名配置

*格式如: '子域名'=>array('分組名/[模塊名]','var1=a&var2=b');

*/

'APP_SUB_DOMAIN_RULES'=>array(

'beijing'=>array('Home/','city=beijing'),  // city做爲一個get參數,指明城市,對應beijing.domain.com

'hangzhou'=>array('Home/','city=hangzhou'),  // city做爲一個get參數,指明城市,對應hangzhou.domain.com

),

就這麼簡單,並且二級域名部署和以前的URL路由是不衝突的,固然既然部署了二級域名就徹底不須要URL路由了。

好了就扯這麼多,感謝你閱讀完本教程,但願對你的項目有所幫助,有任何問題歡迎留言討論。

補充:若是你使用的ThinkPHP是3.2.1版本的而且字段排除出現了奇怪的錯誤,這是由於規則排除和函數功能使用的分隔符相同都爲「|」致使混淆,目前TP官方已經修復這一BUG,把排除分割符該爲了「-」,因此還請你趕忙更新你的TP版本。3.1.3版本無此問題。

相關文章
相關標籤/搜索