2

我试图在我的控制器中获取一个 ServiceManager 实例,以便为 Db\Adapter 使用工厂。

我添加到模块/应用程序/config/module.config.php:

'service_manager' => [
    'factories' => [
        Adapter::class => AdapterServiceFactory::class,
    ],
],

到 config/autoload/local.php 我添加了以下几行:

'db' => [
    'driver' => 'Mysqli',
    'database' => 'mydb',
    'username' => 'myuser',
    'password' => 'mypassword',
]

现在我想访问我的模块/Application/src/Controller/IndexController.php 中的ServiceManager。我怎么做?

我试过$sm = $this->getPluginManager();没有成功。如果我$serviceManager->get(Adapter::class)使用 PluginManager 运行它会给我一个错误:

Too few arguments to function Zend\Db\Adapter\Adapter::__construct(), 0 passed in (...)\vendor\zendframework\zend-servicemanager\src\Factory\InvokableFactory.php on line 30 and at least 1 expected

我该怎么做才能获得一个 ServiceManager 来获取我的那个 Adapter 对象?


我将控制器工厂从

'controllers' => [
    'factories' => [
        Controller\IndexController::class => InvokableFactory::class,
    ],
],

'controllers' => [
    'factories' => [
        Controller\IndexController::class => function(ContainerInterface $serviceManager) {
            return new Controller\IndexController($serviceManager);
        },
    ],
],

我还在 module.config.php 中添加了一个 getServiceConfig() 方法,并向 IndexController 添加了一个构造函数,它接收 ServiceManager。现在我可以访问控制器内部了。

但我现在的问题是:是否有更好、更“类似 zend”的方式来实现这一目标?

4

2 回答 2

4

感谢 SO 的相关主题,我终于找到了答案。ZF3 中的服务管理器

它似乎是通过使用控制器工厂来完成的,就像我一样。

于 2017-03-04T14:28:35.100 回答
0

ZF1经验丰富,现在正在学习ZF3,我想做一个简单的事情:在配置文件中设置DB配置,然后在控制器处获取db适配器。我花了一段时间才弄明白,因为官方文档有数百万种不同的定制选项。所以我发布我的答案来帮助任何人寻找。

1-在config/autoload/global.phpor中添加数据库凭据config/autoload/local.php,如下所示:

<?php
return [
    'db' => [
        'driver' => 'Pdo_Mysql',// can be "Mysqli" or "Pdo_Mysql" or other, refer to this link for the full list: https://docs.zendframework.com/zend-db/adapter/
        'hostname' => 'localhost',// optional
        'database' => 'my_test_db',
        'username' => 'root',
        'password' => 'root',
    ],
];

2- 在module/YOUR_MODULE_NAME/config/module.config.php中,在控制器工厂部分下添加:

return [
    //...
    'controllers' => [
        'factories' => [
            //...
            // Add these lines
            Controller\MycontrollernameController::class => function($container) {// $container is actually the service manager
                return new Controller\MycontrollernameController(
                    $container->get(\Zend\Db\Adapter\Adapter::class)
                );// this will pass the db adapter to the controller's constructor
            },
            //...
        ]
    ]
    //...
];

3-最后,在您的控制器module/YOUR_MODULE_NAME/src/Controller/MycontrollernameController中,您可以获取并使用 db 适配器:

<?php
namespace Application\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;

use Zend\Db\Adapter\Adapter;

class MycontrollernameController extends AbstractActionController
{

    private $db;

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

    public function indexAction()
    {
        $result = $this->db->query('SELECT * FROM `my_table`', Adapter::QUERY_MODE_EXECUTE);
        echo $result->count();// output total result
        return new ViewModel();
    }
}

还有另一种方法可以通过为控制器创建工厂来实现相同的目的,并在该工厂内部将数据库适配器传递给控制器​​。对于像我这样在 hello-world 级别尝试 ZF3 的初学者,我认为这太过分了。

于 2017-08-09T09:49:16.543 回答