在 cache.php 中直接使用 env() 返回 null 是因加载时序问题,应改用 $_env['redis_host'] ?? '127.0.0.1' 等原生方式并加默认值兜底。

cache.php 里直接用 env() 函数会返回 null?
因为 ThinkPHP 的 cache.php 配置文件在框架初始化早期就被加载,此时环境变量尚未被完整解析——env() 函数依赖的 .env 文件读取和环境检测逻辑,实际发生在 App::init() 阶段,而配置文件加载早于它。
所以你在 cache.php 里写 env('REDIS_HOST'),大概率得到 null 或空字符串,不是 bug,是加载时序问题。
正确做法:改用 $_ENV 或 getenv()
这两个是 PHP 原生机制,在 cache.php 执行时已可用(前提是 .env 已被 think\Env 类提前加载过——ThinkPHP 默认会在入口文件中调用 Env::load())。
推荐优先用 $_ENV,更稳定;getenv() 在某些 SAPI(如 CLI 模式)下可能受 php.ini 中 variables_order 影响。
-
$_ENV['REDIS_HOST']—— 直接取值,注意大小写必须完全匹配 -
getenv('REDIS_HOST')—— 返回字符串或false,建议加空值判断 - 避免在
cache.php中调用env()、Config::get()等依赖框架运行时的函数
示例:redis 缓存配置中读取 Env 变量
return [
'default' => 'redis',
'stores' => [
'redis' => [
'type' => 'redis',
'host' => $_ENV['REDIS_HOST'] ?? '127.0.0.1',
'port' => (int)($_ENV['REDIS_PORT'] ?? 6379),
'password' => $_ENV['REDIS_PASSWORD'] ?? '',
'select' => (int)($_ENV['REDIS_DATABASE'] ?? 0),
'timeout' => 0,
],
],
];
注意:(int) 强制类型转换很重要,否则端口、数据库编号可能被当字符串处理,部分驱动会报错或连接异常。
为什么不用 Env::get()?
think\Env::get() 是 ThinkPHP 封装的环境变量读取方法,但它内部仍依赖 $_ENV 或 getenv(),且做了额外判断(比如是否启用 env 功能)。在 cache.php 这种纯配置上下文中,绕过封装直接用 $_ENV 更轻量、更可控。
另外,如果你在 cache.php 中 use think\Env,会导致类自动加载提前触发,可能干扰配置加载流程,尤其在某些部署环境下(如 Swoole 长连接)容易引发不可预期行为。
真正容易被忽略的是:环境变量的默认值兜底必须写,不能只靠 .env。服务器部署时 .env 文件常被忽略或权限错误,$_ENV 读不到就全挂了。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











