在Laminas / Zend Framework中注入SQL表-这是正确的方法吗?

问题描述

我可能对薄片有一些理解上的问题,或者也许我太复杂了:-) 希望有人可以带来启发...

我有一个IndexController,一个IndexController Factory和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中,我正在创建需要上述UserTable和PhotosTable的gallery-Class的实例。

现在是在IndexControllerFactory.PHP中注入UserTable和PhotoTable并从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);
    }
}


gallery.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到gallery类

直到我终于可以在gallery类的方法中“使用它们”。

在我终于可以使用它们之前,似乎有很多代码!?

解决方法

更正确的方法是为 Gallery 类创建一个 GalleryFactory 类,该类将 UserTable 和 PhotosTable 注入其中,然后将 Gallery 对象注入到 IndexControllerFactory 中的 IndexController

这样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,array $options = null)
    {
        return new IndexController(
            $container->get(Gallery::class),$container->get('ApplicationConfig')
        );
    }
}

并将 indexController 更改为重新接收 Gallery 对象

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