Cms: Problems with multi-thread php for dotenv

Created on 15 Jan 2019  Â·  11Comments  Â·  Source: craftcms/cms

Description

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.

Steps to reproduce

  1. Make multiple ajax calls or load multiple pages in multiple tabs in a Craft CMS website.

Additional info

  • Craft version: 3.0.37
  • Windows 10, Apache 2.4.37 with mod_php
  • PHP version: PHP 7.2.14 thread safe x64
enhancement

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 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();

All 11 comments

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mattstein picture mattstein  Â·  3Comments

brandonkelly picture brandonkelly  Â·  3Comments

michel-o picture michel-o  Â·  3Comments

timkelty picture timkelty  Â·  3Comments

angrybrad picture angrybrad  Â·  3Comments