phpdotenv: Do not throw and exception if .env file is missing

I think it would be a good idea to change the Dotenv::load method so that it wouldn’t throw an exception. The motivation for this is that not all environments use a .env file, for example when we deploy to Amazon we configure the environmental variables through OpsWorks. What this means in practice is that I need an additional check in application to see if the file actually exists before calling Dotenv::load. What do you think?

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Reactions: 2
  • Comments: 39 (3 by maintainers)

Commits related to this issue

Most upvoted comments

@GrahamCampbell The behavior is indeed correct in Lumen. However if you decide to use a .env file during development and run something else in production with the current implementation you will need to add unnecessary logic for this in your bootstrap file.

This is not how the other dotenv libraries works. The ruby implementation ignores the error by default (https://github.com/bkeepers/dotenv/blob/master/lib/dotenv.rb#L14), while the node implementation just logs the error by default (https://github.com/motdotla/dotenv/blob/master/lib/main.js#L39), and there is even a option to make it silent.

If you port a module from one programming language to another, I think that the implementation should be as close to the original implementation as possible. That makes it easier to work with the library if you already worked with another dotenv library in another programming language.

@vlucas Can we re-open this issue and implement it in a future version?

@vlucas if the try/catch method is the preferred pattern for dealing with alternative environment configurations, it might be worth documenting this in the README.

You could include empty .env file?

@GrahamCampbell I still don’t like the fact that this library works differently than the original Ruby library. Also, that try / catch block with an empty catch doesn’t look too nice either.

This behavior cannot be changed at this point. Too many people rely on this behavior for it to be changed now. Just wrap your call in a try/catch.

Sometimes people use frameworks and aren’t in control of how their framework use phpdotenv. In our CI tooling, we constantly get these red hot errors in our logs:

    ERROR: file_get_contents(/app/.env): Failed to open stream: No such file or directory 

    in /app/vendor/vlucas/phpdotenv/src/Store/File/Reader.php:73

To me, a missing .env should trigger a notice or a warning (at most). Not all environments in your pipeline use .env files and not all projects can control the way their framework implements .env support. So we are stuck scrolling through error messages that should be notices, or modify framework source code, which is not a good idea.

@markushausammann We now have two methods you can call, and the exception types are well-defined, so you can know what to catch if you want the hard fail. We have load and safeLoad: https://github.com/vlucas/phpdotenv/blob/v3.3.3/src/Dotenv.php#L71-L98.

If the file doesn’t exist, then InvalidPathException will be thrown only by load. Both load and safeLoad will throw InvalidFileException if the file has a syntax error, however.

@crisu83 Yeah! I’ve updated the comment. Thanks!

@msheakoski Sorry! i had a silly error:

if (file_exists($envFile));
{
    (new Dotenv\Dotenv(dirname($envFile)))->load();
}

see the semi-colon?

We use environment variables in part because of the 3rd factor. Adding specific code for production environment (the try/catch block in this case) goes against that point in some way.

I’m with @crisu83, it should work like the original library.