问题描述:
在apache的配置文件中开启了路由重写后,改写tp3.2框架项目中的.htaccess文件的重写规则如下:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([0-9]+)$ index.php?m=Show&a=index&roomnum=$1
</IfModule>
可以看到,上面的路由规则很简单,就是将匹配到所有路由为 “/27525”的路由都重写到show模块下面的index控制器中,参数为roomnum=27525。但在实际的运行中,却没有达到想要的结果。
查看了apache的错误日志,发现其实apache实际上是有命中上面的路有规则,但是后续缺又被一步步修改,重新定位到其他的地方了,这个让人一直百思不得其解。
但是,比较明确的一点是,既然apache已经命中了规则,那问题所在很可能是tp3.2项目的配置有问题
于是乎,抱着试一试的心态,本鸟就追踪到了tp框架下面的一个源文件下面,这个文件就是进行路由处理的文件,该文件是tp3.2目录下面的ThinkPHP/Library/Think/Dispatcher.class.php。
探索过程:
1、通过在Dispatcher.class.php中打断点调试发现,在这个文件中,程序最终会给
S
E
R
V
E
R
插
入
一
个
值
:
P
A
T
H
I
N
F
O
。
按
照
以
上
的
路
由
重
写
规
则
,
最
终
_SERVER插入一个值:PATH_INFO。按照以上的路由重写规则,最终
SERVER插入一个值:PATHINFO。按照以上的路由重写规则,最终_SERVER[‘PATH_INFO’]的值时 RewriteRule ^([0-9]+)$ index.php?m=Show&a=index&roomnum=$1规则中匹配到的数字,即$1中的值,这个是不匹配的
解决过程:
1、因为该项目一开始是在nginx的环境下开发的,所以在nginx中配置路由重写规则 :^([0-9]+)$ index.php?m=Show&a=index&roomnum=$1是没有问题的,于是本鸟就到Dispatcher.class.php中调试,发现在文件的开头处,会有一个参数,上图
在nginx的环境下,
S
E
R
V
E
R
[
′
P
A
T
H
I
N
F
O
′
]
的
值
已
经
变
成
了
路
由
命
中
的
值
,
即
/
S
h
o
w
/
i
n
d
e
x
/
r
o
o
m
n
u
m
/
27525
这
类
值
,
但
在
a
p
a
c
h
e
的
环
境
中
这
个
值
缺
为
空
,
因
为
_SERVER['PATH_INFO']的值已经变成了路由命中的值,即/Show/index/roomnum/27525这类值,但在apache的环境中这个值缺为空,因为
SERVER[′PATHINFO′]的值已经变成了路由命中的值,即/Show/index/roomnum/27525这类值,但在apache的环境中这个值缺为空,因为varPath的参数值为s,而看上图可以知道,要获取
G
E
T
[
′
s
′
]
的
值
,
_GET['s']的值,
GET[′s′]的值,_GET就必须要有这个变量,所以这个时候本鸟就去查看了
$varPath = C(‘VAR_PATHINFO’)到底是什么配置,搜索文件得知,如下图
细看上图中对于改配置项的解释,本鸟恍然大悟,我在.htcaccess文件中重写的规则与此处的模式下的路有规则有所区别,该文件下刚好有个s的值,于是,将路由规则改写成下面的值:
RewriteRule ^([0-9]+)$ index.php?s=/Show/index/roomnum/$1
果不其然,问题就在这里,路由重写成功,问题解决。
疑惑:
虽然问题解决,但仍有一惑,就是在apache的环境下,不知为何,按照一开始的路由规则来走的话,
G
E
T
中
不
会
有
s
变
量
,
但
在
n
g
i
n
x
中
的
重
写
规
则
中
使
用
下
面
的
规
则
却
有
s
变
量
,
两
者
的
重
写
规
则
虽
然
不
完
全
相
同
,
但
都
没
有
s
,
为
何
在
a
p
a
c
h
e
的
环
境
下
的
_GET中不会有s变量,但在nginx中的重写规则中使用下面的规则却有s变量,两者的重写规则虽然不完全相同,但都没有s,为何在apache的环境下的
GET中不会有s变量,但在nginx中的重写规则中使用下面的规则却有s变量,两者的重写规则虽然不完全相同,但都没有s,为何在apache的环境下的_GET中没有s变量,而在nginx的环境下中却有:
rewrite ^/([0-9]+)$ /Show/index/roomnum/$1/;