【问题标题】:Zf3 controller not able to access the model class table located in another moduleZf3 控制器无法访问位于另一个模块中的模型类表
【发布时间】:2016-12-06 09:39:30
【问题描述】:

我是 Zend 框架的新手。 有没有办法从我的活动控制器访问位于另一个模块中的模型类表?作为 ZF3 中的再见服务定位器,我无法访问位于其他模块中的模型类表。

以前在 ZF2 控制器中

private configTable;

public function getConfigTable()
{
    if (!$this->configTable) {
        $sm = $this->getServiceLocator();
        $this->configTable = $sm->get('Config\Model\ConfigTable'); // <-- HERE!
    }
    return $this->configTable;
}

public function indexAction(){
     $allConfig = $this->getConfigTable()->getAllConfiguration();
    ......

}

因为服务定位器足以将函数从控制器调用到位于另一个模块中的模型类。 有没有办法在没有服务定位器的情况下在 ZF3 中实现类似的功能?

提前谢谢各位。 再见!

【问题讨论】:

  • 1.您可以在控制器的构造函数中使用DI。 2. 为什么你的控制器知道另一个模块的表?
  • @newage 谢谢你的建议,我确实使用了 DI。我试图访问另一个模块模型中已经创建的函数以避免冗余。

标签: php zend-framework zend-framework2 zend-controller zend-framework3


【解决方案1】:

ZF3 中的再见服务定位器

服务定位器尚未从 ZF3 中移除。但是,新版本的框架引入了一些更改,这些更改将破坏现有代码如果您依赖 ServiceLocatorAwareInterface 和/或将服务管理器注入您的控制器/服务中。

在 ZF2 中,默认操作控制器实现了此接口,并允许开发人员从控制器中获取服务管理器,就像在您的示例中一样。您可以在migration guide 中找到有关更改的更多信息。

对此的推荐解决方案是在服务工厂中解析控制器的所有依赖项并将它们注入构造函数。

首先,更新控制器。

namespace Foo\Controller;

use Config\Model\ConfigTable; // assuming this is an actual class name

class FooController extends AbstractActionController
{
    private $configTable;

    public function __construct(ConfigTable $configTable)
    {
        $this->configTable = $configTable;
    }

    public function indexAction()
    {
        $config = $this->configTable->getAllConfiguration();
    }

    // ...
}

然后创建一个新的服务工厂,将配置表依赖注入控制器(使用the new ZF3 factory interface

namespace Foo\Controller;

use Foo\Controller\FooController;
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\FactoryInterface;

class FooControllerFactory implements FactoryInterface
{
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {
        $configTable = $container->get('Config\Model\ConfigTable');

        return new FooController($configTable);
    }
}

然后更新配置以使用新工厂。

use Foo\Controller\FooControllerFactory;

'factories' => [
    'Foo\\Controller\\Foo' => FooControllerFactory::class,
],

【讨论】:

  • 非常感谢!!!!你太棒了@AlexP。 Service Manager 迁移文档对我帮助很大,这个示例非常棒且易于理解。
  • @PrashantKasajoo 我们应该编写 createService() 方法吗?在旧版本中,服务定位器用作参数。我应该在那个函数里面写什么?我是zend的新手...
  • @PrashantKasajoo 我收到了这个错误Class Application\Factory\IndexFactory contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Zend\ServiceManager\FactoryInterface::createService)
  • @CJRamki 答案展示了如何专门为 ZF3 创建工厂。该错误是因为您使用的是 ZF2 并且 Zend\ServiceManager\FactoryInterface 是已更新的接口之一。您需要使用 createService() 方法或更新到 ZF3 才能使上述示例正常工作。
  • @AlexP 如何检查我当前的供应商目录 zend 库是 ZF3 还是 ZF2?因为每个组件都有自己的版本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-19
  • 1970-01-01
  • 2020-02-22
相关资源
最近更新 更多