7

In my App I have a helper class App\Command\GenerateFixturesCommand that provides a command named my-nice-project:generate-fixtures.

This command consumes a service of my own project named App\Services\CatalogFixtureGenerator that generates 1000 random PDF documents for testing while developing the app.

To do so, this service uses the joshtronic\LoremIpsum class which is required in composer only in dev. LoremIpsum is a third-party library. I require it under composer's require-dev.

So the injection is:

  1. I run my GenerateFixturesCommand.
  2. Before that, the system transparently locates my CatalogFixtureGenerator and to inject it into the command.
  3. Before that, the system transparently locates the LoremIpsum third party service to inject it into my fixture generator service.

All is autowired.

When I deploy to prod and do composer install --no-dev --optimize-autoloader of course the LoremIpsum class is not installed.

But when I clear the cache with APP_ENV=prod php bin/console cache:clear the framework finds the command and cannot inject the autowired dependencies.

[WARNING] Some commands could not be registered:
In CatalogsFixtureGenerator.php line 26:
Class 'joshtronic\LoremIpsum' not found

This my-nice-project:generate-fixtures command is never going to be used in the production server.

Question

How can I "disable" the command in prod?

I mean: How can I tell the framework that the class GenerateFixturesCommand should not be loaded nor its autowired dependencies, and neither of them should be autowired in prod?

4

3 回答 3

4

使用isEnabled()命令中的方法。例如

    public function isEnabled(): bool
    {
        // disable on prod
        if ($this->appKernel->getEnvironment() === 'prod') {
            return false;
        }

        return true;
    }
于 2021-03-15T15:06:50.097 回答
0

在我的上一个项目中,我需要一些命令才能仅在开发环境中工作。您使用getenv函数来实现这一点:

# src/Command/SomeCommand.php
...

public function __construct()
{
    parent::__construct();
    if (getenv("APP_ENV") !== "dev") {
        exit('This command should work only "dev" environment.');
    }
}

这会成功的。

代码乐趣:)

于 2020-09-09T07:44:28.420 回答
0

@gusDeCooL 建议的解决方案不适用于延迟加载的命令(至少不适合我)。

isEnabled()无论如何,我最终还是实现了该方法,但随后我在以下位置添加了一个警卫execute()

<?php


namespace App\Command;
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: 'command:name',
    description: 'Some description',
)]
class CommandName extends Command
{
    public function isEnabled(): bool
    {
        return 'dev' === getenv('APP_ENV');
    }

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

        if (!$this->isEnabled()) {
            $io->error('This command is only available in `dev` environment.');
            exit(1);
        }

        // the rest
    }
}

于 2022-03-02T01:36:56.267 回答