登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  文章 >  php教程

PHP OPcache 预加载适合放哪些代码

来源:17golang原创

时间:2026-09-28 07:51:01 409浏览 收藏

PHP OPcache 预加载适合放进程启动后长期不变、没有请求状态、能被多个请求复用的类、接口、trait 和纯函数。它不是“把整个项目提前 include 一遍”:数据库连接、当前用户、请求参数、环境快照和会随发布改变的业务数据,都应该留在请求生命周期内。

官方文档:https://www.php.net/manual/en/opcache.preloading.php

要点速览
  • 预加载需要持久化 PHP 进程,PHP-FPM 比 CLI 更适合。
  • 优先选择稳定的类、接口、trait 和无副作用函数,避免连接、状态和动态配置。
  • 预加载内容要到 PHP 进程重启后才会被清掉,部署必须配套重启与回滚。

先判断预加载真正解决什么问题

普通 OPcache 主要缓存编译后的字节码;preload 则在 PHP 进程启动时执行一个脚本,把其中加载的实体放进持久内存。之后的请求可以直接看到已加载的类和函数,少掉重复解析与加载的工作,但代价是常驻内存和更严格的发布边界。

PHP-FPM、preload.php、OPcache共享内存与HTTP请求的静态关系说明图
图1:OPcache 预加载的静态边界说明图,展示跨请求复用与 CLI 单次进程的区别。

因此,判断标准不是“这个文件常用吗”,而是“它定义的实体是否稳定、初始化是否无副作用、是否值得让每个 PHP-FPM worker 长期持有”。CLI 即使启用 OPcache,通常也没有跨请求持久进程可复用,收益很有限。

把稳定的类与函数放进 preload.php

配置至少需要开启 OPcache 并指定预加载入口。示例使用显式清单,便于代码审查和发布回滚;不要一开始就递归加载整个 vendor 目录。

; 仅在持久化 SAPI 中启用预加载
opcache.enable=1
opcache.preload=/srv/app/config/preload.php
; 按服务启动用户执行,避免用 root 运行应用代码
opcache.preload_user=www-data

include 或 require 会执行被引入文件,opcache_compile_file() 只编译并缓存脚本。入口本身应保持小而明确:如果某个类的加载依赖运行时条件,就不要为了凑数量强行放进来。

按生命周期筛选代码边界

可以把候选代码分成三组:稳定定义、启动配置和请求资源。前两组还要继续检查副作用;第三组直接排除。

代码或资源建议原因
值对象、接口、trait、纯函数优先预加载跨请求稳定,初始化成本可预测
只读配置定义谨慎预加载发布后可能形成旧值快照
PDO、Redis、文件句柄不要预加载资源属于请求或连接生命周期
当前用户、Header、业务数据不要预加载每个请求的输入都不同
PHP preload.php中稳定类与数据库连接请求状态之间的生命周期边界图
图2:代码筛选结构说明图,稳定类可以常驻,连接和请求状态必须在请求内创建。

最容易忽略的是“配置读取”。如果 preload.php 把环境变量、租户配置或发布目录内容直接固化,服务重启前它们不会自动更新。更稳妥的做法是预加载配置类的定义,而不是预加载某次部署读取出来的动态值。

把部署重启和验证纳入方案

预加载实体会一直存在到 PHP 进程关闭;仅调用 opcache_reset() 不能可靠地重新载入已预加载代码。发布流程应把 PHP-FPM 的平滑重启或滚动替换列为必选动作,并在失败时保留旧进程的回滚路径。

# 先检查配置语法,再让 PHP-FPM 重新执行 preload.php
php-fpm -t
# 下面的服务名按发行版实际名称调整,避免误重启错误实例
sudo systemctl reload php8.3-fpm

复查时可以查看 opcache_get_status() 返回的 preload_statistics,确认预加载统计中出现了预期的脚本、类或函数。这里检查的是加载边界,不是用一张静态图冒充性能压测;是否值得长期保留,仍要结合常驻内存、发布频率和请求基线决定。

相关问题

所有 vendor 类都适合预加载吗?

不适合。应先筛掉带启动副作用、依赖动态配置或占用大量常驻内存的部分,再按稳定性和收益分组。

修改 preload.php 后为什么旧代码还在?

因为预加载实体跟随 PHP 进程生命周期存在。需要让对应 PHP-FPM 进程重启或滚动替换,不能只清理普通 OPcache。

Windows 环境能直接使用 OPcache preload 吗?

PHP 官方文档明确说明预加载不支持 Windows;可以继续使用普通 OPcache,但不要把 preload 配置当作跨平台方案。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>