Nginx 下禅道的伪静态 rewrite 规则
搭建了一个禅道的项目管理平台,但是 Nginx 下并不是伪静态的,URL 看着不是很舒服,上网搜索配置规则,但是没有一个可以正常使用的,于是乎自己琢磨一下。
先给出最终配置,有兴趣看原因的可以往下看
server { listen 80; root /zentao/root/path/www; index index.php index.html index.htm; server_name domain_name; location / { try_files $uri /index.php$uri; } location ~ \.php(/.+)?$ { fastcgi_pass unix:/var/run/php-fpm.sock; fastcgi_index index.php; include fastcgi.conf; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_param PATH_INFO $fastcgi_path_info; } access_log off; }
禅道给出了 apache 的伪静态规则,但是我尝试了半天也没有转换成可用的 nginx 伪静态规则,但是禅道是基于 PHP 的,而 PHP 伪静态一般基于 $_SERVER
变量中的一些变量来实现的,既然 apache 可以实现伪静态,那么就打印一下伪静态后的 $_SERVER
变量的值。
修改禅道根目录下 www/index.php
文件,在最上面修改为如下代码:
<?php
echo "<pre>";
print_r($_SERVER);
echo "</pre>";
die;
然后访问 http://domain/user-login-Lw==.html 此为禅道登陆 url
// 仅给出几个重要的变量
Array
(
[REDIRECT_URL] => /user-login-Lw==.html
[REQUEST_URI] => /user-login-Lw==.html
[SCRIPT_NAME] => /index.php
[PATH_INFO] => /user-login-Lw==.html
[PATH_TRANSLATED] => redirect:/index.php/user-login-Lw==.html
[PHP_SELF] => /index.php/user-login-Lw==.html
)
对于未配置过的 nginx 做相同的操作:
未配置的 nginx 并不是什么都没配置,基本的还是要配置的
location / {
try_files $uri /index.php;
}
location ~ \.php$ {
# With php5-fpm:
fastcgi_pass unix:/var/run/php-fpm.sock;
fastcgi_index index.php;
include fastcgi.conf;
}
如上,这两个 location 还是要有的,一个是将所有的请求重定向到 index.php
,一个是解析 php 文件的.
这次,php 返回的信息为
// 仅给出几个重要的变量
Array
(
[SCRIPT_NAME] => /index.php
[REQUEST_URI] => /user-login-Lw==.html
[DOCUMENT_URI] => /index.php
[PHP_SELF] => /index.php
)
对比一下,发现不同了吧。nginx 少了 PATH_INFO
,而且 PHP_SELF
也是不一样的,至于 REDIRECT_URL
和 PATH_TRANSLATED
这些变量都是 apache 自己加的,禅道并不会用到。
回想一下禅道的配置文件 config/config.php
和 config/my.php
中有一项 $config->requestType
配置,如果配置为 GET
的话,就会禁用伪静态,而通过 query string 的方式,如果配置成 PATH_INFO
的话就需要 nginx 或 apache 配置伪静态规则,也就是说禅道通过解析 PATH_INFO 来实现伪静态的。
那么 PATH_INFO 又是什么东东,根据 PHP 官方文档 的解释,如果我访问 http://www.example.com/php/path_info.php/some/stuff?foo=bar 这个 url,那个 PATH_INFO 就应该等于 /some/stuff
,也就是所 PATH_INFO
等于 url 中跟在真实脚本名称之后并且在查询语句(query string)之前的字符串,你可能会说,我访问的 url 中根本没有 filename.php 啊,那是因为 nginx 帮你添加了,记得配置中的 try_files $uri /index.php$uri
吧,这个内部跳转就是干这个事情的。
找到了原因就开始解决,Nginx 和 PHP 是通过 cgi 协议传递数据的,可以通过 nginx 开启 debug ( http://nginx.org/en/docs/debugging_log.html ) 来查看传递 nginx 和 php 交换的数据。
这里不给出详细 debug log 了,反正开启 log 后发现 nginx 并没有传递 PATH_INFO 给 php,于是在解析 php 的 location 中添加一行
location ~ \.php$ {
fastcgi_pass unix:/var/run/php-fpm.sock;
fastcgi_index index.php;
include fastcgi.conf;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
但只有这个还是不行,因为此时 nginx 内部变量 $uri
(就相当于 PHP_SELF 的值) 还是*/index.php*,需要再修改一个地方
location / {
try_files $uri /index.php;
}
修改之后 php 那个 location 就没办法被识别了,需要修改为 \.php(/.+)?$
最终的效果就是
server { listen 80; root /zentao/root/path/www; index index.php index.html index.htm; server_name domain_name; location / { try_files $uri /index.php$uri; } location ~ \.php(/.+)?$ { fastcgi_pass unix:/var/run/php-fpm.sock; fastcgi_index index.php; include fastcgi.conf; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_param PATH_INFO $fastcgi_path_info; } access_log off; }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

上一篇: PHP 中的 DateTime 类
下一篇: 彻底找到 Tomcat 启动速度慢的元凶
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论