2011-06-25 63 views
1

我不太確定如何提出這個問題。基本上我試圖讓我的視圖對象是一個從Smarty對象擴展的單例。然後我希望能夠將視圖對象擴展到我的控制器對象。擴展PHP Smarty Singleton類

View對象會將我想要的模板變量分配給我的所有控制器。

我知道我現在有什麼問題,但如果有人能指引我朝着正確的方向發展,那將會很棒。我試圖盡最大努力說出這些。

<?php 

defined('SITE_ROOT') ? null : define('SITE_ROOT', $_SERVER['DOCUMENT_ROOT'].'/mvcsandbox'); 

require_once('Smarty/Smarty.class.php'); 

class View extends Smarty { 

    public static $instance=NULL; 

    public static function getInstance(){ 

     if (self::$instance === null){ 
      self::$instance = new self(); 
     } 
     return self::$instance; 
    } 

    public function __construct() { 

     $this->template_dir = SITE_ROOT.'/Library/tmp/'; 
     $this->compile_dir = SITE_ROOT.'/Library/tmp/'; 
     $this->config_dir = SITE_ROOT.'/Library/tmp/'; 
     $this->cache_dir = SITE_ROOT.'/Library/tmp/'; 

     $this->assign("var1", "This is from the view class"); 

    } 

    public static function output() { 

     self::display('test.tpl'); 

    } 

} 

class Controller1 extends View { 

    public function init() { 
     $this->assign("var2", "This is from the Controller1 class"); 
    } 

} 

class Controller1_index extends Controller1 { 

    public function init() { 
     $this->assign("var3", "This is from the Controller1_index class"); 
    } 

} 

//$view = View::getInstance(); 
$controller1 = Controller1::getInstance(); 
$controller1_index = Controller1_index::getInstance(); 

$controller1->init(); 
//$controller1_index->init(); 

$controller1->output(); 

?>

+1

我認爲你的意思是「單身人士」:D雖然這個比喻很引人注目。 – Halcyon

+1

是的,「Simpleton」引用是我很好的觸摸,儘管我會誠實地建議你放棄Smarty並嘗試使用[PHP的本機功能](http://codeangel.org/articles/simple-php-template-engine .html)在模板中。 –

回答

5

您控制器不應該延長IEW ..它應該給視圖提供數據。你也可能不會有多個控制器用於不同的事情,並且在任何時候你可能需要從另一個控制器中重新獲得這些控制器的邏輯,所以使基本控制器成爲一個單獨的控制器不是一個好主意。而是使用一個單獨的前端控制器,然後使用實際處理模塊特定控制器邏輯的動作控制器。

class Controller { 
    // put any shared logic between all controllers here 

} 

class FrontController extends Controller { 

    protected $request; // a model representing and http request 
    protected $response; // a model representing a http response 
    protected $view; // the view instance 
    protected static $instance; // the FrontController instance 

    protected function __construct(); 

    public static function getInstance(); 

    public function getRequest(); 

    public function getResponse(); 

    public function getView(); 

    public function execute($args); 


} 

class View { 
    protecect $engine; 

    public function __Construct($options) 
    { 
    // $options could contain overrides for smarty config 
    $options = array_merge(array(
     'template_dir' = SITE_ROOT.'/Library/tmp/', 
     'compile_dir' = SITE_ROOT.'/Library/tmp/', 
     'config_dir' = SITE_ROOT.'/Library/tmp/', 
     'cache_dir' = SITE_ROOT.'/Library/tmp/', 
    ), $options); 

    $this->engine = new Smarty(); 

    foreach($options as $name => $value){ 
     $this->engine->$name = $value; 
    } 
    } 

    public function getEngine(){ 
     return $this->engine; 
    } 

    // proxy method calls and accessors not directly defined on 
    // the View to the Smarty instance 

    public function __get($key) 
    { 
    return $this->engine->$key; 
    } 

    public function __set($key, $value){ 
    $this->engine->$key = $value; 
    return $this; 
    } 

    public function __call($method, $args){ 
    if(is_callable(array($this->engine, $method)){ 
     return call_user_func_array(array($this->engine, $method)); 
    } 
    } 

    public function render(){ 
    // render the entire smarty instance 
    } 

} 

class ActionController extends Controller 
{ 
    protected $view; 

    public function init(); 

    public function setRequest(); 

    public function getRequest(); 

    public function getResponse(); 

    public function execute($request, $response); 

    public function getView(); 

    public function __get($key){ 
    return $this->view->$key; 
    } 

    public function __set($key, $value){ 
    $this->view->$key = $value; 
    } 
} 

所以,你的index.php會打電話FrontController::getInstance()->execute();注入任何選項請求生命週期,它需要通過選項來注入到execute。構造函數將預先配置一個視圖,請求和響應實例。執行將決定加載和運行的ActionController。它將加載該操作控制器並設置視圖,然後確定該操作控制器內的哪個操作需要運行並執行。

您的操作控制器執行後,您的前端控制器會調用View::render()這將返回完整的html字符串輸出到瀏覽器並將其設置爲響應對象上的內容以及使用該響應對象上的方法來設置像標題和餅乾,什麼不是。然後前控制器會在響應對象上調用sendResponse之類的東西,然後將響應對象發送到瀏覽器。

+0

非常感謝!我確實改變了一點。使它更多地融合了我原來的想法和你給我展示的內容。 –