gpt4 book ai didi

php - Zend Framework 2 模块在 Controller onBootstrap 之间共享变量

转载 作者:可可西里 更新时间:2023-11-01 13:35:48 25 4
gpt4 key购买 nike

是否可以在 Module.php 中创建变量甚至共享对象(如数据库适配器)以供所有 View Controller 使用? (Zend 框架 2)

例如:

class Module 
{
public function onBootstrap(MvcEvent $e)
{

$moduleConfig = $e->getServiceManager()->get('Config')
}
}

在 Controller 中,以某种方式访问​​:

$this->moduleConfig['db']

在上面我知道这只是数据库适配器的配置数组,但它如何工作?

我看到可以在 Controller 操作中执行此操作:

$config = $this->getServiceLocator()->get('Config')
$dba = new DbAdapter($config['db']);

我不想在每个需要配置的地方都这样做。我怎么能把它变成这样的: $this->config ??因此它适用于所有操作。更好的是,如何在整个模块中做到这一点?我知道我做错了,但在 ZF1 中我们有 Zend_Registry::get() 来处理像这样的简单事情。我正在阅读文档和那里的各种 tuts,但总是有一些假设,我只是迷路了。所以我真正想要的是:A)全局可访问的配置项,B) 全局可访问的数据库适配器

我只想在我的 Controller 中调用 $this->db 或 $this->config->item。这可能吗?我知道我错过了一些非常简单的东西。

我也尝试使用 $this->getServiceLocator()->get('Config'); 在我的 __construct 中设置 $this->config但我知道服务定位器在构建期间尚不可用。我尝试通过在模块的 onBootstrap 中设置 preDispatch 来做类似的事情,但我似乎无法将这些项目放入我的 Controller 中。

仅供引用,我的 global.php 中确实有这个(不,它不会留在那里,只是示例):

'db' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=mydb;host=localhost;',
'username' => 'root',
'password' => '',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),

),

我可以使用 getServiceLocator() 在任何操作中访问该项目和其他项目。我希望这些项目可用作我的 Controller 属性,如 $this->config->item 中。

感谢任何指导!谢谢!

最佳答案

好的...多部分回答。

1。在站点范围内添加配置变量。 (以及如何在 Controller 中访问)

这很简单,一旦我看到它起作用了。但是取决于下面的 preDispatch。在您的应用程序根目录中,将文件放入 config/autoload.称它为:things.config.local.php

在这个文件中,我们只返回一个包含配置项的数组。

<?php
return array(
'things' => array(
'avalue' => 'avalue1',
'boolvalue' => true,
),

);

所以我想在我的 Controller 中访问它。假设您在 Controller 中创建了一个配置属性,您可以通过这种方式访问​​它。 (您在下面的 preDispatch 中设置该属性以使其工作)在我的系统中,我更愿意像这样检索该值:

$this->config['things']['boolvalue'];

但是,您可以在这样的操作中调用它:

$config = $this->getServiceLocator()->get('Config');
echo $config['things']['boolvalue'];

其实这很容易。不确定如何使用 ini 文件执行此操作,但在我的情况下不需要它,而且我的 ini 文件直接移入数组也没什么大不了的。问题 1 为我解决了!

2。如何在 Controller 中获取 preDispatch(因为 __construct 不会加载配置)

我的另一个问题是我可以在全局级别访问某些对象和/或值,并在初始化 Controller 和操作时加载它们。据我了解,无法在 Controller 的 __construct 中访问服务管理器配置。

$this->getServiceLocator()->get('Config');

上面的方法是行不通的。我相信是因为 ServiceManager 在 Controller 类的构造过程中尚不可用。有道理。

虽然有几个额外的步骤,但我可以让 preDispatch 工作,类似于 ZF1。 然后 配置工作正常。以及访问全局对象,如数据库。

在 Controller 中添加以下方法:

protected function attachDefaultListeners()
{
parent::attachDefaultListeners();
$events = $this->getEventManager();
$this->events->attach('dispatch', array($this, 'preDispatch'), 100);
$this->events->attach('dispatch', array($this, 'postDispatch'), -100);
}

然后添加pre和post方法。

public function preDispatch (MvcEvent $e)
{
// this is a db convenience class I setup in global.php
// under the service_manager factories (will show below)
$this->db = $this->getServiceLocator()->get('FBDb');
// this is just standard config loaded from ServiceManager
// set your property in your class for $config (protected $config;)
// then have access in entire controller
$this->config = $this->getServiceLocator()->get('Config');
// this comes from the things.config.local.php file
echo "things boolvalue: " . $this->config['things']['boolvalue'];
}

public function postDispatch (MvcEvent $e)
{
// Called after actions
}

问题2解决了!初始化 Controller 。

3。如何将上述内容与 ServiceManager 结合使用以加载 DB 对象以在 Controller 中使用

好吧,我最不想做的就是全局访问我的数据库。我希望它在整个 Controller 范围内,这样我就可以在任何地方调用 $this->db->fetchAll。

首先在 global.php 中设置服务管理器。
另外,请记住,我不会像在我的 global.php 文件中那样保留它。但它现在有效。将这些数组添加到 global.php 中的返回数组:

'db' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=mydb;host=localhost;',
'username' => 'root',
'password' => '',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),

),
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter'
=> 'Zend\Db\Adapter\AdapterServiceFactory',
'db-adapter' => function($sm) {
$config = $sm->get('config');
$config = $config['db'];
$dbAdapter = new Zend\Db\Adapter\Adapter($config);
return $dbAdapter;
},
'FBDb' => function($sm) {
$dba= $sm->get('db-adapter');
$db = new FBDb\Db($dba);
return $db;
},

),
),

在上面,我设置了数据库配置,然后 service_manager 有一些工厂,这些工厂在应用程序的其余部分需要时可用。在我的例子中,我想要一些方便的向后兼容我的一些旧 ZF1 代码,所以我添加了一个名为 FBDb 的自定义模块。我发现了一个很棒的包装器/bridge-to-zf1-style-db 类,由 Fabrizio Balliano 称为​​ ZFBridge。非常适合我的需要,你可以在这里找到: https://github.com/fballiano/zfbridge

我接受了它,稍微修改了一下,然后制作了一个模块。因此 FBDb 对象在我的 Controller 中可用作我的数据库连接。如果我想在其他地方使用它,则与“db-adapter”相同。

无论如何,在我的 Controller 中,我设置了“protected $db;”在类(class)开始时,我可以使用该属性。然后如上面的 #2 所示,我让 preDispatch 将 FBDb 数据库对象分配给 $this->db。

$this->db = $this->getServiceLocator()->get('FBDb');

然后在我的操作方法中,如果我愿意,我可以用这个调用记录集或数据库值:

$sql = 'select * from customer where cust_nbr between ? and ?';
$rs = $this->db->fetchResults($sql, array('120400', '125250'));

或者,对于返回的数组:

$rs = $this->db->fetchAll($sql, array('120400', '125250'));

(我将 fetchResults 添加到 ZFBridge 以仅从数据库查询返回 PDO\Results 对象,以便稍后在 foreach 中使用。)

我知道其中一些可能是糟糕的设计或“糟糕的 OOP”,但它对我有用而且我喜欢它。我个人不喜欢对所有事情都使用基于纯对象的数据实体,只是一些事情。大多数时候,我只想放入一个结果集并完成它。 :)

问题解决了。目前。如果您习惯了 ZF1,现在让 ZF2 更加友好。

关于php - Zend Framework 2 模块在 Controller onBootstrap 之间共享变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14128085/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com