如何在 zend framework 3 的控制器中获取服务管理器实例?
How to get a service manager instance in a controller in zend framework 3?
我正在尝试在我的控制器中获取一个 ServiceManager 实例,以将工厂用于 Db\Adapter。
我添加到module/Application/config/module。config.php:
'service_manager' => [
'factories' => [
Adapter::class => AdapterServiceFactory::class,
],
],
到config/autoload/local.php我添加了以下几行:
'db' => [
'driver' => 'Mysqli',
'database' => 'mydb',
'username' => 'myuser',
'password' => 'mypassword',
]
现在我想访问 module/Application/src/Controller/IndexController.php 中的 ServiceManager。我该怎么做?
我尝试了 $sm = $this->getPluginManager();
但没有成功。如果我使用 PluginManager 运行 $serviceManager->get(Adapter::class)
它会给我一个错误:
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);
},
],
],
我还向模块添加了一个 getServiceConfig() 方法。config.php 并向接收 ServiceManager 的 IndexController 添加了一个构造函数。现在我可以访问控制器内部了。
但我现在的问题是:是否有更好、更 "zend like" 的方法来实现这一点?
感谢 SO 的相关主题,我终于找到了答案。
好像是用Controller Factories做的,跟我做的差不多
我对ZF1有经验,现在正在学习ZF3,我想做一件简单的事情:在配置文件中设置数据库配置,然后在控制器上获取数据库适配器。我花了一段时间才弄清楚,因为官方文档有数百万种不同定制的选项。所以我发布了我的答案以帮助任何人寻找。
1- 在 config/autoload/global.php
或 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
中,您可以获取并使用数据库适配器:
<?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 的初学者,我认为这太多了。
我正在尝试在我的控制器中获取一个 ServiceManager 实例,以将工厂用于 Db\Adapter。
我添加到module/Application/config/module。config.php:
'service_manager' => [
'factories' => [
Adapter::class => AdapterServiceFactory::class,
],
],
到config/autoload/local.php我添加了以下几行:
'db' => [
'driver' => 'Mysqli',
'database' => 'mydb',
'username' => 'myuser',
'password' => 'mypassword',
]
现在我想访问 module/Application/src/Controller/IndexController.php 中的 ServiceManager。我该怎么做?
我尝试了 $sm = $this->getPluginManager();
但没有成功。如果我使用 PluginManager 运行 $serviceManager->get(Adapter::class)
它会给我一个错误:
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);
},
],
],
我还向模块添加了一个 getServiceConfig() 方法。config.php 并向接收 ServiceManager 的 IndexController 添加了一个构造函数。现在我可以访问控制器内部了。
但我现在的问题是:是否有更好、更 "zend like" 的方法来实现这一点?
感谢 SO 的相关主题,我终于找到了答案。
好像是用Controller Factories做的,跟我做的差不多
我对ZF1有经验,现在正在学习ZF3,我想做一件简单的事情:在配置文件中设置数据库配置,然后在控制器上获取数据库适配器。我花了一段时间才弄清楚,因为官方文档有数百万种不同定制的选项。所以我发布了我的答案以帮助任何人寻找。
1- 在 config/autoload/global.php
或 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
中,您可以获取并使用数据库适配器:
<?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 的初学者,我认为这太多了。