ThinkPHP是知名的国产PHP框架,Nginx也是常见的Web服务器了。最近在调试ThinkPHP的URL Rewrite的时候遇到了一些麻烦,ThinkPHP默认使用PATH_INFO
作为URL Rewrite的参数。Nginx的配置里默认不带PATH_INFO
,虽然官方给出了解决方案,但实际效果并不好。
以下是包括常见的配置,这个配置可以完美支持CodeIgniter的URL Rewrite(基于REQUEST_URI
)。
location / { try_files $uri $uri/ /index.php; } location ~ .*\.php?$ { try_files $uri =404; fastcgi_pass unix:/tmp/php-cgi.sock; fastcgi_index index.php; include fastcgi_params; }
但是这个配置并不能很好地支持ThinkPHP,我尝试在ThinkPHP论坛、Nginx论坛找一些解决方法,总结出了以下解决办法:
方案一:按Nginx官方提供的解决办法,使用fastcgi_split_path_info
传递PATH_INFO
参数(但是我没有测试成功)。
方案二:按ThinkPHP官方提供的做法,修改Nginx Rewrite规则。
location / { if (!-e $request_filename) { rewrite ^(.*)$ /index.php?s=$1 last; } }
但是我的项目有几个特殊的需求:
- 尽量少改动Nginx的配置,使我的几个站点在设置Nginx配置的时候不至于让我昏头转向
- Nginx 提示,if is evil ,能不用尽量不用
/?s=
参数在WordPress等系统里普遍作为搜索、查询的参数名,而s
参数被ThinkPHP默认用作传入PATH_INFO
经过一番尝试以后我找到了解决办法。
首先,Nginx 使用上面的常见方法,即不需要作任何修改。
然后,配置ThinkPHP的项目目录下面的 /Conf/config.php,加入
// 使用 URL_Rewrite 模式 'URL_MODEL' => 2, // 使用自定义的 get_path_info 函数来获取请求路径 'URL_PATHINFO_FETCH' => ':get_path_info', // 让系统使用 /?pathinfo=... 替换默认的 /?s= 'VAR_PATHINFO' => 'pathinfo',
接着修改项目目录 /Common/common.php,加入
function get_path_info(){ $path = explode('?', $_SERVER['REQUEST_URI'], 2); return $path[0]; }