文档章节

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

喵王不瞌睡
 喵王不瞌睡
发布于 2015/03/06 20:10
字数 1595
阅读 2587
收藏 15

ThinkPHP在PATHINFO的URL模式下,URL的格式类似于http://www.domain.com/appName/module/action

即:http://www.domain.com/分组名/模块名/方法名

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

然而在有些类似于58同城这样的应用中,需要分城市展示不同的页面内容,我们希望在网站域名后面紧跟一个城市目录,也即这种格式:

http://www.domain.com/城市名/模块名/方法名,根据不同的城市展示当地的信息内容

这里大家可能最容易想到也是最暴力的一个方法就是:为每一个城市建立一个单独的分组,然后把相同的代码copy N份......这显然违背了软件设计中代码重用的原则,而且不够灵活,所以我们不提倡。

那么下面我要介绍的是利用Thinkphp的URL路由来实现这一功能:

如果你还不知道怎么配置URL路由的话,建议你先暂停一下,戳下面的链接先了解一下:(只看规则路由部分就行了,先无视正则路由。。)

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

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

我先去喝杯茶。。。。

好了欢迎回来,在使用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版本无此问题。


本文转载自:http://peimin.sinaapp.com/?p=168

喵王不瞌睡
粉丝 11
博文 168
码字总数 51103
作品 0
浦东
个人站长
私信 提问
加载中

评论(2)

stefanliao
stefanliao
‘APP_SUB_DOMAIN_RULES’ = array('*' => array('Home/','city=*') ),然后我浏览器随便一个城市访问如gz.test.com还是刷不出来,初学请指教。已经开启了子域名部署。(ps:连接上一条回复,不小心回车了)
stefanliao
stefanliao
我在本机模拟泛域名部署,127.0.0.1改映射www.test.com。使用tp3.2.3,配置了应用配置文件如
ThinkPHP中的三大自动简介

ThinkPHP中的三大自动简介 文章TAG:thinkphp 自动简介 过期已备案域名,注册就能用!终身VIP会员,畅享源码下载织梦精美仿站,火热预定中! 本文较为详细的讲述了ThinkPHP中的三大自动,是非...

thinkyoung
2015/10/10
0
0
新手指导Thinkphp开发指南

小编于昨日参加朋友婚礼,浑身喜气洋洋。今天给用户带来的是关于thinkphp开发指南的纯技术性的文档,本文档目的很简单: 1、 帮助开发人员掌握thinkphp入门 2、 快速利用thinkphp进行项目开发...

汤圆
2012/12/25
304
1
php thinkPHP 模版映射问题【求助】

./Lib/IndexAction.class.php class IndexAction extends Action { //默认执行此处 public function index() { //:)欢迎使用 ThinkPHP! $this->show ( ' :) 欢迎使用 ThinkPHP!', 'utf-8' ......

liu_kelin
2013/04/07
468
2
thinkphp多域名(子域名)支持配置解决方案

网站优化中我们需要把www.51php.com和51php.com 都指向同一个IP地址,并且需要定位到ThinkPHP的某个项目App中的不同模块,我们怎么实现类?在thinkphp中,我们可以通过 thinkphp入口文件的配...

汤圆
2012/12/27
2.3K
0
ThinkPHP 3.2 正式版发布

模块化 驱动化 为云平台而生 ThinkPHP3.2正式版发布! ThinkPHP是国内领先的WEB应用开发框架,诞生于2006年初,在国内具有良好的口碑和广大的用户群,秉承了大道至简的开发理念,让WEB开发变...

流年
2013/12/19
11
0

没有更多内容

加载失败,请刷新页面

加载更多

【JVM学习】2.Java虚拟机运行时数据区

来源: 公众号: 猿人谷 这里我们先说句题外话,相信大家在面试中经常被问到介绍Java内存模型,我在面试别人时也会经常问这个问题。但是,往往都会令我比较尴尬,我还话音未落,面试者就会“...

物种起源-达尔文
24分钟前
2
0
dart datetime

var date = DateTime.now().toUtc(); //格式化输出 String timestamp = "${date.year.toString()}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, ......

zdglf
今天
20
0
如何在Linux中复制文档

在办公室里复印文档过去需要专门的员工与机器。如今,复制是电脑用户无需多加思考的任务。在电脑里复制数据是如此微不足道的事,以致于你还没有意识到复制就发生了,例如当拖动文档到外部硬盘...

老孟的Linux私房菜
今天
47
0
SpringBoot 集成MongoDB

一、MongoDB 简介 MongoDB 如今是最流行的 NoSQL 数据库,被广泛应用于各行各业中,很多创业公司数据库选型就直接使用了 MongoDB,但对于大部分公司,使用 MongoDB 的场景是做大规模数据查询...

zw965
今天
49
0
使用 Envoy 和 AdGuard Home 阻挡烦人的广告

> 原文链接:使用 Envoy 和 AdGuard Home 阻挡烦人的广告 通常我们使用网络时,宽带运营商会为我们分配一个 DNS 服务器。这个 DNS 通常是最快的,距离最近的服务器,但会有很多问题,比如: ...

米开朗基杨
今天
54
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部