0
votes

I am new in Zend 2. I have made a controller and Model.

I am getting the following error:

Fatal error: Call to a member function get() on a non-object in C:\websites\zend2\module\Pages\src\Pages\Model\PagesTable.php on line 25

What do i do wrong?!?!

SOLUTION:

controller:

namespace Pages\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;

class IndexController extends AbstractActionController {

protected $pagesTable;

function indexAction() {
    return new ViewModel(array(
        'pages' => $this->getPagesTable()->fetchAll(),
    ));
}

public function getPagesTable()
{
    if (!$this->pagesTable) {
        $sm = $this->getServiceLocator();
        $this->pagesTable = $sm->get('Pages\Model\PagesTable');
    }
    return $this->pagesTable;
}
}

Model:

namespace Pages\Model;
use Zend\Db\TableGateway\TableGateway;

class PagesTable  {

protected $tableGateway;

public function __construct(TableGateway $tableGateway)
{
    $this->tableGateway = $tableGateway;

}

public function fetchAll()
{
    $resultSet = $this->tableGateway->select();
    return $resultSet;
}

}

Add Module.php

public function getServiceConfig()
{
    return array(
        'factories' => array(
            'Pages\Model\PagesTable' =>  function($sm) {
                $tableGateway = $sm->get('PagesTableGateway');
                $table = new PagesTable($tableGateway);
                return $table;
            },
            'PagesTableGateway' => function ($sm) {
                $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                $resultSetPrototype = new ResultSet();
                return new TableGateway('pages', $dbAdapter, null, $resultSetPrototype);
            },
        ),
    );
}
1

1 Answers

0
votes

This is because the functin getServiceLocator() is a function that is implemented in the AbstractController which AbstractActionController extends from, which then again you are extending your Controllers from.

The ServiceLocator itself is injected by the ServiceManager.

The way you wanna be doing things is like this:

// SomeController#someAction
$table = $this->getServiceLocator()->get('MyTableGateway');
$pages = $table->pages();

A very clean and slim Controller. Then you set up a Service for MyTableGateway

// Module#getServiceConfig
'factories' => array(
    'MyTableGateway' => function($serviceLocator) {
        $dbAdapter = $serviceLocator()->get('Zend\Db\Adapter\Adapter');
        $gateway   = new MyTableGateway($dbAdapter);
        return $gateway;
    }
)

This Factory will call your class MyTableGateway and then use Constructor-Injection to inject the Dependency, which in this case is Zend\Db\Adapter\Adapter.

All that's left for you to do is to modify the __construct() of your MyTableGateway to allow for the DbAdapter-Parameter and you're done. That way you gain access to the DbAdapter inside your Gateway and the code is all clean and separated ;)