Giter Site home page Giter Site logo

Detect and convert types about phpdotenv HOT 38 CLOSED

vlucas avatar vlucas commented on May 2, 2024 4
Detect and convert types

from phpdotenv.

Comments (38)

drmax24 avatar drmax24 commented on May 2, 2024 15

such constructions will kill php in a meantime

filter_var(getenv('APP_DEBUG'), FILTER_VALIDATE_BOOLEAN)

Instead of executing the simple command as in a normal language you start to add useless sophistication

"very simple" filter_var(getenv('APP_DEBUG'), FILTER_VALIDATE_BOOLEAN)
No junior guy can write this from his head and senior guys are senior just because they keep in mind this. So senior php programmer is senior because he stores 80% of the useless information in his mind. This is where you lead this platform with your popular package.

So simple and elegant! Every php line should be like this! Keep up good work!

$kernel = new AppKernel(
    filter_var(getenv('APP_ENV')) ?? 'dev',
    filter_var(getenv('APP_DEBUG'), FILTER_VALIDATE_BOOLEAN) ?? false
);

My comments to this code would be:
Php is doomed

from phpdotenv.

natsu90 avatar natsu90 commented on May 2, 2024 6

I have to use following solution;

filter_var(getenv('DB_DEBUG'), FILTER_VALIDATE_BOOLEAN)

refs: http://stackoverflow.com/a/10645030

from phpdotenv.

oscarotero avatar oscarotero commented on May 2, 2024 4

Maybe, a way to keep backward compatibility is make this behaviour optional. For example:

$dotenv->load(); // do not convert types
$dotenv->load(true); // convert types

from phpdotenv.

patricknelson avatar patricknelson commented on May 2, 2024 2

Environment variables really don't work quite the same way as most typical languages when it comes to booleans, since they don't really exist in the traditional sense. Personally, I'd shoot for broader compatibility and just embrace how environment variables work.

An elegant way to do this that "just works" even if you're not using dotenv would be to also leverage PHP's type juggling abilities, and simply avoid using true or false in your environment variables entirely, like so:

# False:
MY_VAR=0
MY_VAR=
# ... or just don't define it...

... then...

if ((int) getenv('MY_VAR')) {
    // ... won't run.
} else {
    // ... always runs.
}

In every scenario above, (int) getenv('MY_VAR') will always cast to 0. I know I'll be using this method since I'm also dockerizing/containerizing/kubernetes-er-izing my application, so .env won't exist and this library can't be used anymore anyway. Just thought I'd throw this technique out there as an alternative suggestion!

from phpdotenv.

GrahamCampbell avatar GrahamCampbell commented on May 2, 2024 2

Environment variables are strings. The type of an environment variable repository is array<string, string>. Anything else is not doing "environment variables". It's some other kind out out of scope transformation.

from phpdotenv.

oscarotero avatar oscarotero commented on May 2, 2024 1

Currently it returns false if the variable is not defined, but I don't get the values true or false converted to booleans.
In the tests I can see this fixture and the expected value is string, not boolean.

from phpdotenv.

oscarotero avatar oscarotero commented on May 2, 2024 1

Here's how laravel handle this: https://github.com/laravel/framework/blob/8c614010648bffb8bc24c3b532db08619e9a5983/src/Illuminate/Foundation/helpers.php#L626

from phpdotenv.

oscarotero avatar oscarotero commented on May 2, 2024 1

Well, thinking about this, maybe this is not good idea and it's better the way laravel handles this, using a custom function to consume the environment variables. So if you want to convert the values, use the custom function and if you don't, use getenv.

var_dump(env('MY_BOOLEAN_VALUE')); // bool(true)
var_dump(getenv('MY_BOOLEAN_VALUE')); // string(4) "true"

from phpdotenv.

GrahamCampbell avatar GrahamCampbell commented on May 2, 2024

We do this don't we?

from phpdotenv.

GrahamCampbell avatar GrahamCampbell commented on May 2, 2024

We have tests that prove this works.

from phpdotenv.

GrahamCampbell avatar GrahamCampbell commented on May 2, 2024

What version?

from phpdotenv.

GrahamCampbell avatar GrahamCampbell commented on May 2, 2024

Hmmm.

from phpdotenv.

oscarotero avatar oscarotero commented on May 2, 2024

The latest dev version (2.1@dev)

from phpdotenv.

GrahamCampbell avatar GrahamCampbell commented on May 2, 2024

NB, 2.0.x is the latest version. I don't recommend using an unreleased version as it's still subject to change.

from phpdotenv.

oscarotero avatar oscarotero commented on May 2, 2024

Yes, you're right šŸ˜„ 2.0.1 does the same.

from phpdotenv.

vlucas avatar vlucas commented on May 2, 2024

@GrahamCampbell These are converted in Laravel, but not in phpdotenv itself. The only reason this is not done in phpdotenv is because I originally tried to keep it as close to shell as possible, and in PHP ENV variables, everything is a string. I am not opposed to adding this functionality in, though - and we can probably even just grab the code from Laravel that does this and put it in phpdotenv.

from phpdotenv.

GrahamCampbell avatar GrahamCampbell commented on May 2, 2024

Yeh, but laravel makes it impossible to have null as a string, which isn't ideal.

from phpdotenv.

oscarotero avatar oscarotero commented on May 2, 2024

Yes, I think this should be handled when loading values, so it's possible to differentiate between null and "null".

from phpdotenv.

vlucas avatar vlucas commented on May 2, 2024

So if you want to convert the values, use the custom function and if you don't, use getenv

This approach is above the level of phpdotenv, since it does not provide any convenience methods by itself. To me, this is an argument supporting keeping things they way they are.

from phpdotenv.

GrahamCampbell avatar GrahamCampbell commented on May 2, 2024

Yeh, we probably don't need to change anything tbh.

from phpdotenv.

 avatar commented on May 2, 2024

I've been wanting something like this, but probably alongside the current allowedValues or required. basically setting a schema of acceptable variables and their values

from phpdotenv.

barbushin avatar barbushin commented on May 2, 2024

Same problem #129

from phpdotenv.

vlucas avatar vlucas commented on May 2, 2024

There is a solution in #121. We need to get this added to the README.

from phpdotenv.

jpcercal avatar jpcercal commented on May 2, 2024

@vlucas thanks guy, i am happy to help.

from phpdotenv.

GrahamCampbell avatar GrahamCampbell commented on May 2, 2024

Leaving this for people to wrap.

from phpdotenv.

bs-thomas avatar bs-thomas commented on May 2, 2024

@drmax24 I agree with you.

What got me here is because of this problem. Actually I must say I do not quite agree on automated conversions inside dotenv file.

I use Laravel, and including phinx for the independent library for database migrations. There is a problem caused indirectly because of this mindset.

cakephp/cakephp#12669

from phpdotenv.

llbbl avatar llbbl commented on May 2, 2024

So where did we land on this. If this isn't going to be a planned feature can we at least update README to explicitly say that booleans must be handled in user code.

from phpdotenv.

GrahamCampbell avatar GrahamCampbell commented on May 2, 2024

https://www.php.net/manual/en/function.getenv.php has return type string|false. One cannot do type conversion and still call what you are doing environment variables.

from phpdotenv.

llbbl avatar llbbl commented on May 2, 2024

@GrahamCampbell do you happen to know where the env function ended up in Laravel 8+ ? Are you open to changing the language on README that talks about getenv and if the user even cares about running php with thread safety (mod Apache). Maybe a link to a SO that explains thread safety etc, would probably help a lot of people.

from phpdotenv.

GrahamCampbell avatar GrahamCampbell commented on May 2, 2024

Yes, the env function source code is: https://github.com/laravel/framework/blob/8.x/src/Illuminate/Support/Env.php.

from phpdotenv.

llbbl avatar llbbl commented on May 2, 2024

@GrahamCampbell Thanks for the link! Any thoughts on the other question? Happy to take a crack at clearing up the Readme. I don't want to waste time unless you are open to it.

from phpdotenv.

thexpand avatar thexpand commented on May 2, 2024

And this issue is closed, because?

EDIT: Sorry, I missed @GrahamCampbell's comment about the return type of getenv(). Now I get it. Thanks anyway :)

from phpdotenv.

llbbl avatar llbbl commented on May 2, 2024

And this issue is closed, because?

EDIT: Sorry, I missed @GrahamCampbell's comment about the return type of getenv(). Now I get it. Thanks anyway :)

vlucas sounded like he was not opposed to (at least optionally) replicating Laravel return types but Graham most definitely is. I tried pushing for updated Readme to at least explain their reasoning and hopefully remind people coming back to this library that it doesn't work how you are probably expecting.

from phpdotenv.

rodurma avatar rodurma commented on May 2, 2024

You can just use

$active = $_ENV['SOME_CONFIG'] == 'true';

from phpdotenv.

patricknelson avatar patricknelson commented on May 2, 2024

But you shouldnā€™t, thatā€™d be crossing concerns and gets confusing. Just treat environment variables as strings 100% of the time, because thatā€™s what they are. If you need a number or need a quick way to interpret an environment variable as a Boolean, the simplest thing to do is just type cast it to int. See my example above for a bit more explanation šŸ˜„

from phpdotenv.

CodeByZach avatar CodeByZach commented on May 2, 2024

Can someone explain to me why something as simple as the absence of quotations couldn't be used to indicate a non-string data type? I believe this, along with the ability to specify default values, would be a welcome improvement.

variable_1="apple" (string)
variable_2="true" (string)
variable_3=true (bool)
variable_4="24" (string)
variable_5=24 (int)

from phpdotenv.

patricknelson avatar patricknelson commented on May 2, 2024

If you read the thread above, several of us give the explanation for this: Environment variables are strings.

Environment variables can come from several sources, not just .env. Not only that, but in each of those sources, including/excluding quotes at definition time doesnā€™t change their data type once accessed in those other hybrid environments (e.g. bash, docker, etc). Since phpdotenv is an abstraction layer that operates on top of this would likely need some method by which to do the same level of type interpretation across all forms of input, not just .env and Iā€™m not sure thatā€™s possible. For example, once itā€™s reached getenv(), $_ENV and $_SERVER, Iā€™m not sure itā€™s possible to correctly infer the originally defined data type (as it was defined, i.e. with or without quotes, like your example). So, why treat .env differently? I assume this would cause unexpected behavior and introduce more bugs than benefits.

But thatā€™s just my opinion on why this is probably not being done. šŸ˜Š

from phpdotenv.

patricknelson avatar patricknelson commented on May 2, 2024

That saidā€¦ I could see phpdotenv possibly adding this as a feature (disabled by default) but it could only work in some limited situations since it does take these values from multiple sources, this would likely happen after variables coalesced together (unless this feature explicitly only applies to .env where we have access to the original definition and the developer has explicitly opted into interpreting missing quotes as a string/bool/etc).

For example, it could logically interpret ā€falseā€ (string) as false (bool) but it would be ambiguous to interpret ā€ā€ (empty string) as a bool representing false and would still need some custom application layer logic (which for example would have an understanding of the variable itself in order to make that decision, i.e. it already knows that particular var should be a bool).

from phpdotenv.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    šŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ā¤ļø Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.