Attention
TYPO3 v11 has reached end-of-life as of October 31th 2024 and is no longer being maintained. Use the version switcher on the top left of this page to select documentation for a supported version of TYPO3.
Need more time before upgrading? You can purchase Extended Long Term Support (ELTS) for TYPO3 v11 here: TYPO3 ELTS.
Tutorial
Create a console command from scratch
A console command is always situated in an extension. If you want to create one, kickstart a custom extension or use your sitepackage extension.
Creating a basic command
The extension kickstarter "Make" offers a convenient console command that creates a new command in an extension of your choice: Create a new console command with "Make". You can use "Make" to create a console command even if your extension was created by different means.
This command can be found in the Examples extension.
1. Register the command
Register the command in Configuration/
by adding the service
definition for your class as tag console.
:
services:
_defaults:
autowire: true
autoconfigure: true
public: false
T3docs\Examples\:
resource: '../Classes/*'
exclude: '../Classes/Domain/Model/*'
T3docs\Examples\Command\DoSomethingCommand:
tags:
- name: console.command
command: 'examples:dosomething'
description: 'A command that does nothing and always succeeds.'
# Also an alias for the command can be configured
- name: console.command
command: 'examples:dosomethingalias'
alias: true
The following attributes are available:
command
- The name under which the command is available.
description
- Give a short description. It will be displayed in the list of commands and the help information of the command.
schedulable
- By default, a command can be used in the scheduler, too. This can be disabled by setting
schedulable
tofalse
. hidden
- A command can be hidden from the command list by setting
hidden
totrue
. alias
- A command can be made available under a different name. Set to
true
, if your command name is an alias.
Note
Despite using autoconfigure: true
the commands
have to be explicitly defined in Configuration/
. It
is recommended to always supply a description, otherwise there is
an empty space in the list of commands.
2. Create the command class
Create a class called Do
extending
\Symfony\
.
<?php
declare(strict_types=1);
namespace T3docs\Examples\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class DoSomethingCommand extends Command
{
protected function configure(): void
{
$this->setHelp('This command does nothing. It always succeeds.');
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
// Do awesome stuff
return Command::SUCCESS;
}
}
The following two methods should be overridden by your class:
configure
() - As the name would suggest, allows to configure the command. The method allows to add a help text and/or define arguments and options.
execute
() - Contains the logic when executing the command. Must
return an integer. It is considered best practice to
return the constants
Command::
orSUCCESS Command::
.FAILURE
See also
A detailed description and an example can be found in the Symfony Command Documentation.
3. Run the command
The above example can be run via command line:
vendor/bin/typo3 examples:dosomething
typo3/sysext/core/bin/typo3 examples:dosomething
The command will return without a message as it does nothing but stating it succeeded.
Note
If a newly created or changed command is not found, clear the cache:
vendor/bin/typo3 cache:flush
Create a command with arguments and interaction
Passing arguments
Since a command extends \Symfony\
,
it is possible to define arguments (ordered) and options (unordered) using the Symfony
command API. This is explained in depth on the following Symfony Documentation page:
Add an optional argument and an optional option to your command:
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
final class CreateWizardCommand extends Command
{
protected function configure(): void
{
$this
->setHelp('This command accepts arguments')
->addArgument(
'wizardName',
InputArgument::OPTIONAL,
'The wizard\'s name'
)
->addOption(
'brute-force',
'b',
InputOption::VALUE_NONE,
'Allow the "Wizard of Oz". You can use --brute-force or -b when running command'
);
}
}
This command takes one optional argument wizard
and one optional option,
which can be passed on the command line:
vendor/bin/typo3 examples:createwizard [-b] [wizardName]
typo3/sysext/core/bin/typo3 examples:createwizard [-b] [wizardName]
This argument can be retrieved with $input->get
, the options with
$input->get
, for example:
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use T3docs\Examples\Exception\InvalidWizardException;
final class CreateWizardCommand extends Command
{
protected function execute(
InputInterface $input,
OutputInterface $output
): int {
$io = new SymfonyStyle($input, $output);
$wizardName = $input->getArgument('wizardName');
$bruteForce = (bool)$input->getOption('brute-force');
try {
$this->doMagic($io, $wizardName, $bruteForce);
} catch (InvalidWizardException) {
return Command::FAILURE;
}
return Command::SUCCESS;
}
}
User interaction on the console
You can create a Symfony
console user interface from the
$input
and $output
parameters to the execute
function:
use Symfony\Component\Console\Style\SymfonyStyle;
final class CreateWizardCommand extends Command
{
protected function execute(
InputInterface $input,
OutputInterface $output
): int {
$io = new SymfonyStyle($input, $output);
// do some user interaction
return Command::SUCCESS;
}
}
The $io
variable can then be used to generate output and prompt for
input:
use Symfony\Component\Console\Style\SymfonyStyle;
use T3docs\Examples\Exception\InvalidWizardException;
final class CreateWizardCommand extends Command
{
private function doMagic(
SymfonyStyle $io,
mixed $wizardName,
bool $bruteForce
) {
$io->comment('Trying to create wizard ' . $wizardName . '...');
if ($wizardName === null) {
$wizardName = (string)$io->ask(
'Enter the wizard\'s name (e.g. "Gandalf the Grey")',
'Lord Voldermort'
);
}
if (!$bruteForce && $wizardName === 'Oz') {
$io->error('The Wizard of Oz is not allowed. Use --brute-force to allow it.');
throw new InvalidWizardException();
}
$io->success('The wizard ' . $wizardName . ' was created');
}
}
Dependency injection in console commands
You can use dependency injection (DI) in console commands by constructor injection or method injection:
use T3docs\Examples\Http\MeowInformationRequester;
final class MeowInformationCommand extends Command
{
public function __construct(
private readonly MeowInformationRequester $requester,
) {
parent::__construct();
}
}
Initialize backend user
A backend user can be initialized with this call inside execute
method:
use TYPO3\CMS\Core\Core\Bootstrap;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
final class DoBackendRelatedThingsCommand extends Command
{
protected function execute(InputInterface $input, OutputInterface $output): int
{
Bootstrap::initializeBackendAuthentication();
// Do backend related stuff
return Command::SUCCESS;
}
}
This is necessary when using DataHandler or other backend permission handling related tasks.
More information
- See implementation of existing command controllers in the Core:
typo3/
sysext/*/ Classes/ Command - Symfony Command Documentation
- Symfony Commands: Console Input (Arguments & Options)