ZF 2 - Fatal Error: Call to a member function getPosts() on null

1.2k views Asked by At

I am creating a website using Zend Framework 2, and I'm using as an example the exercise from the official course of Zend Technology, Zend Framework 2: Fundamentals.

I have a table called posts and I want to show the table content in my home page, ordered by id. These are the codes I have written:

Controller/PostsTableTrait.php

trait PostsTableTrait
{
    private $postsTable;

    public function setPostsTable($postsTable)
    {
        $this->postsTable = $postsTable;
    }
}

Controller/IndexController.php

class IndexController extends AbstractActionController
{
    use PostsTableTrait;

    public function indexAction()
    {
        return new ViewModel(array(
            'post' => $this->postsTable->getPosts()
        ));
    }
}

Factory/IndexControllerFactory.php

class IndexControllerFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $serviceManager = $serviceLocator->getServiceLocator()->get('ServiceManager');

        $indexController = new IndexController();
        $indexController->setPostsTable($serviceManager->get('Rxe\Factory\PostsTable'));

        return $indexController;
    }
}

Factory/PostsTableFactory.php

class PostsTableFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        return new PostsTable(PostsTable::$tableName, $serviceLocator->get('Zend\Db\Adapter\AdapterService'));
    }
}

Model/PostsTable.php

class PostsTable extends TableGateway
{
    public static $tableName = "posts";

    public function getPosts()
    {
        $select = new Select(self::$tableName);
        $select->columns(array(
            'date',
            'title',
            'text',
            'category'
        ));
        $select->order('id DESC');

        return $select;
    }
}

config/module.config.php

'controllers' => array(
    'invokables' => array(
        'Rxe\Controller\Index' => 'Rxe\Controller\IndexController',
        'Rxe\Controller\Panel' => 'Rxe\Controller\PanelController'
    ),
    'factories' => array(
        'Rxe\Factory\PanelController' => 'Rxe\Factory\PanelControllerFactory'
    )
),
'service_manager' => array(
    'factories' => array(
        'Rxe\Factory\PanelForm' => 'Rxe\Factory\PanelFormFactory',
        'Rxe\Factory\PanelFilter' => 'Rxe\Factory\PanelFilterFactory',
        'Rxe\Factory\PostsTable' => 'Rxe\Factory\PostsTableFactory',
        'Zend\Db\Adapter\AdapterService' => 'Zend\Db\Adapter\AdapterServiceFactory'
    )
),

I don't know if the error could be in the getPosts() method. I have tried many different ways to return the query but none of them made any difference, not even showed another error.

1

There are 1 answers

1
AlexP On BEST ANSWER

You have registered the controller as an 'invokable'. When the the controller manager creates IndexController it will do so without using the IndexControllerFactory; therefore the Rxe\Factory\PostsTable dependency is never set.

To fix this, update module.config.php and register the index controller with your factory class.

'controllers' => [
    'factories' => [
        'Rxe\Controller\Index' => 'Rxe\Factory\IndexControllerFactory',
    ],
],

Also (not an error as such) but the IndexControllerFactory calls ->get('ServiceManager') using the service manager.

You could update it to be like this.

class IndexControllerFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $controllerManager)
    {
        // @var \Zend\ServiceManager\ServiceManager
        $serviceManager = $controllerManager->getServiceLocator();

        $indexController = new IndexController();
        $indexController->setPostsTable($serviceManager->get('Rxe\Factory\PostsTable'));

        return $indexController;
    }
}