Comments (39)
@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?
from phpdotenv.
You could include empty .env file?
from phpdotenv.
@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.
from phpdotenv.
@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.
from phpdotenv.
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.
from phpdotenv.
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.
from phpdotenv.
@msheakoski Sorry! i had a silly error:
if (file_exists($envFile));
{
(new Dotenv\Dotenv(dirname($envFile)))->load();
}
see the semi-colon?
from phpdotenv.
@crisu83 Yeah! I've updated the comment. Thanks!
from phpdotenv.
@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.
from phpdotenv.
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.
from phpdotenv.
I could, but it's not an optimal solution because I don't want to create or keep around an empty .env file that I'd include in my build. Adding an empty .env file sounds like a hack.
from phpdotenv.
That's no better than checking if the file actually exists. If the project would use proper versioning (semver) you could change this for the next major release without worrying to break BC.
from phpdotenv.
Please, add configuration attribute for this behaviour. I totally agree with @crisu83, this exception does not need on production environments. Now, all times, I need to create empty .env file in project root.
from phpdotenv.
You don't need to deploy an empty .env
file - just do a file_exists
check before using Dotenv instead.
from phpdotenv.
@vlucas I think that's unnecessary boilerplate, if the library automatically loads a file it should ensure that the file actually exists before trying to load it.
from phpdotenv.
@crisu83 It does, which is why it throws an Exception if it does not exist. You can also wrap the Dotenv call in a try/catch block as well.
from phpdotenv.
Of course you can, but it feels unnecessary to add such logic to your bootstrap file. Here's how dotenv is used by Lumen, Laravel's micro framework https://github.com/laravel/lumen/blob/master/bootstrap/app.php#L5. Maybe that gives you a better idea of what I'm after here.
from phpdotenv.
I think this behviour is correct. See how it's commented out. That's what you do if you don't want to load a .env file.
from phpdotenv.
@vlucas I still think that we should re-open this issue, just because it works differently in the PHP implementation than in the other implementations.
from phpdotenv.
We have changed the exception we throw. You can now catch it. There's no real issue here.
from phpdotenv.
See how we catch the exception specifically for if the file is not found: https://github.com/laravel/framework/blob/v5.2.32/src/Illuminate/Foundation/Bootstrap/DetectEnvironment.php#L22-L26.
from phpdotenv.
Just thought I would throw my 2 cents in for not throwing on file not found... I realize it is an easy fix on the user end but catches me every time in production :)
Either way, thanks for the superb library!
from phpdotenv.
I know this has been closed for a while, but for future readers:
The most performant solution would be file_exists()
because as they say, no code is faster than no code. This solution does not load the Dotenv code into memory and does not execute any further instructions in the PHP interpreter. That's what you want for production, the most optimized path.
$envFile = "path/to/.env";
if (file_exists($envFile)) {
(new Dotenv\Dotenv(dirname($envFile)))->load();
}
Having Dotenv ignore the missing file internally still loads Dotenv into memory, and instantiates objects such as Loader and InvalidPathException. A try/catch block, like one that @GrahamCampbell pointed to in Laravel, would also do the same with the added overhead of the instructions for handling the exception.
from phpdotenv.
@msheakoski even with file_exists returning false, I'm still getting: Uncaught Dotenv\Exception\InvalidPathException: Unable to read the environment file at
from phpdotenv.
@jartaud you mean semi-colon?
from phpdotenv.
I agree, it should not throw an exception at all. A lot of implementations use .env
files only on development platforms while staging and production, etc. use a different implementation of environment variables.
from phpdotenv.
@markushausammann An example of using safeLoad
is available at https://github.com/laravel/lumen-framework/blob/v5.8.8/src/Bootstrap/LoadEnvironmentVariables.php if you are interested. It is called at https://github.com/laravel/lumen/blob/v5.8.0/bootstrap/app.php#L1-L7.
from phpdotenv.
@GrahamCampbell While it's good that this issue finally got mended after four years, I'm still a bit unsatisfied with the solution as this differs from the other implementations. 😐
from phpdotenv.
I don't agree that it does. Neither load nor loadSafe is the default behaviour. It's up to the caller to choose which they want. Thus, it does not differ in any meaningful way, only naming.
from phpdotenv.
@GrahamCampbell Some silentLoad
method would be perfect, with same try-catch under the hood, don't you think? Especially if you have default values in your project that could be altered by .env file (so .env file is optional). In that case try-catch feels like unnecessary complication.
And with load
method, try-catch block is a part of usage but I don't see any mention about that in readme.
from phpdotenv.
@mykytak safeLoad
does exactly what you say already.
from phpdotenv.
@GrahamCampbell safeLoad
throws file_get_contents(...): failed to open stream: No such file or directory
exception. Yes, it is not fatal but still exception. So you need to wrap it anyway.
from phpdotenv.
Does it? I can't replicate that?
from phpdotenv.
This has to be a bug in your custom error handler. We suppress the error.
from phpdotenv.
https://github.com/vlucas/phpdotenv/blob/v3.6.0/src/Loader.php#L111-L150
from phpdotenv.
Make sue your custom error handler looks aterror_reporting()
. If it's 0, ignore the error - it was suppressed by the code, and not meant be handled.
from phpdotenv.
@GrahamCampbell it's CodeIgniter default I think. Maybe it was altered in some way, don't know.
from phpdotenv.
Well, something in your code is grabbing up that error, and incorrectly propagating it. Specifically, something in your registered error handlers. Are you seeing your app crash, or just it being logged?
If you write a single PHP file and just load composer's autoload file and then the phpdotenv code, that should confirm there's no bug in the code here.
from phpdotenv.
Hiding the above comment because the author has not read the README or any of this thread. Going to lock this now, since safeLoad
is already implemented, and available.
from phpdotenv.
Related Issues (20)
- Equals Symbol in last line of multiline variable causes issues. HOT 3
- Save to .env HOT 1
- How to loads many env file, but the extension is .txt HOT 1
- Fatal error: Uncaught Error: Class "Dotenv\Dotenv" not found in HOT 1
- Performance degradation HOT 3
- Question - are there any 'builtin' variables? HOT 5
- Add reader with support for secret files HOT 1
- loading a .env file from outside the webspace seem to not work
- php 8.2 function getenv() not set HOT 1
- Please dont use $_SERVER HOT 1
- Load AWS system environments HOT 4
- symfony/dotenv Correlation HOT 1
- PHP version 7.4 HOT 1
- How does this help with php_value in .htaccess?
- Is there anyway to use sections created in the .env file? HOT 4
- Fatal error: Uncaught Error: Class "Dotenv\Dotenv" not found in HOT 2
- Can one use Heredoc syntax for multi-line strings? HOT 1
- Failed to parse dotenv file due to unexpected whitespace HOT 1
- Inconsistent result when calling `$this->dotenv->load()` multiple times from PHPUnit
- Simple script doesn't work. HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from phpdotenv.