0

views\scripts我的header.phtml文件中,放置了有关用户的信息:姓名、姓氏、照片

现在我必须在每个控制器构造函数中从数据库中获取这些数据,也许是使用抽象类或其他东西的更好解决方案?

因为很难在每个控制器构造函数中放置相同的代码。

4

3 回答 3

2

定义一个 BaseController,把每个控制器需要做的事情放在那里,然后用你的常规控制器扩展它......

于 2013-07-23T12:31:35.477 回答
2

是的,有两个推荐的解决方案,第一个是制作一个插件(http://framework.zend.com/manual/1.12/en/zend.controller.plugins.html),例如在你的引导程序中加载并且会做每个请求的某些内容,如果您想做的仅适用于少数操作,您可以创建一个操作帮助程序(http://framework.zend.com/manual/1.12/en/zend.controller.actionhelpers.html)。

在您的情况下,我将创建一个 frontController 插件,例如在 dispatchLoopStartup 上将用户数据存储在注册表中,然后在您的视图中,您从注册表中检索该数据并回显它。为了减少数据库请求的数量,插件可以使用用户会话来存储信息,因此只有对您站点的第一个请求才会触发数据库查询,或者在登录时将用户数据放入会话中。

我不建议使用 baseController,因为这不是最佳实践,您必须编辑所有控制器以告诉他们扩展 baseController,出于同样的原因,我也不会使用所有控制器的 init 函数,通过使用您需要做的就是在您的 boostrap 中初始化它,然后在您的标题视图部分中从注册表中检索数据

插件的名称以您的库目录的名称开头,然后是您可能拥有的任何子文件夹,最后一个下划线之后是您的类的名称,这就是自动加载器通过用斜杠或反斜杠替换下划线来找到您的插件的原因取决于您的操作系统以获得正确的路径

header.phtml:

<?php 
// test if userData is there
Zend_Debug::dump($userData);

引导程序.php:

<?php

// add the namespace of your library directory
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->registerNamespace('MyLibrary_');
// register header plugin
$front = Zend_Controller_Front::getInstance();
$front->registerPlugin(new headerUserDataPlugin());

如果您的目录结构与此不同,请将以下插件放入正确的文件夹并调整插件类名称,例如您的 Library 文件夹可能不称为“myLibrary”:

application/
        configs/
            application.ini
        forms/
        layouts/
        modules/
        views/
        Bootstrap.php
    library/
        Zend/
        MyLibrary/
            Controller/
                Plugin/
                    HeaderUserDataPlugin.php
    public/
        index.php

HeaderUserDataPlugin.php:

<?php

/**
 * header user data plugin
 *
 **/
class MyLibrary_Controller_Plugin_HeaderUserDataPlugin extends Zend_Controller_Plugin_Abstract {

    public function routeShutdown(Zend_Controller_Request_Abstract $request) {

        // at this point you can retrieve the user id from session
        $mysession = new Zend_Session_Namespace('mysession');

        // is there a userId in the session
        if (!isset($mysession->userId)) {

            $userId = $mysession->userId;

            // get userData from user model
            $userModel = new UserModel();
            $userData = UserModel->getUserData($mysession->userId);

            Zend_Registry::set('user_data', $userData);

        }

    }

}

我没有测试代码,可能有一些拼写错误:S

于 2013-07-23T13:51:09.193 回答
1

如果我正确理解了这个问题,您想在每个控制器构造中使用相同的查询调用 DB,为视图变量分配返回的结果并将它们打印在 header.phtml 中。如果这是您想要的,请继续阅读。

如果内存不是问题,更简单的方法是在引导程序中使用Zend_Registry将所需数据的 json 编码数组存储在注册表中。这样,您只需要对 DB 进行 1 次查询。

引导程序.php

$row = $db->fetchRow("SELECT name, surname, url FROM people WHERE id = '127'");
$userData = array('name' => $row ['name'], 'surname' => $row ['surname'], 'photo' => $row ['url']);
Zend_Registry::set('user_data', json_encode($userData));

现在,您不需要将此代码放在任何控制器中。只需制作一个从所需属性读取Zend_Registry并返回所需属性的视图助手。您可以header.phtml直接从您的电话中调用它。

/views/helpers/User.php

class Zend_View_Helper_User
{
    public function user($property)
    {
        $userData = Zend_Registry::get('user_data');
        $userData = json_decode($userData, true);
        return $userData[$property];
    }
}

header.phtml

<p><?=$this->user('name')?> <?=$this->user('surname')?></p>
<img src="<?=$this->user('photo')?>"/>
于 2013-07-23T14:40:59.170 回答