我已经开始学习Zend Framework了。我已经完成了快速入门教程和akrabat教程。
现在我正在尝试使用Zend Framework开发一些自己的项目,至少可以说这是一个令人沮丧的经历。
我做了一个布局,创建了我的标准标题,显示在每个页面上。现在我想在从mysql数据库中检索的标题中显示用户名。我不知道该怎么做。我是否与布局中的控制器和模型进行交互?
此外,这类信息还有其他好的指南吗? zend文档似乎对每个组件都非常详细,但不太擅长解释事情如何协同工作。
答案 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只是一个框架,所以解决这个问题的方法真的不止一种。
要填充布局部分,您可以使用:
我认为最好的是动作堆栈。它的工作方式是:
以下是代码的外观:
对于阻止操作(这里是/ 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()方法中执行的所有操作都将全局到你的完整项目。