Nginx(读作 “engine-x”)是一款高性能的 Web 服务器 + 反向代理服务器。Nginx 不会直接执行 PHP 脚本。它只懂得发送文件、转发请求,不会解析 .php 文件里的逻辑代码。所以 Nginx 必须结合 PHP 解析器才能很好的处理 PHP 请求,而且 NGINX 也只懂得如何响应和转发请求,它也不太懂如何管理 PHP 进程以及调用,连接 nginx 和 PHP 解析器的桥梁则是 FastCGI 协议,这里简单介绍一下 FastCGI ,FastCGI(Fast Common Gateway Interface) 是一种用于 Web 服务器(Nginx 或 Apache)与应用程序(如 PHP、Python、Perl)之间通信的协议。而 PHP-FPM 则是 FastCGI 的一种具体实现,拥有处理 Web 服务器和 PHP 应用程序之间的通信。
工作原理 1 2 3 4 5 6 7 8 9 10 11 12 13 浏览器请求 index.php ↓ Nginx 收到请求 ↓ Nginx 将请求转发给 PHP-FPM(FastCGI 协议) ↓ PHP-FPM 调用 PHP 解释器执行代码 ↓ 执行结果(HTML )返回给 Nginx ↓ Nginx 返回响应给浏览器
构建应用程序 很多教程都按照部署的顺序进行讲解,首先讲解 Nginx 的部署,PHP-FPM 的安装,PHP 环境安装等等的顺序进行讲解,并没有将各部件之间的关系讲解清楚。所以我打算以开发的角度讲解如何使用 Nginx 部署 PHP 应用程序。首先讲解如何构建一个简单的 php 程序,然后运行程序需要的环境,然后讲解如何透过 FastCGI 将其封装成为一个 web 服务,最后讲解如何借助 nginx 的能力将其完善成为一个完整的 web 应用。
let’s start from small, 一个经典的 hello world 程序
第一个 PHP 脚本:hello.php
1 2 3 4 5 6 7 <?php echo "Hello World!" ;?>
要执行字段 php 脚本,我们需要安装 php 基础包,用于解释和执行 php 脚本。这里以 REHL 系列 linux 为例,讲解如何安装 php 基础包:
注意:在安装 php 基础包的时候就自动帮我们安装了 php-fpm, 后续我们需要使用到 php-fpm 的时候就不必再次安装了
接着我们使用 php 脚本解析执行器来运行这段脚本
1 2 3 4 5 user@server $ php hello.php Hello World!
一个简单的 php 程序就完成了,接着我们在此基础上完善一下应用程序,创建一个完整的 index.php, 里面包括大部分的 web 元素,超链接,图片,css, javascript 等等。将其保存为 index.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 <?php $title = "欢迎来到我的网站" ;$subtitle = "一个由 PHP 动态生成的页面" ;$date = date ("Y年m月d日 H:i:s" );?> <!DOCTYPE html> <html lang="zh-CN" > <head> <meta charset="UTF-8" > <title><?php echo $title ; ?> </title> <meta name="viewport" content="width=device-width, initial-scale=1.0" > <!-- CSS 样式 --> <style> body { font-family: "Microsoft YaHei" , sans-serif; margin: 0 ; background: color: } header { background: color: white; padding: 20 px; text-align: center; } nav { background: display: flex; justify-content: center; gap: 20 px; padding: 10 px 0 ; } nav a { color: white; text-decoration: none; font-weight: bold; } nav a:hover { text-decoration: underline; } main { max-width: 900 px; margin: 40 px auto; background: white; padding: 30 px; border-radius: 12 px; box-shadow: 0 4 px 10 px rgba (0 ,0 ,0 ,0.1 ); } h1 { color: img { max-width: 100 %; border-radius: 8 px; } .gallery { display: flex; gap: 10 px; flex-wrap: wrap; } .gallery img { width: 30 %; transition: transform .2 s; } .gallery img:hover { transform: scale (1.05 ); } footer { background: color: text-align: center; padding: 15 px 0 ; margin-top: 40 px; } button { background: color: white; border: none; padding: 10 px 16 px; border-radius: 6 px; cursor: pointer; } button:hover { background: } </style> </head> <body> <header> <h1><?php echo $title ; ?> </h1> <p><?php echo $subtitle ; ?> </p> </header> <nav> <a href="#home" >首页</a> <a href="#gallery" >图片</a> <a href="#about" >关于我们</a> <a href="#contact" >联系我们</a> </nav> <main id="home" > <h2>欢迎光临!</h2> <p>当前服务器时间:<strong><?php echo $date ; ?> </strong></p> <p>这是一个包含 PHP、HTML、CSS、JavaScript 的完整网页示例。你可以在此基础上扩展自己的功能。</p> <hr> <section id="gallery" > <h3>📸 图片展示</h3> <div class ="gallery "> <img src ="https ://picsum .photos /300/200?random =1" alt ="图片1"> <img src ="https ://picsum .photos /300/200?random =2" alt ="图片2"> <img src ="https ://picsum .photos /300/200?random =3" alt ="图片3"> </div > </section > <hr > <section id ="about "> <h3 >💡 关于我们</h3 > <p >我们是一家专注于 Web 技术与网络加速的团队。我们的目标是让全球访问更快速、更稳定。</p > <p ><a href ="https ://www .php .net /" target ="_blank ">了解更多 PHP 技术 →</a ></p > </section > <hr > <section id ="contact "> <h3 >📬 联系我们</h3 > <form id ="contactForm "> <label >姓名:</label ><br > <input type ="text " id ="name " placeholder ="请输入您的名字" required ><br ><br > <label >留言:</label ><br > <textarea id ="message " rows ="4" cols ="40" placeholder ="请输入留言内容" required ></textarea ><br ><br > <button type ="submit ">提交留言</button > </form > <p id ="formResponse " style ="color :green ; display :none ;">✅ 已收到您的留言,谢谢!</p > </section > </main > <footer > <p >© <?php echo date ("Y "); ?> 我的 PHP 网站 | Powered by PHP & Nginx </p > </footer > <!-- JavaScript --> <script > document .getElementById ("contactForm ").addEventListener ("submit ", function (e ) { e.preventDefault (); document.getElementById ("formResponse" ).style.display = "block" ; }); document.addEventListener ("DOMContentLoaded" , () => { const btn = document.createElement ("button" ); btn.textContent = "点击显示当前时间" ; btn.onclick = () => alert ("当前时间是:" + new Date ().toLocaleString ()); document.body.appendChild (btn); }); </script> </body> </html>
使用 php 脚本解析执行器测试一下脚本,并将内容输出为 index.html, 打开 index.html 就能看到我们制作的首页的效果。
1 2 3 user@server $ php hello.php > index.html
浏览器打开 index.html,就能看到首页效果了。
这样一个包含 css, javascipt, 超文本等等 web 元素的首页就制作完成了,如果我们要进一步探索,可以将 css 样式做成外部样式,javascript 都移动到 index.php 外部。但是这些静态文件的管理就属于 nginx 所擅长的了,所以这里不继续展开了。另外我们也可以加入 php 连接数据库脚本,这样就更加完善了。由于这是一篇讲解 php 应用部署的文章,所以这部分也不进一步展开讲解了。
使用 PHP-cli 内置 web server 运行 index.html PHP 内置了一个轻量开发服务器。适合快速测试或本地开发使用,不适合生产环境。我们可以使用它来测试我们的 index.php 脚本,这样就不用手动拷贝生成的 index.html 查看效果了。
1 2 3 php -S 0.0.0.0:8080 -t /var/www/html
🔹 启动一个 PHP 内置开发服务器 🔹 监听 0.0.0.0:8080 所有网卡请求(内网 + 外网) 🔹 将 /var/www/html 作为网站根目录, 🔹 静态文件直接返回,.php 文件交给 PHP 解析执行
这样我们将 index.php 放入到/var/www/html 文件夹下,然后使用浏览器打开 http://your_server_id:8080/index.php 即可看到首页内容。
使用 PHP-FPM 将 php 应用包装成一个 web 应用 PHP-cli 内置 web server 只适合在测试和本地开发中使用,在生产环境我们还是要使用 PHP-FPM 将 php 应用包装成为一个 web 应用。
CGI(Common Gateway Interface)全称是“通用网关接口”,是一种让客户端(web 浏览器)与 Web 服务器(nginx 等)程序进行通信(数据传输)的协议。FastCGI(Fast Common Gateway Interface)全称是“快速通用网关接口”是通用网关接口(CGI)的增强版本,由 CGI 发展改进而来,主要用来提高 CGI 程序性能, 类似于 CGI,FastCGI 也是一种让交互程序与 Web 服务器通信的协议。
安装与配置 PHP-FPM PHP 在 5.3.3 之后已经把 php-fpm 并入到 php 的核心代码中了。 所以 php-fpm 不需要单独的下载安装。由于是关联安装的,所以这里也不用太担心 php 与 php-fpm 的版本问题。
运行rpm -ql php-fpm, 可以看到 PHP-FPM 的主配置文件是 /etc/php-fpm.conf
首先我们来直接启动 php-fpm
1 2 3 4 5 6 user@server $ sudo php-fpm [01-Nov-2025 16:26:26] ERROR: unable to bind listening socket for address '/run/php-fpm/www.sock' : No such file or directory (2) [01-Nov-2025 16:26:26] ERROR: FPM initialization failed
此时系统会报错,原因是 php-fpm 的配置文件中指定的 user 默认为 apache, 而 apache 用户没有权限在/run/php-fpm 目录下创建 www.sock 文件
1 2 3 4 user@server $ grep "^user" /etc/php-fpm.d/www.conf user = apache
由于我们要使用 Nginx 结合 php-fpm 来部署 PHP 应用,为了避免在 SELinux 开启以后的一些权限问题,我让 php-fpm 以 Nginx 用户运行,此时我们修改 www.conf 将用户设置为 nginx, 用户组设置为 nginx。然后为 nginx 用户创建/run/php-fpm 文件夹。
1 2 3 4 sudo mkdir -p /run/php-fpmsudo chown -R nginx:nginx /run/php-fpm
再次以 nginx 身份启动 php-fpm,即可成功启动 php-fpm 了
1 2 3 user@server $ sudo -u nginx php-fpm
为了验证此步骤是否成功,我们可以安装 fastcgi 测试工具 fcgi
然后切换为 nginx 用户
执行测试脚本,如果能正确的生成首页的 html 内容则表示 php-fpm 配置成功。
1 2 3 4 5 6 SCRIPT_FILENAME=/var/www/html/index.php \ REQUEST_METHOD=GET \ QUERY_STRING="" \ cgi-fcgi -bind -connect /run/php-fpm/www.sock
将 php-fpm 设置为开机自启动
首先将之前手动启动的 php-fpm 关闭
1 2 3 sudo kill -QUIT $(cat /run/php-fpm/php-fpm.pid)
设置 php-fpm 为开机自启动
1 2 3 4 5 6 7 8 9 10 sudo systemctl enable php-fpmsudo systemctl start php-fpmsystemctl status php-fpm
至此 php-fpm 就安装并配置完成,如果有些参数需要调整,可以阅读 php-fpm 相关文档进行调整。
安装并配置 Nginx 安装 nginx
1 2 3 4 5 6 7 8 9 10 dnf install -y nginx systemctl enable --now nginx systemctl status nginx
转发请求给 PHP-FPM
在 /etc/nginx/conf.d 新增一个配置文件,例如:your_domain.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 server { server_name www.your_domain.com; listen 443 ssl; root /var/www/html/; index index.html index.htm index.php; location / { try_files $uri $uri / /index.php?q=$uri &$args ; } location ~ \.php?.*$ { fastcgi_pass unix:/run/php-fpm/www.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name ; include fastcgi_params; } ssl_certificate /etc/letsencrypt/live/www.your_domain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/www.your_domain.com/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; } server { listen 80; server_name www.your_domain.com; return 301 https://$host$request_uri ; }
这是一个完整的使用域名和 https 方式访问 php 应用的示例 nginx 配置文件。关于如何申请免费的 ssl 证书和配置 ssl 证书可以参考我之前的文章如何在 Almalinux 上为 Nginx 安装 TLS/SSL 证书并开启自动续订 或者 一篇文章搞懂 HTTPS 协议 。这里重点关注两个 location 部分的配置, 注释部分已经做了详细解释。
另外需要加一条将 DNS 解析将域名和服务器公网 ip 进行绑定,这样通过域名方式就可以访问 php 应用了,在本例中为https://www.your_domain.com/index.php
参考文档 第一课:服务器环境部署(Nginx+PHP-FPM)
关于 CGI 和 FastCGI 的理解
PHP-FPM 详解