2012-04-05 54 views
1

我目前正在參與一個更大的web應用用PHP和基於MVC的框架共享廣泛使用Zend框架相似的方面的開發應用級數據建築。正確的方式來處理需要在每一個網頁瀏覽

當用戶登錄我有一個應該顯示當前用戶的虛擬點的平衡的地方。此顯示需要位於每個控制器的每個頁面上。

在哪裏放置代碼以獲取sidewide modeldata,這不是控制器特定的,但需要在每個綜合瀏覽視圖的網站範圍佈局中獨立於當前控制器? MVC或ZF主管如何做到這一點?你其他人怎麼樣?

我想過在用戶登錄並將其存儲在會話中時加載餘額,但由於經常更改餘額,這看起來不正確 - 它需要在每次加載頁面時進行檢查和更新。我也想過通過向每個控制器添加抓取例程來做到這一點,但這看起來不對,因爲這會導致代碼重複。

+0

如果將所有的控制器使用它,也許你可以做一個基本的控制器,並從一個繼承...... – gosukiwi 2012-04-05 17:17:14

+0

@gosukiwi在可維護性方面,我不知道是否有方法獲取擴展當前控制器實現的方式是,以走。在這種情況下,正如Liyali所述,Action_Helpers通常在ZF環境中使用,但我不知道這些工作是否適合這項工作?我認爲在選擇的答案中描述的View_Helpers的使用更適合我的用例,其中只需要從模型層簡單獲取。 – oens 2012-04-06 09:24:17

回答

3

嗯,你說得對,有程序,以每個控制器將代碼複製,不會使你的代碼重用。

不像你的問題的意見建議,我就不會走了一個基本的控制器,因爲基地控制器是不是一個好的做法(在大多數情況下)和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在線文檔上有一個really good example about them here

有關自定義查看助手的更多信息here

當您執行此任務時,請考慮使用Zend_Cache組件,這樣您就不必在每次請求後查詢數據庫,而是說每分鐘(取決於您的需要)。

+0

非常想知道什麼。我會研究佔位符 - 我對這些知識不太瞭解。對於目前的應用程序,我將使用View_Helper方法,並沒有想過如何使用它們。關於Zend_Cache的細節,我們目前正在將緩存集成到模型層,因此這應該在完成時緩解輪詢問題。謝謝! – oens 2012-04-06 09:19:43

+0

不客氣;) – Liyali 2012-04-06 09:41:42

1

你在找什麼是Zend_Registry。當你認爲你需要某種形式的全局變量時,這是你應該使用的組件。如果你在每一頁都需要這個,那麼你最好把它加到你的引導程序中,如果你只在某些地方需要它,可以將它添加到相對控制器的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'); 

這凌晨片斷應該給你正確的想法!

+0

在我的理解中,bootstrap只是用於設置應用程序和初始化資源等。不是爲了實際獲取數據,我可能是錯的?其次,在註冊表中存儲各種任意的用戶數據是一種很好的做法嗎?我知道我只問過原始問題中的一個整數餘數,但是如果對全站數據的需求增加了,我認爲Zend_Registry將難以維護?因爲它對整個應用程序來說是全球性的,或者是什麼,所以在取得註冊信息時,取得的內容等等很難回答。 – oens 2012-04-06 09:19:55

+1

就我所知,引導程序用於將應用程序設置爲全局狀態。如果你知道你將在應用程序的某個地方的每個請求中都需要這個值,那麼我不會看到它的問題。然而,在發佈之後,我看到Liyalis發佈並贊成它,因爲這對你想要做的事情更有意義。我在標題中看到了整個應用程序的一部分,並沒有考慮視圖助手。 – 2012-04-06 09:49:40

1

在這種情況下,我通常會使用front controller plugindispatchLoopShutdown()鉤子執行所需的數據訪問並將數據添加到視圖/佈局。佈局腳本然後呈現該數據。

更多詳情可索取。

[更新]

假設你想從你的數據庫(或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; ?> 

明白我的意思?

+0

我是所有的耳朵,請詳細說明,如果你覺得它:) – oens 2012-04-08 15:30:06

+0

添加更多關於前端控制器插件的細節。 – 2012-04-09 03:23:55

+0

對不起,對於遲到的答案。這也是一個很好的方法,謝謝你的細節! Upvoted。 – oens 2012-04-22 10:08:30

相關問題