5

Using symfony2. I have a listener class that is attempting to call a method from a different class (a controller) like so:

        $authenticate = new AuthenticationController();
        $authenticate->isTokenValid($token);

And the controller isTokenValid method:

public function isTokenValid($token) {

    $conn = $this->get('database_connection');

Is throwing the error

Fatal error: Call to a member function get() on a non-object in /home/content/24/9254124/html/newsite/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php on line 246

If i load the controller method the proper way (using routing in the url) it works fine.

coderabbi
  • 2,261
  • 16
  • 18
Jonah Katz
  • 5,230
  • 16
  • 67
  • 90
  • @LightnessRacesinOrbit excuse me? – Jonah Katz Oct 15 '12 at 23:08
  • @LightnessRacesinOrbit I just dont understand what you mean by it is all.. – Jonah Katz Oct 15 '12 at 23:14
  • http://www.eelis.net/iso-c++/testcase.xhtml -- good debugging technique includes making a testcase for yourself _before_ asking the internet for help! The process of making a testcase more often than not identifies the problem. – Lightness Races in Orbit Oct 15 '12 at 23:15
  • You might find this insightful: http://stackoverflow.com/questions/12769982/reference-what-does-this-error-mean-in-php/12769983#12769983 – hakre Oct 15 '12 at 23:25

2 Answers2

7

Symfony2 uses Dependency Injection pattern, you have to inject container that holds all services (like database connection):

$authenticate = new AuthenticationController();
$authenticate->setContainer($this->container);
$authenticate->isTokenValid($token);

Of course I assume here that your listener class is ContainerAware

[+] To make your listener ContainerAware, pass @service_container to it (example form services.yml)

my.listener:
    class: ACME\MyBundle\ListenerController
    arguments: [ @service_container ]
    tags:
        - { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
    kernel.event_listener:
        event: kernel.controller

and then in constructor of you listener class:

public function __construct($container = null){
    $this->container = $container;
}
dev-null-dweller
  • 29,274
  • 3
  • 65
  • 85
  • Actually, i dont think its containeraware, it threw the error `undefined property: $container`.. – Jonah Katz Oct 15 '12 at 23:18
  • Nice. I see what you mean now. Is `[ @service_container ]` literal, or should i be replacing that with something? Excuse my lack of understanding what a container is.. – Jonah Katz Oct 15 '12 at 23:30
  • If you are using yml files for config, it is literally `@service_container`, if you are using something else, please refer to the documentation to see how you should define your listener – dev-null-dweller Oct 15 '12 at 23:34
  • **-1** for suggesting to inject the whole container. – Elnur Abdurrakhimov Oct 16 '12 at 06:29
  • @elnur as far as I understand OP question this class also works as standard controller, so it doesn't make sense to double functionality, one using container and other using only db connection – dev-null-dweller Oct 16 '12 at 06:48
4

I'm adding another answer because what @dev-null-dweller suggests is a bad practice: in almost every case you better to inject only the services you need — not the whole container:

use Doctrine\DBAL\Connection;

public function __construct(Connection $connection)
{
    $this->connection = $connection;
}
my_listener:
    arguments: [ @database_connection ]
Elnur Abdurrakhimov
  • 44,533
  • 10
  • 148
  • 133