La console avec Symfony 6

Le framework Symfony fournit de nombreuses commandes via le script bin/console (par exemple, la commande bien connue bin/console cache:clear). Ces commandes sont créées avec le composant Console. Vous pouvez également l’utiliser pour créer vos propres commandes.

La Console : APP_ENV & APP_DEBUG

Les commandes de la console s’exécutent dans l’environnement défini dans la variable APP_ENV du fichier .env, qui est dev par défaut. Elle lit également la valeur APP_DEBUG pour activer ou désactiver le mode « débogage » (la valeur par défaut est 1, ce qui correspond à « on »).

Pour exécuter la commande dans un autre environnement ou en mode débogage, modifiez les valeurs de APP_ENV et APP_DEBUG.

Création d’une commande

Les commandes sont définies dans des classes qui étendent Command. Par exemple, vous pouvez vouloir une commande pour créer un utilisateur :

// src/Command/CreateUserCommand.php
namespace App\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class CreateUserCommand extends Command
{
    // the name of the command (the part after "bin/console")
    protected static $defaultName = 'app:create-user';

    protected function configure(): void
    {
        // ...
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        // ... put here the code to create the user

        // this method must return an integer number with the "exit status code"
        // of the command. You can also use these constants to make code more readable

        // return this if there was no problem running the command
        // (it's equivalent to returning int(0))
        return Command::SUCCESS;

        // or return this if some error happened during the execution
        // (it's equivalent to returning int(1))
        // return Command::FAILURE;

        // or return this to indicate incorrect command usage; e.g. invalid options
        // or missing arguments (it's equivalent to returning int(2))
        // return Command::INVALID
    }
}

Configuration de la commande

Vous pouvez éventuellement définir une description, un message d’aide ainsi que les options d’entrée et les arguments :

// ...
// the command description shown when running "php bin/console list"
protected static $defaultDescription = 'Creates a new user.';

// ...
protected function configure(): void
{
    $this
        // If you don't like using the $defaultDescription static property,
        // you can also define the short description using this method:
        // ->setDescription('...')

        // the command help shown when running the command with the "--help" option
        ->setHelp('This command allows you to create a user...')
    ;
}

Définir la propriété statique $defaultDescription au lieu d’utiliser la méthode setDescription() permet d’obtenir la description de la commande sans instancier sa classe. Cela permet à la commande php bin/console list de s’exécuter beaucoup plus rapidement.

Si vous souhaitez que la commande list s’exécute toujours rapidement, ajoutez-lui l’option –short (php bin/console list –short). Cela évitera d’instancier des classes de commandes, mais n’affichera aucune description pour les commandes qui utilisent la méthode setDescription() au lieu de la propriété statique.

La méthode configure() est appelée automatiquement à la fin du constructeur de la commande. Si votre commande définit son propre constructeur, définissez d’abord les propriétés et appelez ensuite le constructeur parent, afin de rendre ces propriétés disponibles dans la méthode configure() :

// ...
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;

class CreateUserCommand extends Command
{
    // ...

    public function __construct(bool $requirePassword = false)
    {
        // best practices recommend to call the parent constructor first and
        // then set your own properties. That wouldn't work in this case
        // because configure() needs the properties set in this constructor
        $this->requirePassword = $requirePassword;

        parent::__construct();
    }

    protected function configure(): void
    {
        $this
            // ...
            ->addArgument('password', $this->requirePassword ? InputArgument::REQUIRED : InputArgument::OPTIONAL, 'User password')
        ;
    }
}

Enregistrement de la commande

Les commandes Symfony doivent être enregistrées en tant que services et marquées avec la balise console.command. Si vous utilisez la configuration par défaut de services.yaml, cela est déjà fait pour vous, grâce à l’autoconfiguration.

Exécution de la commande

Après avoir configuré et enregistré la commande, vous pouvez l’exécuter dans le terminal :

php bin/console app:create-user

Comme vous pouvez vous y attendre, cette commande ne fera rien puisque vous n’avez pas encore écrit de logique. Ajoutez votre propre logique dans la méthode execute().

Sortie console
La méthode execute() a accès au flux de sortie pour écrire des messages dans la console :

// ...
protected function execute(InputInterface $input, OutputInterface $output): int
{
    // outputs multiple lines to the console (adding "\n" at the end of each line)
    $output->writeln([
        'User Creator',
        '============',
        '',
    ]);

    // the value returned by someMethod() can be an iterator (https://secure.php.net/iterator)
    // that generates and returns the messages with the 'yield' PHP keyword
    $output->writeln($this->someMethod());

    // outputs a message followed by a "\n"
    $output->writeln('Whoa!');

    // outputs a message without adding a "\n" at the end of the line
    $output->write('You are about to ');
    $output->write('create a user.');

    return Command::SUCCESS;
}

Maintenant, essayez d’exécuter la commande :

php bin/console app:create-user
User Creator
============

Whoa!
You are about to create a user.