Interesting question. You can of course just run the console command itself and capture the list of commands. Might actually be the best way.
However, there is a service called console.command_loader which has a method called getNames which does indeed return a list of command names. It implements CommandLoaderInterface.
Originally I tried to create an alias so it could be injected into an action method:
services:
Symfony\Component\Console\CommandLoader\CommandLoaderInterface:
alias: console.command_loader
But I kept getting console.command_loader not found which was puzzling since debug:container shows it. The service was tagged with container.no_preload which might have something to do with it. Not sure.
So I went and just defined the controller service:
services:
App\Controller\CommandController:
tags:
- 'controller.service_arguments'
arguments:
- '@console.command_loader'
And somewhat to my surprise it worked.
class CommandController extends AbstractController
{
public function __construct(private CommandLoaderInterface $cl)
{
}
#[Route('/commands', name: 'app_commands')]
public function commands(): Response
{
$names = $this->cl->getNames();
dump($names);
// I happen to have a command called app:init
$initCommand = $this->cl->get('app:init');
dump($initCommand->getDescription());
//return $this->render('default/index.html.twig', [
// 'controller_name' => 'DefaultController ' . 'Commands',
//]);
}
}
This was all done in Symfony 6. Did not happen to have a Symfony 3 app handy. Your first step would be to confirm that Symfony 3 also has the service with bin/console debug:container console.command_loader. If it does not have such a service then poke around a bit and see if it has something similar.