Description
Description
right now, ParameterBag
has only a few getter options for fetching values:
get(): mixed
getAlpha(): string
getAlnum(): string
getDigits(): string
getInt(): int
getBoolean(): bool
For those of us using static analyzers like PHPStan, we often find ourselves having to add a bunch of manual type checking code to ensure that the parameter we are fetching is of a specified type. I see two main problems/annoyances here:
- In terms of fetching configuration parameters, this often means implementing type checks to ensure that the returned value is indeed the type that we already know it to be.
- In terms of fetching Request and Query parameters, we have to contend with the fact that forms cast everything to strings, which means fetching a mixed result from
get()
, type checking it as a string, then casting it to the actual type it should be.
The two exclusions here are getInt()
and getBoolean()
. Furthermore, getInt()
is potentially dangerous with it's naked cast, as you may be fetching 5.5
or "5.5"
and it will return 5
instead of throwing an exception.
Example
Would the community find it valuable to have many more typed getters along the lines of getInt()
and getBoolean()
that return validated parameters returned as their proper type? I'm thinking things along the lines of:
getArray(): array
getArrayOrNull(): ?array
getBoolean(): bool
getBooleanOrNull(): ?bool
getInt(): int
getIntOrNull(): ?int
getFloat(): float
getFloatOrNull(): ?float
getString(): string
getStringOrNull(): ?string
here are some quick examples, including an improvement of getInt()
:
protected function getInt(string $key, int $default = 0): int
{
if (is_int($value = $this->get($key, $default))) {
return $value;
}
throw $this->getException("int", $value);
}
protected function getIntOrNull(string $key, int $default = 0): ?int
{
$value = $this->get($key, $default)
if (is_int($value) || is_null($value)) {
return $value;
}
throw $this->getException("int|null", $value);
}
protected function getString(string $key, string $default = ""): string
{
if (is_string($value = $this->get($key, $default))) {
return $value;
}
throw $this->getException("string", $value);
}
protected function getStringOrNull(string $key, string $default = ""): ?string
{
$value = $this->get($key, $default)
if (is_string($value) || is_null($value)) {
return $value;
}
throw $this->getException("string|null", $value);
}
/** @param mixed $value */
private function getException(string $expected, $value): TypeException
{
return new TypeException("expected parameter of type $expected but found " . gettype($value));
}
If the Symfony developers think this is a good idea and/or community members want it, I can work on a PR. I just didn't want to do the work only to find that this discussion has already been had, or there's something I'm missing, or such a feature wouldn't be accepted by Symfony.
And perhaps this logic shouldn't live in ParameterBag
. Maybe it warrants a new Typer
object that can be recycled all over the place. I currently have this type of logic implemented on a Trait that I include as needed.