Внедрение таблиц SQL в Laminas / Zend Framework — правильный ли это способ?

У меня, вероятно, есть некоторые проблемы с пониманием Laminas, или, может быть, я просто слишком сложен :-) надеюсь, кто-то может пролить свет на это...

У меня есть IndexController, фабрика IndexController и 2 таблицы (пользователь, фотографии).

Все таблицы являются расширениями AbstractTableGateway:

UserTable.php

<?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

<?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 = ....
    }
}

В моем IndexController я создаю экземпляр класса Gallery, которому нужны вышеупомянутые UserTable и PhotosTable.

Теперь правильный способ внедрить UserTable и PhotoTable в IndexControllerFactory.php и из IndexController.php вставить их обоих в класс галереи следующим образом:

IndexControllerFactory.php

<?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


<?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);
    }
}


Галерея.php

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;
}

Итак, мой главный вопрос: правильный ли написанный выше код? действительно ли необходимо вводить таблицы

  1. от фабрики до IndexController
  2. от IndexController к классу галереи

пока я, наконец, не смогу использовать их в методах класса галереи.

Кажется, будет много кода, пока я, наконец, не смогу их использовать!?


person jan7007    schedule 23.10.2020    source источник


Ответы (1)


Более правильным способом сделать это было бы создать класс GalleryFactory для класса Gallery, который вводит в него UserTable и PhotosTable, а затем вводит объект Gallery в IndexController в IndexControllerFactory.

таким образом, IndexController не нужно обрабатывать классы таблиц.

Таким образом, создайте GalleryFactory, которая создает объект Gallery и внедряет таблицы.

<?php
namespace Slideshow\Model\Factory;

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

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

А затем измените indexControllerFactory, чтобы внедрить

<?php
namespace Slideshow\Controller\Factory;

use Slideshow\Model\Gallery;
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(Gallery::class),
            $container->get('ApplicationConfig')
        );
    }
}

И измените indexController, чтобы вместо этого получить объект галереи.

<?php
namespace Slideshow\Controller;

use Slideshow\Model\Gallery;
use Laminas\Mvc\Controller\AbstractActionController;
use Laminas\View\Model\ViewModel;

class IndexController extends AbstractActionController
{
    private $gallary;
    private $config;

    public function __construct(Gallary $gallery, array $config)
    {
        $this->gallery= $gallery;
        $this->config = $config;
    }

    public function indexAction()
    {
        $html = $this->gallery->renderUserListHtml();
        var_dump($html);
    }
}
person Otto Sandström    schedule 16.02.2021