标签归档:php

Nginx转发PHP请求流程

Nginx 本身不能直接执行 PHP 脚本,它通过一个叫做 PHP-FPM 的协议网关,将 PHP 文件的请求转发给 PHP 解释器进行处理,最后将处理结果返回给客户端。

整个过程可以分解为以下几个步骤:

  1. 客户端请求:浏览器请求一个 PHP 文件,例如 http://test.com/index.php
  2. Nginx 接收:Nginx 服务器接收到这个请求。
  3. 规则匹配:Nginx 检查自己的配置文件,发现这个请求是针对 .php 文件的。
  4. 转发请求:Nginx 根据配置,通过 FastCGI 协议 将请求和相关参数(如文件路径、请求头等)转发给 PHP-FPM 进程。
  5. PHP-FPM 处理:PHP-FPM 主进程接收到请求,分配一个空闲的 PHP工作进程来处理。
  6. PHP 解释执行:该 PHP 工作进程找到对应的 .php 文件,执行其中的代码。
  7. 返回结果:PHP 进程将执行生成的 HTML 或其他内容,通过 FastCGI 协议返回给 Nginx。
  8. Nginx 响应:Nginx 接收到 PHP 返回的内容,再将其作为 HTTP 响应返回给客户端浏览器。

一道“埋坑”的PHP笔试题

群里一位网友发了道PHP笔试题:

setcookie('name', 'soso');
var_dump($_COOKIE['name']);

上面这道题,大家暂时别运行,先猜猜看,输出结果是什么?

公布答案:

Warning: Undefined array key "name" in /www/wwwroot/wp/php_cookie.php on line 3
NULL

猜对没?

这个问题的原因是 setcookie() 函数并不会立即在当前请求中设置 $_COOKIE 数组

原因分析

  1. setcookie() 只是向浏览器发送一个 HTTP 响应头,告诉浏览器设置 cookie;
  2. $_COOKIE 数组包含的是当前请求中浏览器 已经发送 的 cookie;
  3. 只有在 下一次请求 时,浏览器才会发送这个 cookie,此时 $_COOKIE['name'] 才会存在。

【PHP】实现立即输出缓冲区内容

今天有朋友问到,调chatgpt接口,想把返回结果逐字输出到页面上。然后就调试了一下相关代码,搜索到这篇文章:https://www.jianshu.com/p/06a55bc97e5c

for ($i = 0; $i < 10; $i++) {
 echo $i . '';
 ob_flush();
 flush();
 sleep(1); 
}

按代码理解似乎应该是每过1秒钟就会输出一次数据,但在Nginx服务器会待代码执行完一并输出。

nginx 里面 flush 默认是无效的,这个函数默认是作用在php作为 apache模块时才有效,如果需要 nginx 里面支持,需要加上一行 :

header('X-Accel-Buffering: no');

完整代码如下:

header('Cache-Control: no-cache'); // 禁用浏览器缓存
header('X-Accel-Buffering: no');  // 适用于Nginx服务器环境 
for ($i = 0; $i>10; $i++) { 
  echo $i . ''; 
  ob_flush(); 
  flush(); 
  sleep(1);
}

参考文章:

http://nginx.org/en/docs/http/ngx_http_proxy_module.html 文章中X-Accel-Buffering的介绍