我目前正在参与一个更大的web应用用PHP和基于MVC的框架共享广泛使用Zend框架的相似之处在建筑方面的发展。
当用户已经登录我有一个应该显示当前用户的虚拟点的平衡的地方。 这显示必须跨越每一个控制器在每一页上。
你在哪里把代码获取sidewide modeldata,即不特定的控制器,但需要在整个站点的布局去每一个浏览量,独立于当前控制器的? 将如何MVC或ZF-头做到这一点? 又有怎样的,你休息吗?
我想到了加载平衡时,在用户登录并将其存储在会话,但作为平衡经常改变这似乎并不正确 - 它需要检查和更新几乎在每一页上的负载。 我也想过通过将常规取到每一个控制器做,但似乎并没有正确的无论是作为这将导致代码的重复数据删除。
嗯,你说得对,有程序,以每个控制器将代码复制,不会使你的代码重用。
不像你的问题的意见建议,我不会去为AA基地控制器,因为它们的基本控制器是不是一个好的做法(在大多数情况下)和Zend框架,以避免它们实现动作助手 。
如果你的局部视图是整个网站的,你为什么不只是写自己的自定义视图助手 ,并从您的视图助手获取模型中的数据? 然后,你可以从你的布局直接调用该视图助手。 在我看来,通过从视图模型获取数据不会破坏MVC设计模式可言,只要你不更新/编辑这些数据。
您可以在/视图中添加您的视图助手/助理/或在资料库(那么你就必须得注册您的视图助手路径):
class Zend_View_Helper_Balance extends Zend_View_Helper_Abstract
{
public function balance()
{
$html = '';
if (Zend_Auth::getInstance()->hasIdentity()) {
// pull data from your model
$html .= ...;
}
return $html;
}
}
请注意,您可以查看帮助也可以调用一个局部视图( render()
partial()
partialLoop()
如果你需要以特定的方式来格式化你的代码。
这是一个非常简单的例子,但对我来说已经足够为你的情况。 如果你想拥有这些数据更多的控制权,并可以修改取决于特定视图(或控制器),它(或没有),那么我建议你采取占位符看看。 Zend公司有一个关于他们真的很好的例子上的联机文档。
有关自定义视图助手更多的信息在这里 。
当您执行这样的任务,可以考虑使用Zend_Cache是组件,所以你就不必每次查询请求后,数据库,但让我们说,每分钟(根据您的需要)。
你要找的是合适的词汇 。 这是当你认为你需要某种形式的全局变量,你应该使用的组件。 如果你需要这个每一页上,那么你最好将它添加到你的引导,如果你只需要在某些地方它添加relavent控制器的init方法。
应用程序/ bootstrap.php中
public _initUserBalance()
{
$userId = Zend_Auth::getInstance()->getIdentity()->userId;
$user = UserService::getUser($userId);
Zend_Registry::set('balance', $user->getBalance());
}
应用/布局/ default.phtml
echo 'Balance = ' . Zend_Registry::get('balance');
这凌晨片断应该给你正确的想法!
在这种情况下,我通常与去前端控制器插件带有dispatchLoopShutdown()
执行所需的数据访问和数据添加到视图/布局钩。 布局脚本然后呈现这些数据。
可应要求提供更多细节。
[UPDATE]
假设你想你的布局中显示来自你的数据库(或Web服务或RSS订阅源)的最后一个X的新闻项目, 其独立的请求控制器 。
您的前端控制器插件可以看看在这样的application/plugins/SidebarNews.php
:
class My_Plugin_SidebarNews
{
public function dispatchLoopShutdown()
{
$front = Zend_Controller_Front::getInstance();
$view = $front->getParam('bootstrap')->getResource('view');
$view->sidebarNews = $this->getNewsItems();
}
protected function getNewsItems()
{
// Access your datasource (db, web service, RSS feed, etc)
// and return an iterable collection of news items
}
}
请确保你的前端控制器注册您的插件,通常在application/configs/application.ini
:
resource.frontController.plugins.sidebarNews = "My_Plugin_SidebarNews"
然后在你的布局,只是呈现像往常一样,也许在application/layouts/scripts/layout.phtml
:
<?php if (isset($this->sidebarNews) && is_array($this->sidebarNews) && count($this->sidebarNews) > 0): ?>
<div id="sidebarNews">
<?php foreach ($this->sidebarNews as $newsItem): ?>
<div class="sidebarNewsItem">
<h3><?= $this->escape($newsItem['headline']) ?></h3>
<p><?= $this->escape($newsItem['blurb']) ?></p>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
明白了吗?