Search code examples
phpsymfonywkhtmltopdfsymfony4

Use a controller as a service in a command


I'm trying to use Wkhtmltopdf from a Symfony Command.

I decided to use KnpSnappyBundle, so I created a controller used as a service.

WkhtmltopdfController.php

class WkhtmltopdfController extends Controller {

public function indexUrl()
{
    $snappy = $this->get('knp_snappy.pdf');
    $filename = 'myFirstSnappyPDF';
    $url = 'http://ourcodeworld.com';


    return new Response(
        $snappy->getOutput($url),
        200,
        array(
            'Content-Type'          => 'application/pdf',
            'Content-Disposition'   => 'inline; filename="'.$filename.'.pdf"'
        )
    );
}}

Then I import this service from my Command constructor like this.

MyCommand

class GenerateQuittance extends Command {

private $snappy;
private $container;

public function __construct(WkhtmltopdfController $knpSnappyPdf, ContainerInterface $container)
{
    parent::__construct();
    $this->snappy = $knpSnappyPdf;
    $this->container = $container;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
 [...]
 $this->snappy->indexUrl();
}

But I get [error] Error thrown while running command "app:myCommand". Message: "Call to a member function get() on null".

So how can I use my method from WkhtmltopdfController into a Command.

Thank you,


Solution

  • Injecting controller as a service is generally bad idea because they get special handling from Symfony. Consider refactoring your WkhtmltopdfController::indexUrl() method into separate service. You may also want to convert $filename variable into argument and convert method's return value into plain output instead of Response.

    Please also notice that injecting ContainerInterface is also considered as a bad practice, you need to explicitly list services, you want to inject.

    Your particular error most likely caused by a fact that get() method is provided by ContainerTrait that expects ContainerInterface to be available (by using ContainerAwareTrait in base container), but such injection may not happen in a case of console Application.