Nginx与Tengine环境下部署Thinkphp网站最完美的解决办法—完美解决方法全解析

Posted by

文武双全之前在Tengine下部署Thinkphp3.2.3的项目,按照thinkphp官方的thinkphp3.2.3文档里的方法完美部署。可是后来维护一个thinkphp3.1的项目,按照官方的部署文档死活在nginx下部署不了。thinkphp官方网站和度娘也查了很多资料,走了很多弯路都不行。在卡了我一周之后,终于完美解决了这个问题。Thinkphp3.1的项目,在Tengine环境下部署成功,该方法同样也适合高版本的Nginx环境。

Nginx与Tengine环境下部署Thinkphp网站最完美的解决办法

Nginx与Tengine环境下部署Thinkphp网站最完美的解决办法
Nginx与Tengine环境下部署Thinkphp网站最完美的解决办法

如图所示,就是文武双全在百度找到的解决这个问题的完美解决方案。由于作者已经写出了解决问题的方法,文武双全就不再累述了。只是把这段tengine的配置文件做个总结,就当是学习tengine和nginx的学习总结吧。另外要总结下PATH_INFO的问题,也就是说解决问题的原理。这个解决办法,有几下几个知识点需要着重记忆的:

第一个知识点:uri和url

uri是Universal Resource Identifier的首字母缩写,uri是统一资源标示符的意思,相当于网页资源的ID,可以唯一标识一个网页资源。

而url是Universal Resource Locator的首字母缩写,url是统一资源定位符的意思,可以提供找到该网页资源的路径。

说简单一点,URL本身定位了一个资源,所以URL本身就是URI。但是URI不一定是URL,所以URI包含了URL。

第二个知识点:tengine和nginx的try_files指令

try_files指令最核心的功能是替代nginx的rewrite功能,

语法: try_files file … uri 或 try_files file … = code

默认值: 无

作用域: server location

如上图所示的指令:try_files  $uri  $uri/ /index.php$uri。该指令会按照顺序检查$uri是否存在,如果存在的话会返回第一个找到的文件。结尾如果有斜线 $uri/,则表示为文件夹。如果所有的文件都找不到,会进行一个内部重定向到最后一个参数也就是/index.php$uri。

文武双全的说明:thinkphp里所有的静态资源,按照该语法都可以找到对应的文件。而php文件,由于使用了路由,都会被try_files指令重定向到/index.php$uri。由于该URI被加了/index.php的路径,于是又会被下面.+\.php($|/)的正则匹配到。

该指令可以说完美解决了thinkphp网站,静态资源使用正常URL访问而php脚本文件通过tengine反代交给thinkphp框架解析的问题。

第三个知识点:location的正则.+\.php($|/)详解

该正则表达式意思为:匹配任意uri当中包含.php或者以.php结尾的脚本。

其中:.+表示任意字符重复1次以上。.php($|/)表示 .php或者.php/,也就是说以.php结尾或者URI当中包含了.php/的脚本文件。

第四个知识点:PATH_INFO和phpinfo()函数

上图所示的配置文件当中提到了PATH_INFO,看名字就知道了它的意思了,用来表示脚本的路径信息。PATH_INFO是一个CGI 1.1的标准,PHP当中用$_SERVER[‘PATH_INFO’]这个全局变量获取文件的路径信息。众多PHP的框架,都会用到它来美化网站的URL。举例说明:

http://www.test.com/index.php/foo/bar.html?c=index&m=search

我们可以得到 $_SERVER[‘PATH_INFO’] = ‘/foo/bar.html’,而此时 $_SERVER[‘QUERY_STRING’] = ‘c=index&m=search’;

而phpinfo()这是php的一个函数,并不是nginx的功能,它会以数组的形式返回脚本文件的路径信息。

nginx默认是不会设置PATH_INFO环境变量的值,需要在php的配置文件中使用cgi.fix_pathinfo=1来完成路径信息的获取,但这样做同时会带来安全隐患,需要把cgi.fix_pathinfo=0设置为0,这样php又获取不到PATH_INFO信息,那些依赖PATH_INFO进行URL美化的php框架就失效了。

新版本的nginx这可以使用fastcgi_split_path_info指令来设置PATH_INFO,旧的方式比如使用if来判断,不再推荐使用。

第五个知识点:nginx的fastcgi_split_path_info指令

该指令从URI当中分割出PATH_INFO;

第六个知识点:fastcgi_param  PATH_INFO $fastcgi_path_info

这一行代码设置了一个PATH_INFO的参数,变量名为$fastcgi_path_info;

配置文件的最后一行,include  fastcgi.conf。加载了默认的fastcig.conf文件,将从URI当中分割出来的PATH_INFO并且设定为PATH_INFO的参数$fastcgi_path_info,传递给后台的php-fpm来处理了。实际上也就是交给了php的框架,按照框架自定义的路由来解析了。

One comment

Leave a Reply

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据