`laravel`容器中`.env`配置在`config`下读取错误
cgfeel opened this issue · comments
我知道在laravel-demo
中有提示:
不要在 config 以外的地方调用
env()
函数,运行config:cache
以后该函数永远返回null
不过这次我是在config
内部调用,举例:
api_service/.env
中是这样写的:APP_ENV=local
api_service/config/app.php
是默认的:'env' => env('APP_ENV', 'production'),
我拿tinker来测试,得到的却是development
,如下:
$ ./lnmp-docker php8-cli php /app/api_service/artisan tinker
Psy Shell v0.11.5 (PHP 8.1.1 — cli) by Justin Hileman
>>> echo config('app.env')
development
我尝试重新启动容器,测试结果还是一样,难道说laravel
中的.env
在容器build
的时候被替换掉了?我找了文档很久都没有提到。
这里我是拿APP_ENV
这一项举例,发现.env
里其他项,在config
下也读取异常。这点还是很重要的,因为在我本地环境、宿主机测试环境、还有服务器生产环境3个地方,需要用到3个不同的.env
You can writing some word in a comment to trigger action:
/translate-title
我用lnmp
创建了一个新项做测试,并设置一个域名解析到新项目
$ cd ./app && ../bin/lnmp-laravel new laravel
$ cd ../ && ./lnmp-docker nginx-config http laravel test.laravel-test.com
- 修改
test.laravel-test.com.conf
,将root
指向/app/laravel/public
- 修改本机
host
,将test.laravel-test.com
指向测试机
配置一个路由./app/laravel/routes/web.php
,如下:
Route::get('/test', function () {
return [
'env' => env('APP_ENV'), // 查询环境变量,如果不是 null 说明并没有产生缓存
'putenv_exists' => function_exists('putenv'), // 确认是否禁用读取.env
'file_exists' => file_exists(base_path('.env')), // 确认.env是否存在
'dir_list' => scandir(base_path()), // 扫描项目根目录所有文件
'env_contents' => file_get_contents(base_path('.env')), // 读取项目根目录.env文件内容
];
});
访问 http://test.laravel-test.com/test 这里只看APP_ENV
的结果,如下:
{
"env":"development",
"putenv_exists":true,
"file_exists":true,
"dir_list":[
".env",
".env.example",
],
"env_contents: "APP_NAME=Laravel
APP_ENV=local",
}
说明:
- 并没有生成缓存,否则
env('APP_ENV')
应该是null
; - 读取
env
环境变量值是development
,并没有禁用putenv
,不存在禁止读取env
文件的情况; env
文件存在于项目根目录,且env
环境变量值是local
这就很费解了,为什么读出来的实际值和.env
不一致呢?
- 我就去看是不是读了
.env.example
,结果发现.env.example
中也是APP_ENV=local
! - 也没有其他
.env*
文件,那么这个环境变量到底来自哪里呢? - 肯定也不是
/app/laravel/config/app.php
,因为默认值是'env' => env('APP_ENV', 'production'),
还有什么情况会造成这个问题呢?实在不能理解了。。。
我再做了一个测试,还是/app/laravel
这个项目,先查询.env
内容确保是local
:
$ ./lnmp-docker php8-cli cat /app/laravel/.env
APP_ENV=local
再查询config
内容是否正确
$ ./lnmp-docker php8-cli cat /app/laravel/config/app.php
'env' => env('APP_ENV', 'production'),
两个文件都没有问题,我开始生成缓存文件:
$ ./lnmp-docker php8-cli php /app/laravel/artisan config:cache
这个时候打开缓存文件./app/laravel/bootstrap/cache/config.php
,可以看到env
指向了development
。。。。这是为什么?这个数据来自哪个文件
看到一篇文章是这么说的 https://blog.csdn.net/weixin_34204057/article/details/91759994
因为环境变量是通过php的
putenv()
和getenv()
实现写入和读取的,如果webserver是通过php -S localhost
或类似命令支持的,那么在你重启服务之前,laravel
不允许覆盖之前的环境变量值。
我尝试过./lnmp-docker down
之后./lnmp-docker up
不管用
请问这个有解决办法吗?
我找到一个暂时能够解决问题的办法,分几种情况:
- 第1种:
.env
也覆盖不了的变量,替换个名字,比如APP_ENV
,就加个名字如:APP_ENV_DOCKER=local
修改config/app.php
,将env
改为新的名字如:'env' => env('APP_ENV_DOCKER', 'production')
,然后重新生成缓存 - 第2种:
.env
可以覆盖的变量,修改.env
后重新生成缓存
最后提醒,如论是那种方式,一定要重新生成缓存,否则修改不生效,无论是生产环境,还是开发环境,一定要手动生成缓存
$ ./lnmp-docker php8-cli php /app/laravel/artisan config:cache
至于有哪些环境变量是可以覆盖的,哪些不能覆盖,我也不清楚,遇到了就用上面的方法来解决吧,虽然比较笨,也很麻烦,目前也只能这样了
请在 .env
文件中更改 APP_ENV
的值
再拉取最新提交试试
再拉取最新提交试试
好的,我一会试试看
再拉取最新提交试试
我重新拉取后,执行下面的命令重新生成缓存,在缓存文件./bootstarp/cache/config.php
中结果还是development
:
./lnmp-docker php8-cli php /app/api_service/artisan config:cache
我拉取的应该是最新的20.10
$ git log
commit 2ca22ec3ce26564f8c6f2d62a5a6383cad636a36 (HEAD -> 20.10, origin/20.10)
Author: Kang Huaishuai <khs1994@khs1994.com>
Date: Wed Jun 22 18:51:58 2022 +0800
Support custom APP_ENV,close #1228
Signed-off-by: Kang Huaishuai <khs1994@khs1994.com>
在 .env
文件(lnmp项目根目录,不是laravel项目中的)中修改 APP_ENV 的值了吗
APP_ENV
谢谢,解决了,原来需要修改./.env,我重新查了下文档,原来在php容器化常用命令里找到了