When you have ajax calls or reload/load multiples pages rapidly in a multi-thread environment (for example, Windows Apache with mod_php), some values from .env don't load with getenv(). See these Github issues:
https://github.com/vlucas/phpdotenv/issues/203
https://github.com/vlucas/phpdotenv/issues/219
https://github.com/vlucas/phpdotenv/issues/248
https://github.com/vlucas/phpdotenv/issues/266
https://github.com/laravel/framework/issues/24510
To circumvent this issue, Laravel cache the values from dotenv in a compiled config file:
https://laravel.com/docs/5.7/configuration#configuration-caching
Craft CMS should use a similar solution to prevent these problems on many environments.
Interesting. In lieu of that, you could start storing the environment variables as actual system environment variables, rather than relying on .env. For example, Elastic Beanstalk has an “Environment properties” section where you can manage the environment variables - https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/environments-cfg-softwaresettings.html#environments-cfg-softwaresettings-console.
Yes, but in my case, the problem is in our work environment (it works fine in production). We all use Windows and I have Apache with multiples sites using dotenv. For now, I configured Apache to use mod_fcgid (cgi implementation) instead of mod_php to make it work in local. I had the problem for weeks but just figured it out,
See this comment from the creator of phpdotenv:
https://github.com/vlucas/phpdotenv/issues/219#issuecomment-450900648
Hmm, I don't think this is necessary. I'd strongly recommend people use this package to one-time use this library to populate a compiled config file, exactly how Laravel does it. I'd consider that to be the correct way to use this library in a multi-threaded environment (that is, by not using it in the multi-threaded environment).
Good to know! I didn’t mean to give the impression we’re not interested; just offering a workaround for the meantime.
Thank you for answering so fast and your amazing work on Craft!
V3 of the library provides a fix for this, allowing you to control how phpdotenv set environment variables.
I think it's likely the following example will work in a multithreaded environment. This avoids using the adapter that would have called putenv and getenv, which are not threadsafe.
<?php
use Dotenv\Environment\Adapter\EnvConstAdapter;
use Dotenv\Environment\Adapter\ServerConstAdapter;
use Dotenv\Environment\DotenvFactory;
use Dotenv\Dotenv;
$factory = new DotenvFactory([new EnvConstAdapter(), new ServerConstAdapter()]);
Dotenv::create($path, null, $factory)->load();
I have multiple AJAX calls which were clearing the variables and this solution worked for me.
Thanks
Craftcms would need to replace all their calls from getenv("") to $_ENV[""] then?
Thanks
Laravel recently did this and the community freaked out, and they ultimately brought back getenv() support.
Ultimately, Laravel will remove getenv. People just need time to fix their libraries, and need to be educated about getenv not being a good choice of function.
This should be resolved for the next release (3.4.18) per e76d6a4842510b36909f75fe4861fc611ff3334c.
Most helpful comment
I think it's likely the following example will work in a multithreaded environment. This avoids using the adapter that would have called
putenvandgetenv, which are not threadsafe.