开发者

Symfony2 custom console command not working

开发者 https://www.devze.com 2023-04-04 09:39 出处:网络
I created a new Class in src/MaintenanceBundle/Command, named it GreetCommand.php and put the following code in it:开发者_开发问答

I created a new Class in src/MaintenanceBundle/Command, named it GreetCommand.php and put the following code in it:

开发者_开发问答
<?php

namespace SK2\MaintenanceBundle\Command;

use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class GreetCommand extends ContainerAwareCommand
{
    protected function configure()
    {
        $this
            ->setName('maintenance:greet')
            ->setDescription('Greet someone')
            ->addArgument('name', InputArgument::OPTIONAL, 'Who do you want to greet?')
            ->addOption('yell', null, InputOption::VALUE_NONE, 'If set, the task will yell in uppercase letters')
        ;
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $name = $input->getArgument('name');
        if ($name) {
            $text = 'Hello '.$name;
        } else {
            $text = 'Hello';
        }

        if ($input->getOption('yell')) {
            $text = strtoupper($text);
        }

        $output->writeln($text);
    }
}

?>

And tried to call it via

app/console maintenance:greet Fabien

But i always get the following error:

[InvalidArgumentException] There are no commands defined in the "maintenance" namespace.

Any ideas?


I had this problem, and it was because the name of my PHP class and file didn't end with Command.

Symfony will automatically register commands which end with Command and are in the Command directory of a bundle. If you'd like to manually register your command, this cookbook entry may help: http://symfony.com/doc/current/cookbook/console/commands_as_services.html


I had a similar problem and figured out another possible solution:

If you override the default __construct method the Command will not be auto-registered by Symfony, so you have to either take the service approach as mentioned earlier or remove the __construct override and make that init step in the execute method or in the configure method.

Does actually anyone know a good best practice how to do init "stuff" in Symfony commands?

It took me a moment to figure this out.


I figured out why it was not working: I simply forgot to register the Bundle in the AppKernel.php. However, the other proposed answers are relevant and might be helpful to resolve other situations!

By convention: the commands files need to reside in a bundle's command directory and have a name ending with Command.

in AppKernel.php

public function registerBundles()
{
    $bundles = [
        ...
        new MaintenanceBundle\MaintenanceBundle(),
    ];

    return $bundles;
}


In addition to MonocroM's answer, I had the same issue with my command and was silently ignored by Symfony only because my command's constructor had 1 required argument.

I just removed it and call the parent __construct() method (Symfony 2.7) and it worked well ;)


If you are over-riding the command constructor and are using lazy-loading/autowiring, then your commands will not be automatically registered. To fix this you can add a $defaultName variable:

class SunshineCommand extends Command
{
    protected static $defaultName = 'app:sunshine';

    // ...
} 

Link to the Symfony docs.


I think you have to call parent::configure() in your configure method


I had this same error when I tried to test my command execution with PHPUnit.

This was due to a wrong class import :

use Symfony\Component\Console\Application;

should be

use Symfony\Bundle\FrameworkBundle\Console\Application;

cf. Other stack thread


In my case it was complaining about the "workflow" namespace although the WorkflowDumpCommand was correctly provided by the framework.

However, it was not available to run because I have not defined any workflows so the isEnabled() method of the command returned false.


I tried to use a service passed via constructor inside the configure method:

class SomeCommand extends Command {

    private $service;

    public function __construct(SomeService $service) {
        $this->service = $service;
    }

    protected function configure(): void {
        $this->service->doSomething(); // DOES NOT WORK
    }
}


Symfony uses Autoconfiguration that automatically inject dependencies into your services and register your services as Command, event,....

So first just make sure that you have services.yaml in your config folder. with autoconfigure:true.
this is the default setting

Then Make sure That All your files are exactly the same name as Your Class. so if you have SimpleClass your file must be SimpleClass.php


If you have a problem because of a __constructor, go to services.yml and add something like this:

app.email_handler_command:
    class: AppBundle\Command\EmailHandlerCommand
    arguments:
        - '@doctrine.orm.entity_manager'
        - '@app.email_handler_service'
    tags:
        - { name: console.command }


For newer Symfony-Version (5+) commands must be registered as services.

What I do frequently forget while setting it up, is to tag it properly:

 <service id="someServiceCommand">
      <tag name="console.command"/>
 </service>

Without this litte adaptation, your command name will not be displayed and therefore not accessible.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号