Как вызвать команду из контроллера

Дата обновления перевода 2023-08-25

Как вызвать команду из контроллера

Документация компонента Консоль описывает то, как создавать консольную команду. Эта статья расскажет о том, как использовать её прямо из вашего контроллера.

Вам может понадобиться выполнить некоторую функцию, которая доступна только в консольной команде. Обычно, вам нужно было бы перепроектировать команду и переместить некоторую логику в сервис, который можно использовать в контроллере повторно. Однако, когда команда является частью сторонней библиотеки, вы не хотите изменять или дублировать её код. Вместо этого, вы можете выполнить команду напрямую из контроллера.

Caution

В сравнении с прямым вызовом из консоли, вызов команды из контроллера имеет незначительное влияние на производительность из-за издержек стека запросов.

Представьте, что вы хотите запустить debug:twig изнутри своего контроллера:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// src/Controller/DebugTwigController.php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\KernelInterface;

class DebugTwigController extends AbstractController
{
    public function debugTwig(KernelInterface $kernel): Response
    {
        $application = new Application($kernel);
        $application->setAutoExit(false);

        $input = new ArrayInput([
            'command' => 'debug:twig',
            // (опционально) определите значение аргументов команды
            'fooArgument' => 'barValue',
            // (опционально) передайте опции команде
            '--bar' => 'fooValue',
            // (опционально) передайте опции без значения
            '--baz' => true,
        ]);

        // Вы можете использовать NullOutput(), если вам не нужен вывод
        $output = new BufferedOutput();
        $application->run($input, $output);

        // вернуть вывод, не используйте, если вы использовали NullOutput()
        $content = $output->fetch();

        // вернуть новый Response(""), если вы использовали NullOutput()
        return new Response($content);
    }
}

Отображение цветного вывода команды

Если вы сообщите BufferedOutput, что он декорирован через второй параметр, то он вернёт Ansi содержимое с цветной маркировкой. Чтобы конвертировать это в цветной HTML, может быть использован Преобразователь SensioLabs AnsiToHtml.

Для начала, запросите пакет:

1
$ composer require sensiolabs/ansi-to-html

Теперь, используйте его в своем контроллере:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// src/Controller/DebugTwigController.php
namespace App\Controller;

use SensioLabs\AnsiConverter\AnsiToHtmlConverter;
use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\HttpFoundation\Response;
// ...

class DebugTwigController extends AbstractController
{
    public function sendSpool(int $messages = 10): Response
    {
        // ...
        $output = new BufferedOutput(
            OutputInterface::VERBOSITY_NORMAL,
            true // true for decorated
        );
        // ...

        // вернуть вывод
        $converter = new AnsiToHtmlConverter();
        $content = $output->fetch();

        return new Response($converter->convert($content));
    }
}

AnsiToHtmlConverter может быть также зарегистрирован, как расширение Twig, и поддерживать необязательные темы.