2013-06-24 43 views
8

在幾乎所有教程或SO上的答案中,我都看到將數據從Controller發送到View的常用方法,View類通常看起來類似於以下代碼:將數據從控制器傳遞到PHP MVC應用程序中的視圖

class View 
{ 
    protected $_file; 
    protected $_data = array(); 

    public function __construct($file) 
    { 
     $this->_file = $file; 
    } 

    public function set($key, $value) 
    { 
     $this->_data[$key] = $value; 
    } 

    public function get($key) 
    { 
     return $this->_data[$key]; 
    } 

    public function output() 
    { 
     if (!file_exists($this->_file)) 
     { 
      throw new Exception("Template " . $this->_file . " doesn't exist."); 
     } 

     extract($this->_data); 
     ob_start(); 
     include($this->_file); 
     $output = ob_get_contents(); 
     ob_end_clean(); 
     echo $output; 
    } 
} 

我不明白爲什麼我需要把數據放入數組然後調用extract($ this - > _ data)。 爲什麼不乾脆直接就把一些屬性到視圖從控制器類似

$this->_view->title = 'hello world'; 

然後在我的佈局或模板文件我可能只是這樣做:

echo $this->title; 

回答

7

它從邏輯上合理地分組視圖數據並區分它與內部視圖類屬性。

PHP將允許您動態分配屬性,以便您可以實例化View類並將視圖數據分配爲屬性。我個人不會推薦這個。如果你想迭代視圖數據,或者只是簡單地轉儲它以進行調試呢?

將視圖數據存儲在數組中或包含對象不意味着您必須使用$this->get('x')來訪問它。一個選項是使用PHP5的Property Overloading,這將允許您將數據作爲數組存儲,但與模板中的數據具有$this->x接口。

例子:

class View 
{ 
    protected $_data = array(); 
    ... 
    ... 

    public function __get($name) 
    { 
     if (array_key_exists($name, $this->_data)) { 
      return $this->_data[$name]; 
     } 
    } 
} 

,如果你試圖訪問一個不存在的屬性的__get()方法將被調用。所以,你現在可以做:

$view = new View('home.php'); 
$view->set('title', 'Stackoverflow'); 

在模板:

<title><?php echo $this->title; ?></title> 
+1

非常感謝你的摘錄,真棒!) – Matthew

1

我的猜測,其原因可能是簡單的「少打字「但有一些很不錯的副作用:

  • 幫助時,那些寫模板不熟悉PHP和這種方式,他們沒有與關注」什麼C這個$this->是什麼意思?「。
  • 爲變量提供單獨的容器也有助於在視圖的某些屬性應該是該類的私有屬性時,庫編寫者不希望將它們暴露給模板編寫者
  • 防止與名稱衝突視圖的屬性和模板的變量。
  • 比基於方法的訪問方案快得多。現在可能不像Smarty創建時那麼重要(也可以使用php4)。
+0

同意爲點1和點3,而對於你的第二個問題,我不認爲容器允許隱藏私人View的屬性,您仍然可以執行$ this-> somePrivateProperty,因爲該文件是從View類包含的(請參閱上面的代碼)。 – Matthew

+0

當然,當然,但至少這樣它看起來應該與應該訪問的「正常」變量有明顯區別。 – complex857

+0

好吧,我明白了你的觀點:) – Matthew

相關問題