配置Nginx+PHP的正确思路与过程


Posted in PHP onMay 10, 2016

对很多人而言,配置Nginx+PHP无外乎就是搜索一篇教程,然后拷贝粘贴。听上去似乎也没什么问题,可惜实际上网络上很多资料本身年久失修,漏洞百出,如果大家不求甚解,一味的拷贝粘贴,早晚有一天会为此付出代价。

如何正确配置 Nginx+PHP

假设我们用PHP实现了一个前端控制器,或者直白点说就是统一入口:把PHP请求都发送到同一个文件上,然后在此文件里通过解析「REQUEST_URI」实现路由。

一般这样配置

此时很多教程会教大家这样配置Nginx+PHP:

server {
  listen 80;
  server_name foo.com;

  root /path;

  location / {
    index index.html index.htm index.php;

    if (!-e $request_filename) {
      rewrite . /index.php last;
    }
  }

  location ~ /.php$ {
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME /path$fastcgi_script_name;
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_index index.php;
  }
}

这里面有很多错误,或者说至少是坏味道的地方,大家看看能发现几个。

我们有必要先了解一下Nginx配置文件里指令的继承关系:

Nginx配置文件分为好多块,常见的从外到内依次是「http」、「server」、「location」等等,缺省的继承关系是从外到内,也就是说内层块会自动获取外层块的值作为缺省值。

让我们先从「index」指令入手吧

在问题配置中它是在「location」中定义的:

location / {
  index index.html index.htm index.php;
}

一旦未来需要加入新的「location」,必然会出现重复定义的「index」指令,这是因为多个「location」是平级的关系,不存在继承,此时应该在「server」里定义「index」,借助继承关系,「index」指令在所有的「location」中都能生效。

接下来看看「if」指令

说它是大家误解最深的Nginx指令毫不为过:

if (!-e $request_filename) {
  rewrite . /index.php last;
}

很多人喜欢用「if」指令做一系列的检查,不过这实际上是「try_files」指令的职责:

try_files $uri $uri/ /index.php;
除此以外,初学者往往会认为「if」指令是内核级的指令,但是实际上它是rewrite模块的一部分,加上Nginx配置实际上是声明式的,而非过程式的,所以当其和非rewrite模块的指令混用时,结果可能会非你所愿。

下面看看「fastcgi_params」配置文件

include fastcgi_params;
Nginx有两份fastcgi配置文件,分别是「fastcgi_params」和「fastcgi.conf」,它们没有太大的差异,唯一的区别是后者比前者多了一行「SCRIPT_FILENAME」的定义:

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
注意:$document_root 和 $fastcgi_script_name 之间没有 /。

原本Nginx只有「fastcgi_params」,后来发现很多人在定义「SCRIPT_FILENAME」时使用了硬编码的方式,于是为了规范用法便引入了「fastcgi.conf」。

不过这样的话就产生一个疑问:为什么一定要引入一个新的配置文件,而不是修改旧的配置文件?这是因为「fastcgi_param」指令是数组型的,和普通指令相同的是:内层替换外层;和普通指令不同的是:当在同级多次使用的时候,是新增而不是替换。换句话说,如果在同级定义两次「SCRIPT_FILENAME」,那么它们都会被发送到后端,这可能会导致一些潜在的问题,为了避免此类情况,便引入了一个新的配置文件。

此外,我们还需要考虑一个安全问题:在PHP开启「cgi.fix_pathinfo」的情况下,PHP可能会把错误的文件类型当作PHP文件来解析。如果Nginx和PHP安装在同一台服务器上的话,那么最简单的解决方法是用「try_files」指令做一次过滤:

try_files $uri =404;

改良后的版本

依照前面的分析,给出一份改良后的版本,是不是比开始的版本清爽了很多:

server {
  listen 80;
  server_name foo.com;

  root /path;
  index index.html index.htm index.php;

  location / {
    try_files $uri $uri/ /index.php$is_args$args;
  }

  location ~ /.php$ {
    try_files $uri =404;

    include fastcgi.conf;
    fastcgi_pass 127.0.0.1:9000;
  }
}

如何正确配置 Nginx + PHP,相信大家应该有了自己的认识了吧!

PHP 相关文章推荐
隐藏X-Space个人空间下方版权方法隐藏X-Space个人空间标题隐藏X-Space个人空间管理版权方法
Feb 22 PHP
判断PHP数组是否为空的代码
Sep 08 PHP
php的大小写敏感问题整理
Dec 29 PHP
Apache实现Web Server负载均衡详解(不考虑Session版)
Jul 05 PHP
开源php中文分词系统SCWS安装和使用实例
Apr 11 PHP
php获取网页中图片、DIV内容的简单方法
Jun 19 PHP
ThinkPHP3.1新特性之内容解析输出详解
Jun 19 PHP
php实现比较两个文件夹异同的方法
Jun 18 PHP
PHP通过反射动态加载第三方类和获得类源码的实例
Nov 27 PHP
yii2高级应用之自定义组件实现全局使用图片上传功能的方法
Oct 08 PHP
Laravel 集成微信用户登录和绑定的实现
Dec 27 PHP
laravel框架路由分组,中间件,命名空间,子域名,路由前缀实例分析
Feb 18 PHP
WordPress中设置Post Type自定义文章类型的实例教程
May 10 #PHP
php+MySQL实现登录时验证登录名和密码是否正确
May 10 #PHP
PHP7+Nginx的配置与安装教程详解
May 10 #PHP
php+mysql实现的二级联动菜单效果详解
May 10 #PHP
浅析Yii2缓存的使用
May 10 #PHP
php简单统计在线人数的方法
May 10 #PHP
使用php实现从身份证中提取生日
May 09 #PHP
You might like
php下检测字符串是否是utf8编码的代码
2008/06/28 PHP
php 生成饼图 三维饼图
2009/09/28 PHP
php开发留言板的CRUD(增,删,改,查)操作
2012/04/19 PHP
ThinkPHP CURD方法之data方法详解
2014/06/18 PHP
YII Framework框架教程之国际化实现方法
2016/03/14 PHP
PHP实现文件上传下载实例
2016/10/18 PHP
PHP Ajax跨域问题解决方案代码实例
2020/08/01 PHP
异步javascript的原理和实现技巧介绍
2012/11/08 Javascript
JS.getTextContent(element,preformatted)使用介绍
2013/09/21 Javascript
特殊情况下如何获取span里面的值
2014/05/20 Javascript
JS实现简单的键盘打字的效果
2015/04/24 Javascript
js支持键盘控制的左右切换立体式图片轮播效果代码分享
2015/08/26 Javascript
jQuery实现磁力图片跟随效果完整示例
2016/09/16 Javascript
jquery实现的回旋滚动效果完整实例【附demo源码下载】
2016/09/20 Javascript
基于Angularjs+mybatis实现二级评论系统(仿简书)
2017/02/13 Javascript
jQuery图片切换动画效果
2017/02/28 Javascript
Javascript 实现匿名递归的实例代码
2017/05/25 Javascript
webpack打包多页面的方法
2018/11/30 Javascript
python+pandas生成指定日期和重采样的方法
2018/04/11 Python
tensorflow更改变量的值实例
2018/07/30 Python
python处理大日志文件
2019/07/23 Python
利用python-docx模块写批量生日邀请函
2019/08/26 Python
Django添加bootstrap框架时无法加载静态文件的解决方式
2020/03/27 Python
使用ITK-SNAP进行抠图操作并保存mask的实例
2020/07/01 Python
PyCharm vs VSCode,作为python开发者,你更倾向哪种IDE呢?
2020/08/17 Python
Python Selenium实现无可视化界面过程解析
2020/08/25 Python
泰国办公用品购物网站:OfficeMate
2018/02/04 全球购物
ECHT官方网站:男女健身服
2020/02/14 全球购物
和平主题的演讲稿
2014/01/12 职场文书
优秀少先队员主要事迹材料
2014/05/28 职场文书
党的群众路线教育实践活动党员个人整改措施
2014/10/27 职场文书
2015年公路养护工作总结
2015/05/13 职场文书
党小组鉴定意见
2015/06/02 职场文书
售房协议书范本
2015/08/11 职场文书
初中班主任培训心得体会
2016/01/07 职场文书
Nginx本地目录映射实现代码实例
2021/03/31 Servers