Laravel 使用 env 读取环境变量为 null 的问题

(原文链接:https://blog.tanteng.me/2016/12/laravel-en...

不知道大家有没有遇到过,在 Laravel 中(除 app/config 目录下的配置文件中)使用 env 函数读取环境变量,有时有用,有时返回 null,究竟怎么回事?让我们一探究竟。

在 Laravel 项目中,如果执行了 php artisan config:cache 命令把配置文件缓存起来后,在 Tinker 中演示(Tinker 是 Laravel 自带的一个交互式命令行界面),使用 env 函数读取环境变量的值为 null,只有执行 php artisan config:clear 清除配置缓存后就可以读取了,这是为什么呢?

如图:

laravel-env

原因何在?

在 Laravel 中,如果执行 php aritisan config:cache 命令,Laravel 将会把 app/config 目录下的所有配置文件“编译”整合成一个缓存配置文件到 bootstrap/cache/config.php,每个配置文件都可以通过 env 函数读取环境变量,这里是可以读取的。但是一旦有了这个缓存配置文件,在其他地方使用 env 函数是读取不到环境变量的,所以返回 null.

让我们看看这段代码,Illuminate/Foundation/Bootstrap/DetectEnvironment.php line 18:

public function bootstrap(Application $app)
{
    if (! $app->configurationIsCached()) {
        $this->checkForSpecificEnvironmentFile($app);

        try {
            (new Dotenv($app->environmentPath(), $app->environmentFile()))->load();
        } catch (InvalidPathException $e) {
            //
        }
    }
}

这个方法在框架启动后就会运行,这段代码说明了如果存在缓存配置文件,就不会去设置环境变量了,配置都读缓存配置文件,而不会再读环境变量了。

因此,在配置文件即 app/config 目录下的其他地方,读取配置不要使用 env 函数去读环境变量,这样你一旦执行 php artisan config:cache 之后,env 函数就不起作用了。所有要用到的环境变量,在 app/config 目录的配置文件中通过 env 读取,其他地方要用到环境变量的都统一读配置文件而不是使用 env 函数读取。

这个问题以前遇到过后来改了写法,在 github 上一个扩展包中发现一个 bug,发现也是这个问题导致的,跟作者反馈也确认这一点。

本帖已被设为精华帖!
本帖由系统于 5年前 自动加精
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 5

谢谢分享,之前没注意这个坑。明天上班开始改代码了。

7年前 评论

@纸牌屋弗兰克 感谢你发错的问题,之前确实遇到过,但后来直接改写成config(),确实是可以了,也没在意,确实要有探求精神,涨知识了。

7年前 评论
张雷

这坑我也碰到了,直接用config解决了.

4年前 评论

碰到这个坑了,本来好好的,一到生产环境出问题了一直获取不到配置文件

4年前 评论

缓存配置文件到 bootstrap/cache/config.php,那么读取config和env,不都是读取文本吗?区别是什么呢?

1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!