使用过ThinkPHP框架开发过应用的同学应该都知道它有一个URL模式叫做pathinfo,看起来类似于下面的URL:http://example.com/module/controller/action/key1/value1/key2/value2.html其实上面这个URL的原型是这样的://这个才是正宗的URL,上面那个是假冒的http://example.com/index.php?m=module&c=controller&a=action&key1=value1&key2=value2既然pathinfo方式的url不真实,为什么不用真实的呢?用正品不好吗?相对于真实的URL,pathinfo模式确实有优势。以下是它的一些好处。它提供了最好的SEO支持,并且可以实现伪静态URL。它看起来更简洁更好。pathinfo模式的URL有这么多优点,所以我们必须支持它们。ThinkPHP更多的URL模式配置和实现可以参考这篇文档。本文主要讨论Nginx中pathinfo方式URL的实现,ThinkPHP官方文档中没有介绍,但是实现起来还是比较简单的。以下是关于实施过程的一些想法。标准的通用URL格式是这样的:://:@:/;?#指的是常见的URL格式,可以发现pathinfo模式和标准模式URL有两大不同,一是没有index.php文件,二是查询参数没有使用符号“?“分开了。我们现在要做的是在Nginx收到时,将向Nginx的pathinfo方式的URL请求恢复为标准的URL方式,让服务器正常处理。要补上缺失的index.php文件,需要使用Nginx的rewrite命令,该命令用于将请求的URI替换为目标URL。这里要实现的效果是将http://example.com/module/controller/action/key1/value1/key2/value2.html替换为http://example.com/index.php/module/controller/action/key1/value1/key2/value2.html当然并不是所有的URI都会被这个规则改写,只有那些不是文件的URI才会被改写。因此,重写指令将类似如下:#如果请求的文件不存在,则进行URI重写#添加入口文件index.phpif(!-e$request_filename){rewrite^/(.*)$/index.php/$1last;}通过上面的配置,可以达到完成index.php入口文件的效果。变音符号?前后内容在一个普通的URL中,符号“?”有一个特殊的作用,它用于将查询字符串与之前的文件分开。在pathinfo方式的URL中,符号“?”没有了,也就是说服务器无法区分哪些URI是文件,哪些是查询字符串。因此,我们的目的是手动区分应该用符号“?”区分的内容。在路径信息模式下。好在Nginx中有一条指令可以达到我们的目的,fastcgi_split_path_info。它可以将正则表达式定义的两个字符串赋值给变量$fastcgi_script_name和变量$fastcgi_path_info,以备后用。fastcgi_split_path_info的更多信息请参考类似如下代码的相关配置:location~^(.+\.php)(.*)${root/var/www/html/$vhost_path;fastcgi_passphpfpm:9000;fastcgi_split_path_info^(.+\.php)(.*)$;fastcgi_paramSCRIPT_FILENAME$document_root$fastcgi_script_name;fastcgi_paramPATH_INFO$fastcgi_path_info;includefastcgi_params;}一个简单的例子通过以上两部分的配置,目前的Nginx服务器已经支持pathinfo方式的URL,下面是一个简单的服务器配置,仅供参考:server{listen80;服务器名称tp5.loc;设置$vhost_pathtp5/public;位置/{root/usr/share/nginx/html/$vhost_path;indexindex.phpindex.htmlindex.htm;if(!-e$request_filename){最后重写^/(.*)$/index.php/$1;}}location~^(.+\.php)(.*)${root/var/www/html/$vhost_path;fastcgi_passphpfpm:9000;fastcgi_split_path_info^(.+\.php)(.*)$;fastcgi_paramSCRIPT_FILENAME$document_root$fastcgi_script_name;fastcgi_paramPATH_INFO$fastcgi_path_info;包括fastcgi_params;}}