正确的方式来处理需要在每个网页浏览应用程序范围内的数据(Correct way to deal wi

2019-09-16 08:42发布

我目前正在参与一个更大的web应用用PHP和基于MVC的框架共享广泛使用Zend框架的相似之处在建筑方面的发展。

当用户已经登录我有一个应该显示当前用户的虚拟点的平衡的地方。 这显示必须跨越每一个控制器在每一页上。

你在哪里把代码获取sidewide modeldata,即不特定的控制器,但需要在整个站点的布局去每一个浏览量,独立于当前控制器的? 将如何MVC或ZF-头做到这一点? 又有怎样的,你休息吗?

我想到了加载平衡时,在用户登录并将其存储在会话,但作为平衡经常改变这似乎并不正确 - 它需要检查和更新几乎在每一页上的负载。 我也想过通过将常规取到每一个控制器做,但似乎并没有正确的无论是作为这将导致代码的重复数据删除。

Answer 1:

嗯,你说得对,有程序,以每个控制器将代码复制,不会使你的代码重用。

不像你的问题的意见建议,我不会去为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是组件,所以你就不必每次查询请求后,数据库,但让我们说,每分钟(根据您的需要)。



Answer 2:

你要找的是合适的词汇 。 这是当你认为你需要某种形式的全局变量,你应该使用的组件。 如果你需要这个每一页上,那么你最好将它添加到你的引导,如果你只需要在某些地方它添加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');

这凌晨片断应该给你正确的想法!



Answer 3:

在这种情况下,我通常与去前端控制器插件带有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; ?>

明白了吗?



文章来源: Correct way to deal with application-wide data needed on every pageview