前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >如何正确配置Nginx+PHP

如何正确配置Nginx+PHP

作者头像
LA0WAN9
发布于 2021-12-14 00:19:53
发布于 2021-12-14 00:19:53
5.6K00
代码可运行
举报
文章被收录于专栏:火丁笔记火丁笔记
运行总次数:0
代码可运行

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

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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」等等,缺省的继承关系是从外到内,也就是说内层块会自动获取外层块的值作为缺省值(有例外,详见参考)。

参考:UNDERSTANDING THE NGINX CONFIGURATION INHERITANCE MODEL

让我们先从「index」指令入手吧,在问题配置中它是在「location」中定义的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
location / {
    index index.html index.htm index.php;
}

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

参考:Nginx Pitfalls

接下来看看「if」指令,说它是大家误解最深的Nginx指令毫不为过:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if (!-e $request_filename) {
    rewrite . /index.php last;
}

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
try_files $uri $uri/ /index.php;

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

参考:IfIsEvil and How nginx “location if” works

下面看看「fastcgi_params」配置文件:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
include fastcgi_params;

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

注意:documentrootfastcgi_script_name 之间没有 /。

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

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

参考:FASTCGI_PARAMS VERSUS FASTCGI.CONF – NGINX CONFIG HISTORY

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
try_files $uri =404;

参考:

Nginx文件类型错误解析漏洞

Setting up PHP-FastCGI and nginx? Don’t trust the tutorials: check your configuration!

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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;
    }
}

实际上还有一些瑕疵,主要是「try_files」和「fastcgi_split_path_info」不够兼容,虽然能够解决,但方案比较丑陋,具体就不多说了,有兴趣的可以参考问题描述

补充:因为「location」已经做了限定,所以「fastcgi_index」其实也没有必要。

希望大家以后不要再拷贝粘贴了,如果实在改不了,那么就请拷贝粘贴本文。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2013-10-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Linux 下 Nginx + PHP 环境的配置
本来想简单地写一写,结果发现越写越长,折腾了将近一个月,整出这篇 10000 多字的超长笔记。。。
zgq354
2019/11/24
3.6K1
配置Nginx目录别名Alias支持PHP解析
关于Nginx配置基础知识,PHP用FastCGI,在Apache里,有alias,比较方便,在Nginx下没有虚拟目录概念的,是用location配合alias使用,但使用alias标签的目录块中不能使用rewrite的break。
星哥玩云
2022/07/26
1.5K0
laravel+nginx配置好后报错500的一些问题记录,已解决
二、我们看下fastcgi.conf和fastcgi_params文件,fastcgi.conf文件底部增加一行
sinnoo
2020/11/13
1.7K0
laravel+nginx配置好后报错500的一些问题记录,已解决
【PHP】Nginx+Php服务器环境部署
1.2 php服务版本:php-5.2.17-nts-Win32-VC6-x86
用户5640963
2021/09/06
2.4K0
NGINX.conf配置文件支持pathinfo
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/112491.html原文链接:https://javaforall.cn
全栈程序员站长
2022/07/08
4500
nginx实现一个域名配置多个laravel项目
随着公司的子项目越来越多,会有大大小小十几个工程(仅后端),按照原先的做法,每上线一个项目,那么必须要有一个二级域名映射到对应的工程上,十个工程那么就意味着需要有十个二级域名(还不包含测试环境,次生产环境等), 如此多的域名不仅仅是难于管理,更重要的是比较浪费资源 ,这个问题困扰了我很久,今天终于解决了这个问题,特此记录一下采坑日记,本文不会讲nginx中各个指令的原理,而是用实际的项目配置来练习nginx指令的用法并举一反三。
猿哥
2019/07/24
2.7K0
nginx配置二级域名
最近为了练手Vue框架,写了一个博客项目,昨天刚刚把个人博客部署上线,因为前后端分离,所以使用Ajax来请求后端api接口获取数据,部署的过程中碰到了一个坑。我只有一个域名,所以想让一级域名originalix.com来访问博客,而使用二级域名demo.originalix.com来访问后端页面并且请求api。
Originalee
2018/08/30
20.4K1
nginx配置二级域名
Nginx+DokuWiki+PHP搭建自己的维基百科
Wiki系统属于一种人类知识网格系统,可以在Web的基础上对Wiki文本进行浏览、创建、更改,而且创建、更改、发布的代价远比HTML文本小;同时Wiki系统还支持面向社群的协作式写作,为协作式写作提供必要帮助;与其它超文本系统相比,Wiki有使用方便及开放的特点,所以Wiki系统可以帮助我们在一个社群内共享某领域的知识。
zhangheng
2020/04/28
2.6K0
最完美解决Nginx部署ThinkPHP项目的办法
其实应该使用更简单的方法,fastcgi模块自带了一个fastcgi_split_path_info指令专门用来解决此类问题的,该指令会根据给定的正则表达式来分隔URL,从而提取出脚本名和path info信息,使用这个指令可以避免使用if语句,配置更简单。 另外判断文件是否存在也有更简单的方法,使用try_files指令即可。
全栈程序员站长
2022/07/08
1.2K0
【玩转腾讯云】腾讯云域名https申请配置Centos+nginx
在服务器的项目代码目录,创建crt文件夹,把两个文件上传到crt文件夹中,我用的是laravel项目,所以实在这个目录下
无忧366
2020/03/08
18.5K0
Typecho Nginx 使用https加密访问实现方式(解决其他页面404问题)
躺平程序员老修
2023/09/05
5280
nginx域名访问的白名单配置梳理
在日常运维工作中,会碰到这样的需求:设置网站访问只对某些ip开放,其他ip的客户端都不能访问。可以通过下面四种方法来达到这种效果: 1)针对nginx域名配置所启用的端口(比如80端口)在iptables里做白名单,比如只允许100.110.15.16、100.110.15.17、100.110.15.18访问.但是这样就把nginx的所有80端口的域名访问都做了限制,范围比较大! [root@china ~]# vim /etc/sysconfig/iptables ...... -A INPUT -s
洗尽了浮华
2018/01/23
11.3K0
Nginx访问PHP文件的File not found错误处理
可以在你的location php 里面添加当文件不存在时返回404而不是交给php-fpm进行处理
1900
2022/12/05
1.9K0
Windows2003 下配置 nginx+php 环境
最进在2003下搭建了一下nginx+php环境,现在把搭建过程写出来,与大家分享一下。
SuperDream
2019/02/28
1.9K0
nginx配合两个或多个PHP版本。php5.6与php7
brew安装的东西都在目录/usr/local/opt/ 下了。这是我知识的盲点。所以找了很久没找到。
conanma
2021/12/02
1.8K0
phpstudy nginx配置_phpstorm配置php环境
nginx 是一个高性能的http服务器和反向代理服务器。即nginx可以作为一个HTTP服务器进行网站的发布处理,也可以作为一个反向代理服务器进行负载均衡。但需要注意的是:nginx本身并不会对php文件进行解析。对PHP页面的请求将会被nginx交给FastCGI进程监听的IP地址及端口,由php-fpm(第三方的fastcgi进程管理器)作为动态解析服务器处理,最后将处理结果再返回给nginx。即nginx通过反向代理功能将动态请求转向后端php-fpm,从而实现对PHP的解析支持,这就是Nginx实现PHP动态解析的基本原理。
全栈程序员站长
2022/11/09
2.6K0
phpstudy nginx配置_phpstorm配置php环境
详解如何在url中去掉index.php
THINKPHP官方论坛和网络上很多NGINX配置教程不是太完善的。我一直比较喜欢使用lnmp.org配置服务器环境。所以本文将介绍 LNMP 配置NGINX 支持THINKPHP PATHINFO模式 。
PM吃瓜
2019/08/13
2.4K0
[PHP] 深度解析Nginx下的PHP框架路由实现
所有的框架处理业务请求时,都会处理URL的路径部分,分配到指定的代码中去处理。 实现这一功能的关键就是获取$_SERVER全局变量中对于URL部分的数据
唯一Chat
2019/09/10
8430
[实战]docker-compose搭建基本的nginx+php环境
我已经写了简单的注释,其他的可选项可以在官网或者其他教程学习,这里只是演示最基本的搭建。
宣言言言
2019/12/17
2.8K0
工具系列 | PHP-FPM+Nginx 通信详解
PHP-FPM的全称是PHP FastCGI Process Manager,PHP-FPM是FastCGI的实现,并提供了进程管理的功能。FastCGI进程包含master进程和worker进程两种进程。master进程只有一个,负责监听端口,接收Nginx的请求,而worker进程则一般有多个(可配置),每个进程内部都嵌入了一个PHP解释器,是PHP代码真正执行的地方。
Tinywan
2023/03/08
3K0
工具系列 | PHP-FPM+Nginx 通信详解
推荐阅读
相关推荐
Linux 下 Nginx + PHP 环境的配置
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文