workerman配置文件不能直接require或file_get_contents读取,因常驻进程共享内存,重复io和解析会导致性能下降及状态冲突;须用单例+延迟加载+mtime校验实现只解析一次、按需加载、热更新生效。

Workerman 中配置文件不能靠 require 或 file_get_contents 直接读取
Workerman 是常驻内存的 PHP 进程,所有 Worker 实例共享同一份已加载的类和变量。如果在每个 Worker 的构造函数或回调里反复 file_get_contents('config.php') 或 require 'config.php',不仅会重复 IO、解析 PHP 代码,还可能因配置中含全局状态(如静态变量、define())引发不可预期的覆盖或冲突。尤其当配置文件超 1MB(比如带大量路由规则、黑白名单、模板片段),这种做法会拖慢进程启动,甚至触发 OOM。
必须用单例 + 延迟加载 + 缓存键控制
核心不是“只 new 一次”,而是“只解析一次、只加载一次、只在需要时才触发”。Workerman 场景下推荐的单例结构需满足三点:构造函数不主动读文件;提供显式 load() 方法;内部用 static $data 缓存结果,并校验文件 mtime 防止热更新失效。
- 不要在单例构造函数里调用
parse_ini_file()或json_decode(file_get_contents()) - 用
public static function getInstance(): self返回实例,但真正读取推迟到首次调用get('db.host')或all() - 缓存时连同
filemtime($path)一起存,下次读取前先比对,避免改了配置却没生效 - 路径务必用绝对路径:
__DIR__ . '/config/app.php',别依赖getcwd()—— Workerman 启动目录可能和 CLI 当前目录不一致
PHP 数组配置 vs JSON/YAML 文件的性能差异
直接 return ['database' => [...]] 的 PHP 文件,比 JSON/YAML 解析快 3–5 倍(PHP 8.2+ 测得)。但缺点是无法被外部工具校验、不支持注释、易引入执行逻辑风险。若你选 JSON:
使用ydata-profiling(前身为pandas-profiling)生成全面的数据质量报告,包含相关性分析、缺失值模式和基数检测。导出交互式HTML仪表板和JSON摘要。
- 必须用
json_decode(file_get_contents($path), true, 512, JSON_THROW_ON_ERROR),否则大文件解析失败时静默返回null,难排查 - YAML 更慢,且
symfony/yaml在常驻进程中要注意Parser实例复用,避免每次 new 一个新 Parser - 超过 2MB 的 JSON,建议拆成多个小文件,按模块加载(如
db.php、cache.php),用单例统一管理加载时机
Workerman 多环境配置合并时最容易漏掉的一步
很多人按文档写好 env/production.php 和 config/base.php,再用 array_merge_recursive() 合并,结果线上连不上 Redis —— 问题出在数组键名冲突。比如 base.php 里 'redis' => ['host' => '127.0.0.1'],production.php 也写 'redis' => ['port' => 6380],array_merge_recursive 会变成 'redis' => [['host' => '127.0.0.1'], ['port' => 6380]],而非期望的扁平合并。
正确做法是用 array_replace_recursive(),或者自己写个深度覆盖函数。更稳妥的是:所有环境配置都只定义「差量」,基础配置里把完整结构占位写全(包括空数组),环境配置只填值,不删键、不重定义结构。










