Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to use tablegateway and Adapter

Zend or I say this whole framework concept is new for me. Some examples are based on tablegateway format, in which you define name of table related to that controller in Module.php.

/* 'MYMODULE\Model\CompanyTable' =>  function($sm) {
                $tableGateway = $sm->get('CompanyTableGateway');
                $table = new CompanyTable($tableGateway);
                return $table;
            },
            'CompanyTableGateway' => function ($sm) {
                $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                $resultSetPrototype = new ResultSet();
                $resultSetPrototype->setArrayObjectPrototype(new Company());
                return new TableGateway('rs_company', $dbAdapter, null, $resultSetPrototype);
            },*/

And in other example there is only 3 lines of code in Module.php telling about adapter and then intializing through __constuct()

'MYMODULE\Model\CompanyTable' =>  function($sm) {
                $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                $table = new CompanyTable($dbAdapter);
                return $table;
            },

and in class __construc()

public function __construct(Adapter $adapter) {
    $this->adapter = $adapter;
    $this->resultSetPrototype = new ResultSet();
    $this->resultSetPrototype->setArrayObjectPrototype(new Company());

    $this->initialize();
}

What I can't understand is How to choose between both of them.

like image 803
Neelam Gahlyan Avatar asked Dec 21 '22 07:12

Neelam Gahlyan


1 Answers

Simply put, what you essentially want to do is register services (factories) in Zends service manager, so that you can access them from within many of your classes and modules in your application. They are like pre-packaged objects that are ready to go when you need them! The point is that they already have everything that they depend on already injected.

Now, you can register services in the service manager in various ways, such as from within your module.config.php or in your Module.php, the choice is yours. The important thing to remember is this that you just want to be able to ask for something, and not worry about all the underlying details.

The default Db adapter: This adapter is automatically registered in your service manager if you have configured your database settings in the main application config (global.php and local.php).

$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');

Now, you can use this adapter to do your database functions without any TableGateway or Table model, again the choice is yours. You can grab this service from within your controller, you can inject it into models, or whatever floats your boat.

The Table model: What you are doing in the code below is injecting the Adapter into your Table model. So, from within your application, you can simply grab the Table model service from the service manager and it will already have the adapter.

'MYMODULE\Model\CompanyTable' =>  function($sm) {
    $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
    $table = new CompanyTable($dbAdapter);
    return $table;
},

But what is your Table model? Well, it could be a prototype of the Table, a class of functions for the table, or both. Technically, you are the one creating the Table model, so you could create all sorts of functions and inject all sorts of stuff, like:

'MYMODULE\Model\CompanyTable' =>  function($sm) {
    $table = new CompanyTable();
    $table->setAdapterService( $sm->get('Zend\Db\Adapter\Adapter') );
    $table->setSessionService( $sm->get('MYMODULE\Session') );
    $table->setCustomService( $sm->get('MYMODULE\Custom') );
    return $table;
},

Think about this, what if you had several different database adapters, which failover if the primary or even secondary databases go down. You could inject the first available adapter, and your application would never know the difference when it makes calls to the Table model.

The TableGateway: The TableGateway is exactly what it sounds like. It's an instance of Zends TableGateway that is given the table name, Db Adapter, and can even be prototyped with the Table model. What is prototyping? Well, what this does is basically instead of returning a normal result set with data when you make a database query, it will return the data as an instance of the Table model. Again, when registering your gateway in the service manager, the point is for your application to grab and use it without ever having to worry about the adapter or name of the table, or anything else. In this example it's prototyped with your Table model, but it doesn't have to be.

'CompanyTableGateway' => function ($sm) {
    $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
    $resultSetPrototype = new ResultSet();
    $resultSetPrototype->setArrayObjectPrototype(new Company());
    return new TableGateway('rs_company', $dbAdapter, null, $resultSetPrototype);
 },

When using a TableGateway, you could just provide it to your Table model instead of the adapter, and you would write your Table model to use the gateway for all Db functions.

'MYMODULE\Model\CompanyTable' =>  function($sm) {
    $tableGateway = $sm->get('CompanyTableGateway');
    $table = new CompanyTable($tableGateway);
    return $table;
},

So to summarize, the answer to your question is: The choice is yours. Use the Db Adapter by itself, or use it in conjunction with a Table Model AND/OR Table Gateway. Hopefully this helps!

like image 119
jon__o Avatar answered Jan 27 '23 14:01

jon__o