php - 在 Zend Framework 2 模型中访问 MySQL 数据库的最简单方法

标签 php zend-framework2

我对 ZF2 中的工作方式有点困惑。我需要我的模型文件来访问数据库、运行查询并将结果返回给 Controller 。

所以,我这样配置:

/config/autoload/global.php

return array(
'db' => array(
    'driver'         => 'Pdo',
    'dsn'            => 'mysql:dbname=zf2tutorial;host=localhost',
    'driver_options' => array(
        PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
    ),
),
'service_manager' => array(
    'factories' => array(
        'Zend\Db\Adapter\Adapter'
                => 'Zend\Db\Adapter\AdapterServiceFactory',
    ),
    'aliases' => array(
        'db' => 'Zend\Db\Adapter\Adapter',
    ),
),

);

/config/autoload/local.php

return array(
    'db' => array(
        'username' => 'YOUR USERNAME HERE',
        'password' => 'YOUR PASSWORD HERE',
    ),
);

/module/MyModule/src/MyModule/Controller/MyController.php

    //Trying to access the DB service in controller.
    $db = $this->getServiceLocator()->get('db');

我想我可以在 Controller 中访问它,但是当我试图在 MyModel.php 文件中找到它时,它失败了。

/module/MyModule/src/MyModule/Model/MyModel.php

   //Trying to access the DB service in Model -> Results in FATAL error. ServiceLocator not found.
    $db = $this->getServiceLocator()->get('db');

让模块中的所有模型和 Controller 访问数据库的最佳和最简单的方法是什么?

谢谢

最佳答案

您可以使用 $this->getServiceManager() 从 Controller 中的服务管理器访问任何服务;提供 Controller 类扩展 Zend\Mvc\Controller\AbstractActionController

例如

class FooController extends AbstractActionController {
  public function barAction() {
    $serviceManager = $this->getServiceLocator();
  }
}

这样做的原因是 AbstractActionController 实现了 ServiceLocatorAwareInterface(因此具有名为 set/getServiceLocator() 的方法)。默认情况下,服务管理器在创建时被注入(inject)到 Controller 中。

为了将服务管理器注入(inject)任何其他服务,您还需要遵循类似的过程,但需要手动注入(inject)。

先实现接口(interface)

use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

class MyClass implements ServiceLocatorAwareInterface {

  protected $serviceLocator;      

  public function setServiceLocator(ServiceLocatorInterface $serviceLocator) {
    $this->serviceLocator = $serviceLocator; 
  }
  //...
}

然后创建一个工厂来注入(inject)它(有几种方法可以这样做)

Module.php

public function getServiceConfig() {
   return array(
     'factories' = array(
        'MyClass' => function($serviceManager) {
           $myClass = new MyClass();
           $myclass->setServiceLocator($serviceManager);

           return $myClass;
        }
     ),
   );
}

有几点要提一下:

  • 将服务管理器注入(inject)类通常不是一个好主意,因为您很可能只需要服务管理器应该提供的其他实例。在工厂中获取这些(例如您的数据库适配器)然后将它们注入(inject)到类中会更有意义。使用您的适配器的任何人都会知道它依赖这些服务而不是服务管理器。

  • 让您的“模型”或“实体”知道除了它们自己的属性之外的任何东西被认为是糟糕的设计。我建议阅读 single responsibility principle以及用于持久化域模型的已知设计模式(如对象关系映射器 (ORM) 或数据映射器模式)

关于php - 在 Zend Framework 2 模型中访问 MySQL 数据库的最简单方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21732578/

相关文章:

php - 使用键在 PHP 中进行数组映射

events - ZF2 从事件管理器中删除匿名函数

php - 使用 ZF2 时重定向到公用文件夹

php - ZF2 查看助手配置

php - 在php中排序依赖子数组

php - 我的 While 循环没有获取 MySQL 数据库条目

php - 将 PHP 的 password_verify 转换为 Ruby on Rails

ajax - 如何在 Zend 框架 2 中禁用渲染 View ?

mysql - 使用表达式查询选择大于

php - 如何在 Laravel 8 中运行特定工厂