8000 [12.x] Typed getters for Env helper by arttiger · Pull Request #55658 · laravel/framework · GitHub
[go: up one dir, main page]

Skip to content

[12.x] Typed getters for Env helper #55658

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from

Conversation

arttiger
Copy link
@arttiger arttiger commented May 6, 2025

Added methods

  • Env::string(string $key, $default = null): string
  • Env::integer(string $key, $default = null): int
  • Env::float(string $key, $default = null): float
  • Env::boolean(string $key, $default = null): bool
  • Env::array(string $key, $default = null): array

As exist on the Config facede and Arr helper.

Comment on lines 131 to 135
if (! is_string($value)) {
throw new InvalidArgumentException(
sprintf('Environment value for key [%s] must be a string, %s given.', $key, gettype($value))
);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to move these to a helper like

<?php

namespace Illuminate\Support\Typed;

if (! function_exists('check_type')) {
    /**
     * @param 'string'|'int'|'integer'|'long'|'bool'|'boolean'|'float'|'double'|'real' $type
     * @throws \InvalidArgumentException
     */
    function check_type(mixed $value, callable $checkFn, string $type, string $key, string $group = 'variable'): mixed
    {
        throw_unless(
            $checkFn($value),
            InvalidArgumentException::class,
            sprintf('%s value for key [%s] must be a %s, %s given.',
                $group,
                $key,
                $type,
                gettype($value)),
            ),
        );

        return $value; 
    }
}

if (! function_exists('check_string')) {
    function check_string(mixed $value, string $key, string $group = 'variable'): string
    {
        return check_type($value, is_string(...), 'string', $key, $group);
    }
}

or even

<?php

namespace Illuminate\Support\Typed;

use InvalidArgumentException;

if (! function_exists('check_type')) {
    /**
     * @param 'string'|'int'|'integer'|'long'|'bool'|'boolean'|'float'|'double'|'real' $type
     * @throws \InvalidArgumentException
     */
    function check_type(mixed $value, string $type, string $key, string $group = 'variable'): mixed
    {
        $isValid = match ($type) {
            'string' => is_string($value),
            'int', 'integer', 'long' => is_int($value),
            'bool', 'boolean' => is_array($value),
            'float', 'double', 'real' => is_float($value),
            default => throw new InvalidArgumentException('Type "'. $type . '" is not supported. Use one of: string, int, integer, long, bool, boolean, float, double, real')
        };

        throw_unless(
            $isValid,
            InvalidArgumentException::class,
            sprintf('%s value for key [%s] must be a %s, %s given.',
                $group,
                $key,
                $type,
                gettype($value)),
            ),
        );

        return $value; 
    }
}

This could be reused for the array getters (#55567) as well as those for the config (#50140)

Copy link
Author
@arttiger arttiger May 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great idea! However, instead of is_int, maybe it’s better to use filter_var with FILTER_VALIDATE_INT?
Since values from .env (even if you set BANK_NUMBER=12345) are always strings, FILTER_VALIDATE_INT will properly check if the value can actually be cast to an integer. Same applies to is_float - it might be better to use FILTER_VALIDATE_FLOAT in this case.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right 👍🏻

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ready👌

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding it—love it 😍 👍🏻

@arttiger arttiger changed the title Typed getters for Env helper [12.x] Typed getters for Env helper May 6, 2025
Comment on lines 129 to 133
$value = Env::get($key, $default);

if (! is_string($value)) {
throw new InvalidArgumentException(
sprintf('Environment value for key [%s] must be a string, %s given.', $key, gettype($value))
);
}
check_type($value, 'string', $key, 'Environment');

return $value;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could also simplify this even further:

Suggested change
$value = Env::get($key, $default);
if (! is_string($value)) {
throw new InvalidArgumentException(
sprintf('Environment value for key [%s] must be a string, %s given.', $key, gettype($value))
);
}
check_type($value, 'string', $key, 'Environment');
return $value;
return check_type($value, 'string', $key, 'Environment');

or

Suggested change
8000
$value = Env::get($key, $default);
if (! is_string($value)) {
throw new InvalidArgumentException(
sprintf('Environment value for key [%s] must be a string, %s given.', $key, gettype($value))
);
}
check_type($value, 'string', $key, 'Environment');
return $value;
return check_type(
Env::get($key, $default),
'string',
$key,
'Environment'
);

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the code review, this really looks cleaner.

@@ -216,19 +200,15 @@ public static function array(string $key, $default = null): array
{
$value = Env::get($key, $default);

if ($value === null) {
if (is_null($value)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason, you changed to a function call?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was my mistake. I’ll revert it to the previous version, thanks for catching that.

Comment on lines 195 to 203
if ($value === null) {
return [];
}

if (is_string($value)) {
return array_map('trim', explode(',', $value));
}

check_type($value, 'array', $key, 'Environment');

return $value;
return check_type($value, 'array', $key, 'Environment');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want, even this can be shortened:

Suggested change
8000
if ($value === null) {
return [];
}
if (is_string($value)) {
return array_map('trim', explode(',', $value));
}
check_type($value, 'array', $key, 'Environment');
return $value;
return check_type($value, 'array', $key, 'Environment');
return match (true) {
$value === null => [],
is_string($value) => array_map('trim', explode(',', $value)),
default => check_type($value, 'array', $key, 'Environment'),
};

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you 😉 Already change💪

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome! Thanks a lot 👍🏻

@taylorotwell
Copy link
Member

Thanks for your pull request to Laravel!

Unfortunately, I'm going to delay merging this code for now. To preserve our ability to adequately maintain the framework, we need to be very careful regarding the amount of code we include.

If applicable, please consider releasing your code as a package so that the community can still take advantage of your contributions!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants
0