Symfony console commands turn project maintenance work into named tasks that run through bin/console. They fit imports, reports, cleanup routines, and one-off administration jobs where application services and configuration should be available from the terminal.

A Symfony Flex project can use MakerBundle to create the command class skeleton. Symfony stores each console name in the #[AsCommand] attribute, and service autoconfiguration registers command classes from src/Command in the application console.

Start from a Symfony project with dependencies installed and MakerBundle available in the development environment. After editing the generated class, refresh the cache, list the application command namespace, and run the command once to confirm Symfony discovers and executes it.

Steps to create a Symfony console command:

  1. Open a terminal in the Symfony project root that contains bin/console.
  2. Generate the command class with MakerBundle.
    $ php bin/console make:command app:report:daily
     created: src/Command/ReportDailyCommand.php
     
      Success!
     
     Next: open your new command class and customize it!
     Find the documentation at https://symfony.com/doc/current/console.html

    If make:command is missing, add symfony/maker-bundle to the development dependencies before using the generator.

  3. Open the generated command class.
    $ vi src/Command/ReportDailyCommand.php
  4. Replace the placeholder body with the command behavior.
    ReportDailyCommand.php
    <?php
     
    namespace App\Command;
     
    use Symfony\Component\Console\Attribute\AsCommand;
    use Symfony\Component\Console\Command\Command;
    use Symfony\Component\Console\Input\InputInterface;
    use Symfony\Component\Console\Output\OutputInterface;
    use Symfony\Component\Console\Style\SymfonyStyle;
     
    #[AsCommand(
        name: 'app:report:daily',
        description: 'Queue the daily catalog report.',
    )]
    final class ReportDailyCommand extends Command
    {
        protected function execute(InputInterface $input, OutputInterface $output): int
        {
            $io = new SymfonyStyle($input, $output);
     
            $io->writeln('Daily report queued for catalog orders.');
     
            return Command::SUCCESS;
        }
    }

    The Command::SUCCESS return value exits with status code 0, which shell schedulers and deployment tools treat as success.

  5. Refresh the development cache so Symfony rebuilds the service container.
    $ php bin/console cache:clear
     
     // Clearing the cache for the dev environment with debug true
     
     [OK] Cache for the "dev" environment (debug=true) was successfully cleared.

    Clearing the development cache prevents an older container from hiding a newly created service class.
    Related: How to clear Symfony cache

  6. List the application command namespace.
    $ php bin/console list app
    Symfony v8.1.0 (env: dev, debug: true)
    ##### snipped #####
    Available commands for the "app" namespace:
      app:report:daily  Queue the daily catalog report.

    The visible command name and description come from the #[AsCommand] attribute in ReportDailyCommand.php.

  7. Run the new command.
    $ php bin/console app:report:daily
    Daily report queued for catalog orders.