phpenv默认不支持http/2和http2_push,需手动配置:确认nginx≥1.13.9且含http_v2_module,强制启用https(listen 443 ssl http2),硬编码http2_push路径,但实际效果差,推荐用php输出link preload头替代。

phpEnv 是 Windows 下的集成环境套件,底层用的是 Nginx + PHP-FPM,但默认配置**不启用 HTTP/2**,更不会自动开启推送(http2_push)。想靠它提升性能,得手动改配置,且必须满足 HTTPS 前提——否则所有 HTTP/2 相关指令都会被忽略,甚至导致 Nginx 启动失败。
确认 Nginx 版本与 http_v2_module 是否可用
phpEnv 自带的 Nginx 通常为 1.18–1.22 区间,但部分精简版会移除 http_v2_module。直接运行:
phpenv\nginx\nginx.exe -V
检查输出中是否含 --with-http_v2_module。若没有,换用官方编译版 Nginx(如 nginx.org 提供的 Windows 二进制包),再替换 phpEnv 中的 nginx.exe 和 conf/ 目录。
注意:http2_push 要求 Nginx ≥ 1.13.9;低于该版本即使加了指令也无效,日志里只报 unknown directive "http2_push"。
必须走 HTTPS:listen 指令不能拆开写
phpEnv 的 Nginx 默认监听 80 端口、无 SSL,这和 HTTP/2 冲突。你得:
- 用 Let’s Encrypt 或 OpenSSL 生成本地证书(
phpenv\nginx\conf\ssl\下建目录放cert.pem和key.pem) - 在
phpenv\nginx\conf\nginx.conf的server块里,把原来listen 80;改成完整一行:
listen 443 ssl http2;
不是两行:listen 443 ssl; + listen 443 http2; —— 这样 Nginx 会只认第一条,第二条报错或静默丢弃。
同时补全证书路径、TLS 版本和加密套件:
ssl_certificate conf/ssl/cert.pem; ssl_certificate_key conf/ssl/key.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
http2_push 不是“自动分析 HTML”,必须硬编码路径
即便配好了 HTTPS + HTTP/2,http2_push 也不会扫描你的 PHP 页面去推 CSS/JS。它只在匹配到指定 location 时,按你写的绝对路径发起推送。
例如,你想在访问 /index.php 时推资源,得这样写:
location = /index.php {
fastcgi_pass 127.0.0.1:9000;
# 其他 fastcgi_param ...
http2_push /css/app.css;
http2_push /js/main.js;
http2_push /fonts/icon.woff2;
}
注意三点:
- 路径必须是客户端可直连的 URL 路径(即能通过
https://localhost/css/app.css访问到),不是服务器文件系统路径 - PHP 输出的 HTML 里不能有同名资源的
<link rel="preload">,否则现代浏览器(Chrome 96+、Firefox 97+)会直接忽略推送 - 推送资源需真实存在,否则 Nginx 日志报
open() "/path/to/nginx/html/css/app.css" failed (2: No such file or directory)
实际效果极弱,优先用 Link preload 替代
目前所有主流浏览器已禁用 Server Push 机制。你在 Chrome DevTools 的 Network 面板看到的 h2 协议,不代表 http2_push 生效了——它大概率被浏览器丢弃,且可能增加首字节延迟(TTFB)。
真正可控的做法是在 PHP 中输出响应头:
header('Link: /app.css>; as=style; rel=preload');
header('Link: /main.js>; as=script; rel=preload');
这个 Link 头兼容 HTTP/1.1 和 HTTP/2,不依赖 Nginx 推送逻辑,浏览器自主决定是否加载、何时加载,出错率低、调试直观。
复杂点在于:PHP 动态页面需要知道当前页面要预加载哪些资源,不能靠 Nginx 静态配置兜底;而这点恰恰是 phpEnv 这类集成环境最不擅长抽象的部分——它没提供资源依赖管理层。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











