Skip to main content

CLI command basics

Add-ons can provide custom CLI commands that run through cmd.php, which is useful for maintenance scripts and data imports.

Creating a command​

A command is a PHP class in your add-on's Cli/Command directory, such as src/addons/Vendor/AddOn/Cli/Command/Greet.php. XenForo scans this directory in every add-on, so no registration is required.

To scaffold the class, run xf-make:cli-command with development mode enabled:

Terminal
php cmd.php xf-make:cli-command Vendor/AddOn:Greet --description="Greets the user with a message."

This creates the class with configure() and execute() stubs. The class extends XF\Cli\Command\AbstractCommand, which sets up XenForo's output styles:

src/addons/Vendor/AddOn/Cli/Command/Greet.php
<?php

namespace Vendor\AddOn\Cli\Command;

use XF\Cli\Command\AbstractCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

class Greet extends AbstractCommand
{
// ...
}

Configuring the command​

The configure() method defines the command's name, description, and any arguments or options. Prefix the command name to avoid clashes with other add-ons.

protected function configure(): void
{
$this
->setName('vendor-addon:greet')
->setDescription('Greets the user with a message.')
->addArgument(
'name',
InputArgument::REQUIRED,
'The name of the person to greet.'
)
->addOption(
'yell',
'y',
InputOption::VALUE_NONE,
'If set, the greeting will be in uppercase.'
);
}
MethodPurpose
setName()Sets the name used to call the command.
setDescription()Sets the text shown in the command list.
addArgument()Defines a positional argument.
addOption()Defines an option, passed as --yell or -y.

Arguments and options use Symfony's mode constants, such as InputArgument::REQUIRED and InputOption::VALUE_NONE.

Implementing the command​

The execute() method runs when the command is called.

protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);

$name = $input->getArgument('name');
$yell = $input->getOption('yell');

$message = "Hello, $name!";
if ($yell)
{
$message = strtoupper($message);
}

$io->title('Greeting');
$io->table(['Field', 'Value'], [
['Name', $name],
['Yelling', $yell ? 'Yes' : 'No'],
]);

$io->success($message);

return Command::SUCCESS;
}

Return Command::SUCCESS on success, Command::FAILURE on failure, or Command::INVALID for invalid input. Use $io->error() to report failures.

Running the command​

The command appears in the php cmd.php list as soon as the add-on exists, but the add-on must be active to run it.

Terminal
php cmd.php

Pass --help to any command to see its arguments and options, for example php cmd.php vendor-addon:greet --help.

Input​

Pass arguments and options after the command name, for example php cmd.php vendor-addon:greet TestName --yell. The execute() example reads them with $input->getArgument('name') and $input->getOption('yell').

See Console Input for argument and option modes, default values, and array inputs.

Output​

Use SymfonyStyle so your output matches the built-in commands.

Run the command with the TestName argument:

Terminal
php cmd.php vendor-addon:greet TestName
Terminal output
Greeting
========

--------- ----------
Field Value
--------- ----------
Name TestName
Yelling No
--------- ----------

[OK] Hello, TestName!

Passing --yell changes the output:

Terminal
php cmd.php vendor-addon:greet TestName --yell
Terminal output
Greeting
========

--------- ----------
Field Value
--------- ----------
Name TestName
Yelling Yes
--------- ----------

[OK] HELLO, TESTNAME!

Life cycle​

Symfony runs initialize(), then interact(), then execute(). Most commands only need execute(); use interact() to ask for missing values and initialize() for setup that must happen before input is validated.

Further reading​

See the Symfony Console documentation for the full command API and console helpers.