如何使用Zend Framework将数据库信息插入到布局中

时间:2011-05-12 18:26:11

标签: php zend-framework

我已经开始学习Zend Framework了。我已经完成了快速入门教程和akrabat教程。

现在我正在尝试使用Zend Framework开发一些自己的项目,至少可以说这是一个令人沮丧的经历。

我做了一个布局,创建了我的标准标题,显示在每个页面上。现在我想在从mysql数据库中检索的标题中显示用户名。我不知道该怎么做。我是否与布局中的控制器和模型进行交互?

此外,这类信息还有其他好的指南吗? zend文档似乎对每个组件都非常详细,但不太擅长解释事情如何协同工作。

5 个答案:

答案 0 :(得分:2)

在你的布局中你需要这个

 <?= $this->layout()->content ?>

这将从您的视图脚本中输出任何内容。

在项目结构中,您需要一个控制器和该控制器的视图脚本。如果您已完成本教程,您应该知道如何访问它。

您的控制器应该从数据库中获取用户名并将其分配给视图,如此

 $this->view->username = "John";

然后在你看来

 echo $this->username;

修改

在你的Bootstrap类中注册一个新的插件

 $plugin = new Default_Controller_Plugin_Username();

 Zend_Controller_Front::getInstance()->registerPlugin($plugin);

此插件可能如下所示

class Default_Controller_Plugin_Username 
      extends Zend_Controller_Plugin_Abstract 
             implements Lib_Observer_Observable
{
        public function preDispatch(Zend_Controller_Request_Abstract $request)        
        {
            //Do things in here to get username

            //Then you can set it in the registry           
            Zend_Registry::set("username", $username);
        }
}

答案 1 :(得分:1)

如果您拥有来自某种身份验证/登录顺序的$user,那么您可能正在使用Zend_Auth。身份数据的默认容器是基于会话的,因此根据您的会话处理设置,您可能不需要每次都访问数据库以获取该用户信息。

更重要的问题是,您是否需要一个前端控制器插件才能将此$user信息从Zend_Auth放入视图(在您的布局中呈现)或布局是否可以从{直接{1}}

我见过(和使用过)两者。

答案 2 :(得分:1)

您的问题是页面上的块组合问题。您可能知道Zend Framework只是一个框架,所以解决这个问题的方法真的不止一种。

要填充布局部分,您可以使用:

  • 包含块的变量并赋予每个控制器的视图(带有控制器插件?所有控制器都继承的主控制器?
  • 视图中的动作助手将内部调用链接到布局的这一部分中的另一个MVC调用
  • 操作堆
  • 肯定是其他事情

我认为最好的是动作堆栈。它的工作方式是:

  • 你在MVC-thing上做了一个主要的查询(你在控制器中调用了fooAction)
  • 在此Action中调用Action堆栈告诉ZF应该完成其他一些Action上的其他内部调用。在这里,您可以列出应在布局
  • 中填写的所有块
  • 其他bloack由内部MVC循环调用。调用其他一些barAction userAction入口点,在这些操作中,您可以通过 setResponseSegment 告诉布局布局的哪个键由生成的视图渲染填充。

以下是代码的外观:

对于阻止操作(这里是/ modulefoo / titi / pilili内部请求),应该填充布局的'foobar'块:

public function pilipiliAction() {
    (...) // do things
    $this->_helper->viewRenderer->setResponseSegment('foobar');
}

在布局上,您将使用以下内容回显此块:

<?= $this->foobar ?>

现在,您的主要操作必须调用此操作(使用Action Stack帮助程序)。但最好的方法是使用一个新的自定义帮助程序来堆叠所有块操作。

这是控制器上的fooAction,是您的经典切入点。在操作结束时,调用一个帮助程序,它应该构建布局的块

public function fooAction() {
    (...) // do things
    // Build Main layout
    $this->_helper->LayoutBuilder();    
}

这是一个这个帮助器会做什么的例子(应该工作,它是现有的一个简化版本,它可以生成许多其他东西,比如管理块的缓存):

class My_Action_Helper_LayoutBuilder extends Zend_Controller_Action_Helper_Abstract
{
    /**
    * @var $actionStack
    * local ActionStack builtin helper used to Stack several MVC actions,
    * for action for each Layout block
    */
    protected static $actionStack;

    /**
    * @var _layout
    * reference to the general layout collecting view
    */
    protected $_layout;

    public function __construct() {
        self::$actionStack = Zend_Controller_Action_HelperBroker::getStaticHelper('actionStack');
        $this->_layout = Zend_Layout::getMvcInstance();
    }

    public function direct($blocklist = null) {
        $layoutblocks = array(
            array('module' => 'default',
                'controller' => 'index',
                'action' => 'nav')
            ,
            array('module' => 'modulefoo',
                'controller' => 'titi',
                'action' => 'pilipili') // action given upper
            );
        $auth = Zend_Auth::getInstance();
        if ($auth->hasIdentity()) {
            $request = Zend_Registry::get('request');
            $module = $request->getModuleName();
            $layoutblocks[] = array('module' => $module,
                        'controller' => 'index',
                        'action' => 'modulenav');
        }
        if (isset($blocklist))
        { //user had his own blocklist to add
            $layoutblocks = array_merge($layoutblocks,$blocklist);
        }
        $this->buildCompositeLayout($layoutblocks);
    }

    public function buildCompositeLayout($blocklist = null) {
        foreach($blocklist as $MVCBlock) {
            $block = $MVCBlock['action'];
            if (!isset($MVCBlock['module'])) {
                $module  = $this->getRequest()->getModuleName();
                $front   = $this->getFrontController();
                $module = $front->getDispatcher()->getDefaultModule();
            } else {
                $module = $MVCBlock['module'];
            }
            if (!isset($MVCBlock['controller'])) {
                if (!isset($front)) {
                    $front   = $this->getFrontController();
                }
                $controller = $front->getDispatcher()->getDefaultController();
            } else {
                $controller = $MVCBlock['controller'];
            }
            // Here we stack actions
            self::$actionStack->actionToStack($block,
                   $controller,
                   $module,
            );
    }
}

但正如我之前所说,有不止一种方法可以做到这一点。我喜欢这种方式,因为我可以交互式地为一些请求添加新块,在块渲染中添加一些缓存,我也可以'忘记'调用LayoutBuilder 帮助器来执行某些操作,例如<强> ajax 的。秘诀是Zend Framework的MVC循环真的是一个循环;它可以为一个请求运行多个操作。

答案 3 :(得分:0)

Zend_Auth摇滚..你需要使用它。

这里有一个关于Zend_Auth的好教程:

http://akrabat.com/zend-auth-tutorial/

这包括创建View Helper以执行显示用户名,角色和注销链接的重复性任务的过程。

花点时间来掌握View Helpers ......在编写视图时,它们确实会破坏您的工作效率和代码重用。

邓肯。

答案 4 :(得分:0)

@Mike,来自@jakenoble的回答对你的场景来说是完全正确的。 如果你想在你的控制器中执行一些全局操作,那么我建议创建你自己的继承自Zend_Controller的基本控制器类,如MyBaseController。 然后你可以从MyBaseController继承你的所有控制器,这样在MyBaseController的init()方法中执行的所有操作都将全局到你的完整项目。