如何正确配置Nginx + PHP


Posted in PHP onJuly 15, 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;
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
Smarty的配置与高级缓存技术分享
Jun 05 PHP
php 对输入信息的进行安全过滤的函数代码
Jun 29 PHP
用php来改写404错误页让你的页面更友好
Jan 24 PHP
解析php中call_user_func_array的作用
Jun 07 PHP
php结合ajax实现赞、顶、踩功能实例
May 12 PHP
php实现的css文件背景图片下载器代码
Nov 11 PHP
ThinkPHP提示错误Fatal error: Allowed memory size的解决方法
Feb 12 PHP
学习php设计模式 php实现装饰器模式(decorator)
Dec 07 PHP
php连接oracle数据库的核心步骤
May 26 PHP
Thinkphp3.2简单解决多文件上传只上传一张的问题
Sep 26 PHP
php 删除一维数组中某一个值元素的操作方法
Feb 01 PHP
laravel框架中间件简单使用方法示例
Jan 25 PHP
Yii净化器CHtmlPurifier用法示例(过滤不良代码)
Jul 15 #PHP
Yii列表定义与使用分页方法小结(3种方法)
Jul 15 #PHP
session 加入redis的实现代码
Jul 15 #PHP
Yii模型操作之criteria查找数据库的方法
Jul 15 #PHP
功能强大的PHP POST提交数据类
Jul 15 #PHP
Yii的Srbac插件用法详解
Jul 14 #PHP
Yii中srbac权限扩展模块工作原理与用法分析
Jul 14 #PHP
You might like
PHP 冒泡排序 二分查找 顺序查找 二维数组排序算法函数的详解
2013/06/25 PHP
ThinkPHP中Session用法详解
2014/11/29 PHP
PHP连接SQLServer2005的方法
2015/01/27 PHP
In Javascript Class, how to call the prototype method.(three method)
2007/01/09 Javascript
nodejs中exports与module.exports的区别详细介绍
2013/01/14 NodeJs
jquery用offset()方法获得元素的xy坐标
2014/09/06 Javascript
jQuery实现拖拽效果插件的方法
2015/03/23 Javascript
javascript等号运算符使用详解
2015/04/16 Javascript
JS不用正则验证输入的字符串是否为空(包含空格)的实现代码
2016/06/14 Javascript
Vue 2.x教程之基础API
2017/03/06 Javascript
JS对象与json字符串相互转换实现方法示例
2018/06/14 Javascript
JS如何获取地址栏的参数实例讲解
2018/10/06 Javascript
python生成随机验证码(中文验证码)示例
2014/04/03 Python
python实现将html表格转换成CSV文件的方法
2015/06/28 Python
python unittest实现api自动化测试
2018/04/04 Python
python无限生成不重复(字母,数字,字符)组合的方法
2018/12/04 Python
python存储16bit和32bit图像的实例
2018/12/05 Python
Python使用while循环花式打印乘法表
2019/01/28 Python
python实现在函数图像上添加文字和标注的方法
2019/07/08 Python
python监控nginx端口和进程状态
2019/09/06 Python
Python中无限循环需要什么条件
2020/05/27 Python
浅谈pandas dataframe对除数是零的处理
2020/07/20 Python
matplotlib自定义鼠标光标坐标格式的实现
2021/01/08 Python
一款利用html5和css3实现的3D立方体旋转效果教程
2016/04/26 HTML / CSS
css3动画鼠标放上图片逐渐变大鼠标离开图片逐渐缩小效果
2021/01/27 HTML / CSS
欧洲领先的火车票和大巴票预订平台:Trainline
2018/12/26 全球购物
Perfume’s Club德国官网:在线购买香水
2019/04/08 全球购物
铭宣海淘转运:美国、日本、英国转运等全球转运公司
2019/09/10 全球购物
应届生人事助理求职信
2013/11/09 职场文书
护理学中专毕业生求职信
2013/11/11 职场文书
大二法英学生职业生涯规划范文
2014/02/27 职场文书
2014年学校工会工作总结
2014/12/06 职场文书
违纪学生保证书
2015/02/27 职场文书
《跨越海峡的生命桥》教学反思
2016/02/18 职场文书
python中的class_static的@classmethod的巧妙用法
2021/06/22 Python
Python内置数据结构列表与元组示例详解
2021/08/04 Python