Skip to content

Conversation

yceruto
Copy link
Member

@yceruto yceruto commented Aug 21, 2025

Q A
Branch? 7.4
Bug fix? no
New feature? yes
Deprecations? no
Issues -
License MIT

This PR introduces support for using DTOs as command inputs in Console commands through a new #[Input] attribute. Especially useful for commands with many arguments and options, as it prevents cluttering the __invoke() method with lengthy parameter lists and their associated attributes and options.

Example:

class UserDto
{
    #[Argument]
    public string $email {
        set => strtolower($value);
    }

    #[Argument]
    public string $password;

    #[Option]
    public bool $admin = false;
}

The command's arguments and options are defined directly on the DTO's properties. These properties need to be public, and now you can use property hooks to normalize the value when necessary.

#[AsCommand('app:user:create')]
class CreateUserCommand
{
    public function __invoke(#[Input] UserDto $user): int
    {
        // Create new user with $user->email, $user->password, etc.

        return 0;
    }
}
$ bin/console help app:create-user
Usage:
  app:create-user [options] [--] <email> <password>

Arguments:
  email
  password

Options:
      --admin|--no-admin

✨ Input validation and handling become naturally simpler 😉

It also supports splitting the command input across multiple DTOs (e.g. grouping inputs into UserDto and GroupDto), or more complex structured like nested DTOs:

class UserDto
{
    #[Argument]
    public string $email;

    #[Argument]
    public string $password;

    #[Option]
    public bool $active = true;

    #[Input]
    public ProfileDto $profile;
}

class ProfileDto
{
    #[Argument]
    public string $name;

    #[Option]
    public ?string $phone = null;
}

Thus, we can model the command input while defining its arguments and options. Here's the resulting usage output from the previous definition:

Usage:
  app:create-user [options] [--] <email> <password> <name>

Arguments:
  email                     
  password                  
  name                      

Options:
      --active|--no-active  
      --phone=PHONE

Food for Future PRs

  • Automatic validation (if Validator component is installed) with proper error output from the violation list.
  • Defers input interactivity (i.e. the Command::interact() method) to the DTO class.

Cheers!

@yceruto yceruto requested a review from chalasr as a code owner August 21, 2025 00:24
@carsonbot carsonbot added this to the 7.4 milestone Aug 21, 2025
@yceruto yceruto added the DX DX = Developer eXperience (anything that improves the experience of using Symfony) label Aug 21, 2025
@chalasr
Copy link
Member

chalasr commented Aug 21, 2025

Nice, it was on my list!

@yceruto
Copy link
Member Author

yceruto commented Aug 21, 2025

Nice, it was on my list!

it seems we shared the same list at some point :)

@yceruto yceruto force-pushed the console_input_attribute branch from 1a792fb to 0ed04d7 Compare August 22, 2025 21:53
@yceruto
Copy link
Member Author

yceruto commented Aug 22, 2025

Appreciate the feedback @nicolas-grekas 🙏, all points have been addressed.

@yceruto yceruto force-pushed the console_input_attribute branch 3 times, most recently from 6cdbc96 to 84d092f Compare August 23, 2025 09:00
@yceruto yceruto force-pushed the console_input_attribute branch from 84d092f to 28f49fe Compare August 25, 2025 13:31
Copy link
Member

@chalasr chalasr left a comment

Choose a reason for hiding this comment

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

Failures unrelated :shipit:

@yceruto
Copy link
Member Author

yceruto commented Aug 25, 2025

The Fabbot failures are false positives, are there any other failures I might have overlooked?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Console DX DX = Developer eXperience (anything that improves the experience of using Symfony) Feature Status: Reviewed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants