您的位置:晶晶的博客>Linux>nginx下基于ThinkPHP框架的网站url重写

nginx下基于ThinkPHP框架的网站url重写

ThinkPHP在nginx下的各种rewrite伪静态看起来是很麻烦的,但了解透彻了nginx的url重写机理以及ThinkPHP的各种url模式,那么在nginx下为基于ThinkPHP的应用做特定的url重写就很容易了,本文是博主基于ThinkPHP开发的各种web应用以及为这些引用在nginx做各种url适配重写的多次实践中总结而来。

======

ThinkPHP是什么就不再多啰嗦了,ThinkPHP网址:http://www.thinkphp.cn/

ThinkPHP框架基于M-V-C思想,模块化的设计并采用了单一入口模式(单一入口但并不是只能有一个入口),这样为nginx下的url重写免去了不少麻烦。

nginx下的基于ThinkPHP的应用的url重写,需了解ThinkPHP的各种url格式参数的处理逻辑以及nginx重写的原理。简单点说,无论哪种url格式,nginx都需要执行ThinkPHP下的应用单一入口文件,然后将各种url格式按照一定的格式规则进行进行参数化处理,最终执行指定模块与控制器;这个过程用户是看不到的,用户只能看到各种规则的url,这些url的规则如下:

# 通get
htt://blog.jjonline.cn/index.php?m=Info&a=usrInfo

# pathinfo
htt://blog.jjonline.cn/index.php/Info/usrInfo
#有get
htt://blog.jjonline.cn/index.php/Info/usrInfo/Id/1

# 通get ThinkPHP
htt://blog.jjonline.cn/index.php?s=Info/usrInfo
#有get
htt://blog.jjonline.cn/index.php?s=Info/usrInfo/Id/1

/*
#当然这三种模式还可以附带文件后缀
#其实合并起来也就3种
#附带后缀只是上述三种规则的细微变化
#TinkPHP框架核心代码获取到以上三种模式的参数后
#会进行特定的处理 带不带后缀 带哪种后缀 均可配置
#也就是如下几种规则
*/

#
htt://blog.jjonline.cn/index.php/Info/usrInfo.html
#
htt://blog.jjonline.cn/index.php?s=Info/usrInfo.html

======

什么是pathinfo?pathinfo是php的功能,nginx并没有pathinfo功能,在php中书写如下代码:

<?php

print_r(pathinfo('http://blog.jjonline.cn/test/index.txt'));

?>

结果:

Array
(
[dirname] => http://blog.jjonline.cn/test
[basename] => index.txt
[extension] => txt
[filename] => index
)

通过以上运行结果,可以看到打印出来的数组key字段已经很明显的标示出其意义来了。

ThinkPHP就采用了这种思想,将单一入口的url传参格式化,典型的基于ThinKPHP的url示例如下:

http://blog.jjonline.cn/index.php/Usr/UsrInfo

简单点理解,上述格式化的url形式就是ThinkPHP需要支持的pathinfo路径模式。对这个种格式化的url进行稍微解释,访问这个么一个地址,对基于ThinkPHP框架的网站来说,实际需要执行的就是网站根目录下的index.php文件,而该url中后面的/Usr/UsrInfo则被作为mvc思路中的功能模块参数与控制器参数,转换为普通get方式传参则上述url就要变为:

http://blog.jjonline.cn/index.php?m=Usr&a=UsrInfo

当然,get参数的变量该例子中一个是m一个是a,这个变量名在ThinkPHP中是可以改变的,这就需要依据具体的基于ThinkPHP的应用的模块规划与喜好了。

有了这种思路,nginx的url重写就有了最原始的写法了,对于上述pathinfo的格式化url,nginx在不做url重写时会把它当做一个路径来执行,一般来说没有谁会吃多了撑得在网站根目录下建立一个名字叫index.php的目录(注意:是目录,不是一般意义上的文件),所以第一种url重写出现了:

#是nginx 写url
location / {
root /var/www;
index index.html index.htm index.php;
if (!-d $request_filename) {
rewrite ^/(.*)/(.*)/*$ /index.php?m=$1&a=$2 last;
break;
}
}

但问题出现了,基于ThinkPHP的应用不仅仅只有上述例子中的这种pathinfo模式,现在变成这样的了:(为了便于解说,称如下代码段为“url示例”,后方提到“url示例”就是指此处的三种url格式)

#藏index.php 但url.html
http://blog.jjonline.cn/index.php/Usr/UsrInfo.html

#件index.php
http://blog.jjonline.cn/Usr/UsrInfo

http://blog.jjonline.cn/Usr/UsrInfo/

#访掉index.php.html
http://blog.jjonline.cn/Usr/UsrInfo.html

再了解下ThinkPHP中处理url的各种逻辑,ThinkPHP对传参进行了多种判定与处理,除了get方式传递不同的get变量作为mvc中的控制变量外,还有一个“兼容模式”的传参规则,也就是如下:

#ThinkPHP
http://blog.jjonline.cn/index.php?s=/Usr/UsrInfo

这种传参形式依然是get方式传参,但省略了多个get参数。ThinkPHP框架会对获取到的get变量$_GET['s']进行处理,从其中提取出mvc所需要的各个控制变量。

所以又一种nginx的url重写出现了:

location / {
root /var/www;
index index.html index.htm index.php;
if (!-e $request_filename) {
rewrite ^(.*)$ /index.php?s=$1 last;
break;
}
}

那么,现在需要同时兼容上述url示例中的三种格式又出问题了。最后解决方法如下:

location / {
root /var/www;
index index.html index.htm index.php;
if (!-e $request_filename) {
rewrite ^/index.php(.*)$ /index.php?s=$1 last;
rewrite ^(.*)$ /index.php?s=$1 last;
break;
}
}

当然,还有别的解决方法,专门针对pathinfo格式化路径的,就不再啰嗦,提供一篇文章:http://www.ifunsion.com/archives/2491

=======

以上url重写均只做示例,不建议直接照搬,理解了nginx的url重写以及ThinkPHP的路由模式的原理后,按照自己的基于ThinkPHP的应用业务逻辑书写url重写代码才是王道。

转载请注明本文标题和链接:《nginx下基于ThinkPHP框架的网站url重写

相关推荐

网友评论抢沙发

路人甲 表情
Ctrl+Enter快速提交