最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
深入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-FPM(
systemctl 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); }}
- 避免
require或include,改用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.phpopcache.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:cache、route:cache、view:cache,而非纠结预加载
预加载真正起作用的地方只有一个:PHP-FPM 子进程冷启动后的首个请求。它省掉的是磁盘 I/O 和编译时间,而不是 Laravel 自身的启动流程。别把它当成万能药。