Magento 2 Experten — Hyvä Theme, Tailwind CSS & SEO aus einer Hand ›

Creating Your Own Console Commands

Creating Your Own Console Commands

~14 Min. Lesezeit Zuletzt aktualisiert am August 8, 2026

We've used bin/console since chapter 3 for Symfony's OWN commands – now let's build our FIRST custom command: listing overdue tasks from chapter 24.

Generating a command

php bin/console make:command app:list-overdue-tasks
src/Command/ListOverdueTasksCommand.php
<?php

declare(strict_types=1);

namespace App\Command;

use App\Repository\TaskRepository;
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:list-overdue-tasks',
    description: 'Lists all overdue tasks',
)]
class ListOverdueTasksCommand extends Command
{
    public function __construct(
        private readonly TaskRepository $taskRepository,
    ) {
        parent::__construct();
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $io = new SymfonyStyle($input, $output);
        $tasks = $this->taskRepository->findOverdueTasks();

        if (count($tasks) === 0) {
            $io->success('No overdue tasks!');

            return Command::SUCCESS;
        }

        $io->warning(sprintf('%d overdue task(s) found:', count($tasks)));

        foreach ($tasks as $task) {
            $io->writeln(sprintf(
                '- %s (due: %s)',
                $task->getTitle(),
                $task->getDueAt()?->format('Y-m-d') ?? 'unknown',
            ));
        }

        return Command::SUCCESS;
    }
}

EXACTLY like controllers (chapter 8): the __construct() parameter TaskRepository gets resolved automatically via autowiring – console commands are, like EVERYTHING in this course, ORDINARY services (chapters 32-34).

Running the command

php bin/console app:list-overdue-tasks

SymfonyStyle: consistent, formatted terminal output

  • $io->success(...) – green-highlighted success message.
  • $io->warning(...) – yellow-highlighted warning.
  • $io->error(...) – red-highlighted error message.
  • $io->table(...) – formatted table (useful for structured overviews).
  • $io->progressBar(...) – a progress bar for longer-running operations.

SymfonyStyle is the RECOMMENDED way to communicate with the terminal – compared to raw $output->writeln(...), it ensures a consistent, professional look ACROSS all of a project's commands.

Understanding exit codes: Command::SUCCESS and Command::FAILURE

execute()'s return value becomes the actual process exit code – DECISIVE for automation (shell scripts, CI/CD, chapter 41's cron jobs usually check this value):

return Command::SUCCESS; // exit code 0 - all good
return Command::FAILURE; // exit code 1 - something failed
return Command::INVALID; // exit code 2 - wrong input/usage
php bin/console app:list-overdue-tasks
echo $?  # shows the last statement's exit code - 0 means success

Tipp: In a shell script or CI/CD context ("run this command, and abort the whole deployment process on error"), the exit code is the ONLY thing automation relies on – a command that ALWAYS returns Command::SUCCESS, even on an internal error, would make problems INVISIBLE.