# Injecting SQL Tables in Laminas / Zend Framework - is this the correct way?

**URL:** <https://discourse.laminas.dev/t/injecting-sql-tables-in-laminas-zend-framework-is-this-the-correct-way/1909>\
**Category:** Components & MVC\
**Tags:** laminas-db, laminas-mvc\
**Created:** [October 24, 2020, 6:47am UTC](https://discourse.laminas.dev/t/injecting-sql-tables-in-laminas-zend-framework-is-this-the-correct-way/1909 "2020-10-24T06:47:53Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![jan7007](https://avatars.discourse-cdn.com/v4/letter/j/b3f665/32.png) [@jan7007](https://discourse.laminas.dev/u/jan7007)\
**Post date:** [October 24, 2020, 6:47am UTC](https://discourse.laminas.dev/t/injecting-sql-tables-in-laminas-zend-framework-is-this-the-correct-way/1909/1 "2020-10-24T06:47:53Z")

</div>

I probably have some understanding problem with Laminas, or maybe I’m just too complicated 🙂  
hopefully someone can bring light in this…

I have an IndexController, an IndexController Factory and 2 Tables (User, Photos).

The Tables are all extensions of the AbstractTableGateway:

**UserTable.php**

```auto
<?php

declare(strict_types=1);

namespace Slideshow\Model\Table;

use Laminas\Db\Adapter\Adapter;

class UserTable extends AbstractTableGateway
{
    protected $adapter;
    protected $table = 'user';

    public function __construct(Adapter $adapter)
    {
        $this->adapter = $adapter;
        $this->initialize();
    }

    public function getUsersThatHaveAGallery()
    {
         // sql... select... from... where.....
    }
}

```

**PhotosTable.php**

```auto
<?php

declare(strict_types=1);

namespace Slideshow\Model\Table;

use Laminas\Db\Adapter\Adapter;

class UserTable extends AbstractTableGateway
{
    protected $adapter;
    protected $table = 'photos';

    public function __construct(Adapter $adapter)
    {
        $this->adapter = $adapter;
        $this->initialize();
    }

    public function getPhotosFromUser($user_id)
    {
         // sql...select photos from user where id = ....
    }
}

```

In my IndexController I’m creating an Instance of an Gallery-Class which needs the above mentioned UserTable and PhotosTable.

Is the correct way now to inject the UserTable and PhotoTable in the `IndexControllerFactory.php` and from the `IndexController.php` inject them both to the Gallery Class like this:

**IndexControllerFactory.php**

```auto
<?php

declare(strict_types=1);

namespace Slideshow\Controller\Factory;

use Slideshow\Model\Table\UserTable;
use Slideshow\Model\Table\PhotosTable;
use Interop\Container\ContainerInterface;
use Laminas\ServiceManager\Factory\FactoryInterface;

class IndexControllerFactory implements FactoryInterface
{
    public function __invoke(ContainerInterface $container, $requestName, array $options = null)
    {
        return new IndexController(
            $container->get(UserTable::class),
            $container->get(PhotosTable::class),
            $container->get('ApplicationConfig')
        );
    }
}

```

**IndexController.php**

```auto

<?php

declare(strict_types=1);

namespace Slideshow\Controller;

use Slideshow\Model\Table\UserTable;
use Slideshow\Model\Table\PhotosTable;
use Laminas\Mvc\Controller\AbstractActionController;
use Laminas\View\Model\ViewModel;

class IndexController extends AbstractActionController
{
    private $userTable;
    private $photosTable;
    private $config;

    public function __construct(UserTable $userTable, PhotosTable $photosTable, array $config)
    {
        $this->userTable = $userTable;
        $this->photosTable = $photosTable;
        $this->config = $config;
    }

    public function indexAction()
    {
        // At this Point now I have to inject the Tables again ? 
        $Gallery = new Gallery($this->userTable, $this->photosTable);

        $html = $Gallery->renderUserListHtml();
        
        var_dump($html);
    }
}

```

**Gallery.php**

```auto
class Gallery {

   private $userTable;
   private $photosTable;

   // At this point I have to inject the tables AGAIN to make them usable in the Gallery.php ?
   public function __construct(UserTable $userTable, PhotosTable $photosTable)
   {
        $this->userTable = $userTable;
        $this->photosTable = $photosTable;
    {
 
   public function renderUserListHtml()
   {
      $sqlResult = $this->userTable->getUsersThatHaveAGallery();

      foreach($sqlResult as $k => $v) {
            $html .= '<div>' . $v['user_name'] . '</div><br />';
      }
 
      return $html;
}

```

So my main question is: is the above written code correct ?  
is it really necessary to inject the tables

1. from Factory to IndexController
2. from IndexController to Gallery Class

until I can finally “use them” in the methods of the gallery class.

It seems to be a lot of code until I finally can use them !?

---

<div class="post-metadata">

**Author:** ![tomstryja](https://yyz2.discourse-cdn.com/flex032/user_avatar/discourse.laminas.dev/tomstryja/32/1075_2.png) [@tomstryja](https://discourse.laminas.dev/u/tomstryja)\
**Post date:** [October 25, 2020, 6:40pm UTC](https://discourse.laminas.dev/t/injecting-sql-tables-in-laminas-zend-framework-is-this-the-correct-way/1909/2 "2020-10-25T18:40:05Z")

</div>

Would not be better to have Gallery class as ViewHelper? Than you can pass services in ViewHelper constructor.

Or consider SQL JOIN or SQL view (if you dont need to call modules separately in controller).

When I have a module I usually crate service class … `Slideshow` with setters and getters for module forms, models etc. In controller construct I just pass this service class `Slideshow` and than acces models or forms from service class.

Controller action example …

```auto
public function updateHourAction()
    {
        $orderId = (int) $this->params()->fromRoute('id');
        $request = $this->getRequest();
        try {
            $this->serviceOrder->updateHour($request->getPost());
            $this->flashMessenger()->addSuccessMessage('sssss');
        } catch (\Throwable $e) {
            $this->getEventManager()->trigger('log', $this,
                array(
                    'priority' => Logger::ERR,
                    'message' => __METHOD__. '->' . $e->getMessage()
                ));
            $this->flashMessenger()->addErrorMessage('eeeee');
        }

        return $this->redirect()->toRoute('rrrrr', array(
            'id' => $orderId
        ));
    }

```

Service method **updateHour**

```auto
    /**
     * @param \ArrayObject $post
     * @return number
     */
    public function updateHour($post)
    {
        $entity = new \OrderFront\Entity\Order();
        $entity->exchangeArray($post);
       
        return $this->getModelOrder()->update($entity);
    }
```

---

<div class="post-metadata">

**Author:** ![dickdono](https://yyz2.discourse-cdn.com/flex032/user_avatar/discourse.laminas.dev/dickdono/32/656_2.png) [@dickdono](https://discourse.laminas.dev/u/dickdono)\
**Post date:** [November 18, 2020, 7:24pm UTC](https://discourse.laminas.dev/t/injecting-sql-tables-in-laminas-zend-framework-is-this-the-correct-way/1909/3 "2020-11-18T19:24:06Z")

</div>

This may just be a style thing and I’m no expert, but here’s what I do in situations like this (which I deal with all the time).

- Create a `GalleryFactory` class that injects the `UserTable` and `PhotosTable` (just like you are doing in the `IndexControllerFactory` now).
  - you will need to add an entry in `module.config.php` in the `service_manager` section that tells the framework that when you need a `Gallery` object to use `GalleryFactory::class`.

* * *

- Modify the `IndexControllerFactory`:
  - remove the UserTable`and`PhotosTable`
  - add `$container->get(Gallery::class); ` // inject the Gallery object.

* * *

- Modify `IndexController`
  - add a new class variable `private $gallery;`
  - add code to the `__construct` to accept the `Gallery` class and assign it to your new class variable.
  - Now you can remove this line:  
`$Gallery = new Gallery($this->userTable, $this->photosTable);`
  - Then, in your controller, wherever you are currently accessing `$Gallery`, you’d just access `$this->gallery`. For example:  
`$html = $this->gallery->renderUserListHtml();`

* * *

Now, this means that you won’t be able to access the `UserTable` or `PhotosTable` from your IndexController, but I never access tables in the Controller unless it is a **super-simple** controller (with no other associated models).

_Hope that helps!_
