使用“singleton”的Laravel 4视图编辑器


Laravel 4 view composer with "singleton"

我使用视图编写器来创建我的网站的导航结构。导航中的一些链接是动态的,需要几个DB查询。一切都很好,然而,这些DB查询执行多次,如果我注册的视图编写器与多个视图加载在同一页面上(例如:一个主要的导航视图和辅助侧边栏视图)。这是因为Laravel在每次创建一个视图时都会实例化我的Navigation类,这是预期的行为。

但是,我想消除这些重复的查询。我的第一个想法是实现某种单例模式,但由于Laravel的视图作曲家的工作方式,这行不通。有什么方法可以模拟单例模式吗?或者可能有更好的方法来消除这些重复的数据库查询(忽略HTML/文件缓存)?

下面是我为喜欢视觉效果的人所做的快速片段:

查看编辑器注册:

View::composer(array('layouts.nav', 'layouts.sidebar'), ''Namespace'ViewComposers'Navigation');

/命名空间/ViewComposers/Navigation.php:

public function compose(View $view)
{
    $navigation = array();
    ...
    // Some code that requires DB queries
    ... 
    $view->navigation = $navigation;
}

/视图/布局/nav.blade.php:

@foreach($navigation as $nav)
    ...
@endforeach

/视图/布局/sidebar.blade.php:

@foreach($navigation as $nav)
    ...
@endforeach

有许多方法可以做到这一点,但其中一种方法是将编写器注册为IoC容器的单例。这是因为视图编写器是从IoC容器中解析出来的。

App::singleton('MyProject'MyComposer');
namespace MyProject;
class MyComposer
{
    protected $navigation;
    public function compose($view)
    {
        $view->navigation = $this->getNavigation();
    }
    public function getNavigation()
    {
        if ($this->navigation !== null) {
            return $this->navigation;
        }
        $results = ...;
        return $this->navigation = $results;
    }
}

其他解决方案我不会在这里概述,而是依赖注入一个存储库/服务缓存结果在内存中,并使用查询生成器的remember()方法与数组缓存驱动程序。