0

I would like to use $this->container->get in a custom class I've created. I've done my reading and found out that I should use ContainerInterface in the constructor, which I do, but I still get this error:

Error: Call to a member function get() on a non-object

Here is the code:

MyClass.php

namespace path\to\MyClass;

use Symfony\Component\DependencyInjection\ContainerInterface;

class MyClass {

    private $container;
    public $user_id;

    public function __contruct(ContainerInterface $container) {

        $this->container = $container;
        $this->user_id = $user_id;

        return $this;
    }

    /**
     * @param string $data Some data
     * @return array A response
     */
    public function generatePDF($data)
    {
        // Create the folders if needed
        $pdf_folder =  __DIR__.'/../../../../web/pdf/'.$this->user_id.'/';

        if(!file_exists($pdf_folder))
            mkdir($pdf_folder, 0755, TRUE);

        $file_id = "abc1";

        // Set the file name
        $file = $pdf_folder.$file_id.'.pdf';

        // Remove the file if it exists to prevent errors
        if(file_exists($file)) {
            unlink($file);
        }

        // Generate the PDF
        $this->container->get('knp_snappy.pdf')->generateFromHtml(
            $this->renderView(
                'StrimeGlobalBundle:PDF:invoice.html.twig',
                $data
            ),
            $file
        );
    }
}

Do you guys have any idea of what could be the problem?

Thanks for your help.

Romain biard
  • 186
  • 9
  • 2
    How are you injecting the container? Why don't you just inject knp_snappy.pdf directly? – JimL Mar 24 '16 at 10:17
  • Hi @JimL, for now this is what my class looks like. How would you recommend to inject the container in it? How would you directly inject KNP? Thanks for your help. – Romain biard Mar 24 '16 at 15:27
  • Hi @JimL, I managed to make it work with your help and rouflak's help. Thanks. – Romain biard Mar 24 '16 at 18:13
  • Great :) what he said about injecting the actual service(s) you need to be recommended is absolutely true. It makes testing your services / classes much easier – JimL Mar 24 '16 at 18:28
  • You're right. It took me some time to figure out how to make it work, but thanks to you both, I now understand the logic. Thanks again. :o) – Romain biard Mar 25 '16 at 09:53

2 Answers2

2

You need to declare your class as a service in the Symfony configuration.

Please have a look to the Symfony service container page.

Here is an explanation to inject the container in the constructor:

# services.yml
services:
    app.my_class:
        class: TheBundle\Service\MyClass
        arguments: ['@service_container']

Or as said JimL in comment, you can inject the service you need (which is recommanded):

class MyClass
{
    private $pdfService;
    public function __construct(\Your\Service\Namespace\Class $pdfService)
    {
        $this->pdfService = $pdfService;
    }

    // ...
}

And in your service.yml file

# services.yml
services:
    app.my_class:
        class: TheBundle\Service\MyClass
        arguments: ['@knp_snappy.pdf']

The container can also be injected with a setter. See this link

Hope this helps!

Community
  • 1
  • 1
rouflak
  • 154
  • 5
0

Your class cannot "see" any service (including the container) unless you "inject" it. In YourCustomBundle/Resources/config/services.xml you need to define the service and it's dependencies. Read up on Dependency Injection and it should make more sense.

Also, @JimL is right, you shouldn't inject the entire container to access one service, simply inject the one service (knp_snappy.pdf)

craigh
  • 1,909
  • 1
  • 11
  • 24