一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

深入PHPOPcache预加载提升Laravel启动速度调优

时间:2026-07-11 09:18:03 编辑:袖梨 来源:一聚教程网

OPcache预加载仅提升PHP-FPM首个请求的类加载速度,需PHP 7.4+、重启FPM生效,CLI完全不支持;应使用opcache_compile_file()安全编译核心类,避开runtime依赖文件。

OPcache 预加载对 Laravel 启动速度有显著提升,但仅适用于 PHP 7.4+ 的 Web(FPM)环境,CLI(如 php artisan、队列 worker)完全不支持——这点必须先确认清楚,否则所有配置都白忙。

预加载只在 PHP-FPM 启动时生效,不是每次请求都重载

预加载脚本(opcache.preload 指向的 PHP 文件)会在 PHP-FPM 进程启动时执行一次,所有类被加载并常驻共享内存。这意味着:

  • 修改预加载脚本或被预加载的类后,必须重启 PHP-FPMsystemctl restart php*-fpm 或宝塔面板中“重载服务”),opcache_reset()php artisan opcache:clear 完全无效
  • 预加载不解决「服务提供者注册」「配置解析」等运行时开销,只跳过「类文件读取 + 编译」环节
  • Laravel 核心类(IlluminateSupportServiceProvider 等)适合预加载;但含 env()config() 调用的业务类会因环境未初始化而报错,需排除

如何写一个安全的 preload.php 文件

直接 require 所有类会触发自动加载冲突或未定义常量错误。推荐用 opcache_compile_file() 显式编译,跳过执行逻辑:

// preload.php$files = [    __DIR__ . '/vendor/autoload.php',    __DIR__ . '/bootstrap/app.php',    __DIR__ . '/app/Providers/AppServiceProvider.php',    // 注意:不要 include routes/web.php 等含 runtime 逻辑的文件];foreach ($files as $file) {    if (file_exists($file)) {        opcache_compile_file($file);    }}
  • 避免 requireinclude,改用 opcache_compile_file() 只编译不执行
  • 不要预加载 routes/config/resources/ 下的文件——它们依赖运行时上下文
  • composer dump-autoload --classmap-authoritative 后,可考虑预加载 classmap 中高频类(如 AppModelsUser),但需验证是否真被 FPM 进程首次加载到

宝塔面板下启用预加载的实操要点

宝塔默认不暴露 opcache.preload 配置项,需手动编辑 FPM 的 php.ini(非 CLI):

立即学习“PHP免费学习笔记(深入)”;

  • 路径通常是 /www/server/php/*/etc/php.ini,确认是 FPM 对应版本(不是 cli/php.ini
  • [opcache] 段落下添加:
    opcache.preload=/www/wwwroot/your-site/preload.php
    opcache.preload_user=www(宝塔默认运行用户为 www
  • 必须设置 opcache.memory_consumption ≥ 256M(预加载本身吃内存),否则启动时报 Failed to prepare preloaded file
  • 检查是否生效:php -r "var_dump(opcache_get_status()['preload']);" —— 返回数组且 scripts 不为空才表示成功

为什么预加载后 php artisan 还很慢?

因为 CLI SAPI 完全忽略 opcache.preload,且 opcache.enable_cli=1 仅启用字节码缓存,不支持预加载。所以:

  • php artisan config:cache 等命令仍需完整加载框架——预加载对此零影响
  • 队列 worker(php artisan queue:work)性能瓶颈主要在服务容器绑定和配置加载,不是字节码编译,强行给 CLI 开 OPcache 收益极低
  • 若想统一加速 CLI 场景,应优先用 config:cacheroute:cacheview:cache,而非纠结预加载

预加载真正起作用的地方只有一个:PHP-FPM 子进程冷启动后的首个请求。它省掉的是磁盘 I/O 和编译时间,而不是 Laravel 自身的启动流程。别把它当成万能药。

热门栏目