Closed
Description
Symfony version(s) affected
6.0.0 6.1.x-dev
Description
Consider my method: Command::configure
:
protected function configure(): void
{
$this->setName('app:admin:create')
->setDescription('Creates a new admin user')
->addArgument('username', InputArgument::REQUIRED, 'Sets the username of the user to create')
->addArgument('password', InputArgument::OPTIONAL, 'Sets the initial password for the user', fn() => $this->passwordGenerator->generatePassword());
}
This leads to the following error:
Symfony\Component\Console\Input\InputArgument::__construct(): Argument #4 ($default) must be of type array|string|int|float|bool|null, Closure given
How to reproduce
See code in description
Running bin/console --version
was enough to trigger the type error.
Take a skeleton 6.0 symfony project, include the following snippet, and try running bin/console cache:clear -vvv
for full details.
<?php
namespace App\Command;
class PasswordGenerator
{
public function generatePassword(): string
{
return 'password';
}
}
use Symfony\Component\Console\Command\Command;
class AppCommand extends Command
private PasswordGenerator $passwordGenerator;
protected function configure(): void
{
$this->passwordGenerator = new PasswordGenerator();
$this->setName('app:admin:create')
->setDescription('Creates a new admin user')
->addArgument('username', InputArgument::REQUIRED, 'Sets the username of the user to create')
->addArgument('password', InputArgument::OPTIONAL, 'Sets the initial password for the user', fn() => $this->passwordGenerator->generatePassword());
}
}
Possible Solution
I'm actually not sure about the best way to approach this, a few ideas popped into my mind:
- Widen the parameter type in
InputArgument::__construct
to accept mixed (no BC break) - Narrow the parameter type in
Command::addArgument
to also only acceptstring|bool|int|float|array|null
(introduces BC break) - Narrow the parameter annotation as in the solution above, but don't change the actual function signature and then trigger a deprecation warning.
- Validate the passed
$defaultValue
for the correct type and throw anInvalidArgumentException
in case it's anobject|resource|closure
. This keeps BC in the function signatures. But it doesn't really accomplish much.
Additional Context
Would be happy to work out a solution and submit a PR if this is indeed something to be fixed.
Also, I am well aware I can transform my closure into a callable array and have it work, but the point of this issue is to point out the inconsistency in argument types.