Let a service called by a Symfony command write an update to the terminal

Viewed 418

What would be a proper way to have a Service (that will be used by a Command) write information to the terminal? I like the same functionality to parse thousands of records to be able to be called from both a Controller and a Command. When it's called from the Command, I like to write a status to the terminal for every parsed record.

I've tried autowiring InputInterface $input, OutputInterface $output into the service but that gives me the following error:

Cannot autowire service "App\Service\Command\TestIoService": argument "$input" of method "__construct()" references interface "Symfony\Component\Console\Input\InputInterface" but no such service exists. Did you create a class that implements this interface?

I could pass the input and output to the service but I was wondering if there is a better way to do this

1 Answers

I know this is over a year old, but I just stumbled upon the same requirement for my project. It's a bad idea to be passing around the Input/Output Interfaces.

Since Symfony 2.4 you've been able to use the Monolog component to log to the console. (https://symfony.com/doc/current/logging/monolog_console.html). It's already all wired-up for you. DI The LoggerInterface (use Psr\Log\LoggerInterface) in your constructor. Then use it like you normally would. $this->logger->debug('Hello World'). Your output is dependent on the verbosity level set via the CLI -v, -vv, -vvv options as described in the link above.

// src/Command/YourCommand.php
namespace App\Command;

use App\Service\AwesomeService;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class YourCommand extends Command
{

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

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $this->service->doMethod();
    }
}

// src/Service/AwesomeService.php
namespace App\Service;

use Psr\Log\LoggerInterface;

class AwesomeService
{
    private $logger;

    public function __construct(LoggerInterface $logger)
    {
        $this->logger = $logger;
    }

    protected function doMethod()
    {
        $this->logger->debug('Some info');
        $this->logger->notice('Some more info');
    }
}
Related