Neil的備忘錄

          just do it
          posts - 66, comments - 8, trackbacks - 0, articles - 0

          通常在我們利用ZF實現php的mvc時,最關鍵的地方當然是Controller類的各種action方法,在action方法中,我們確定及輸 出內容. 在類 abstract class Zend_Controller_Action 中的dispatch方法你可以發現這一行 $this->$action();

          那么如何確定及輸出內容呢,就是進行render了,不過這個render卻是有好幾個的,下面列出這幾個情形
          1<?php
          2class IndexController extends Zend_Controller_Action
          3{
          4 public function contactAction()
          5 {
          6 //$this->render(“index”);
          7 //$this->render();
          8 //$this->renderScript(“sidebar.phtml”);
          9
          10
          11 //$this->_helper->viewRenderer(“sidebar”);
          12
          13 //$this->view->render(“sidebar.phtml”);
          14 //$this->view(“sidebar”);
          15
          16 }
          17}
          18?>

          總結下來,似乎就是這三中render了(歡迎補充)

          1.自身render

          先看第一種
          //$this->render(“index”);
          //$this->render();
          //$this->renderScript(“sidebar.phtml”);
          這是直接使用Zend_Controller_Action類的render方法
          第一句是render了另一個action所對應的視圖(看清了 是render那個action對應的視圖 而不是執行那個action!)
          第二句式render本action對應的視圖,這個有什么意義呢(因為很多情形你看不到這個寫法的),這個下面再說.
          第三句是render特定的視圖文件,這里你可能認為前兩個方法實際是調用了這個renderScript,其實不是如此.
          下面就闡述一下.順便解釋第二句的原因.
          Zend_Controller_Action類的render方法中其實是有兩個分支的 如下render函數代碼
          1 public function render($action = null, $name = null, $noController = false)
          2 {
          3 if (!$this->getInvokeArg(noViewRenderer) && $this->_helper->hasHelper(viewRenderer)) {
          4 return $this->_helper->viewRenderer->render($action, $name, $noController);
          5 }
          6
          7 $view = $this->initView();
          8 $script = $this->getViewScript($action, $noController);
          9
          10 $this->getResponse()->appendBody(
          11 $view->render($script),
          12 $name
          13 );
          14 }
          可以看到一種情形是利用(代理)了視圖助手類(viewRenderer)的render方法
          另一種是禁用助手時的情形 就得親自上陣了,這也就是render()出現的原因,你禁用了視圖助手后要輸出本action對應視圖內容可以使用render()來完成

          2.通過視圖助手viewRenderer

          上面說起了視圖助手,那我們來看action中的第二個片段,正是借助視圖助手來進行
          //$this->_helper->viewRenderer(“sidebar”);
          實際上這里這句話并不是render內容,而是指定了要render哪個視圖,參考 Zend_Controller_Action_Helper_ViewRenderer類的這個函數
          1 public function direct($action = null, $name = null, $noController = null)
          2 {
          3 $this->setRender($action, $name, $noController);
          4 }
          那么輸出呢 是怎么輸出的?
          可以在$this->_helper->viewRenderer(“sidebar”); 后直接調用$this->render();即可.
          但是實際上你完全不用調用,只寫那一句就行.
          你不寫render的時候,視圖助手會來替你完成.在Zend_Controller_Action類中的dispatch方法中有這么一句
          $this->_helper->notifyPostDispatch();
          _helper是什么? 是一個Zend_Controller_Action_HelperBroker類 ,其中有這個方法
          1 public function notifyPostDispatch()
          2 {
          3 foreach (self::getStack() as $helper) {
          4 $helper->postDispatch();
          5 }
          6 }

          可以看到調用了其中各個助手的postDispatch();
          而viewRenderer正是其中的一個助手,其postDispatch方法如下
          1 public function postDispatch()
          2 {
          3 if ($this->_shouldRender()) {
          4 $this->render();
          5 }
          6 }
          正是在這里視圖助手幫你進行了render,如果你自己render了,聰明的視圖助手會知曉的,可以查看下在_shouldRender()中的這個 $this->getRequest()->isDispatched(),及Zend_Controller_Front 類中dispatch方法的這句話:$this->_request->setDispatched(true);

          3.終極render 關于Zend_View->render()

          好了現在我們來看看Zend_View的render().
          在上面的兩個中我們都說到了render(),比如action的render和視圖助手的render
          那么你該問個問題:就這樣了?后面呢?
          后面的才是關鍵的.
          在action的render中,你可能注意到這句話了
          10 $this->getResponse()->appendBody(
          11 $view->render($script),
          12 $name
          13 );
          而我們再看看viewRenderer的render(),viewRenderer的render方法其實是調用了renderScript方法,代碼 如下
          1 public function renderScript($script, $name = null)
          2 {
          3 if (null === $name) {
          4 $name = $this->getResponseSegment();
          5 }
          6
          7 $this->getResponse()->appendBody(
          8 $this->view->render($script),
          9 $name
          10 );
          11
          12 $this->setNoRender();
          13 }
          可以看到這里跟action的render有點類似,也有同樣的那句話.
          就是說action的render和viewRenderer的render其實都是調用Zend_View的render,拿到內容而后置放到 response中

          Zend_View的render:
          1 public function render($name)
          2 {
          3 // find the script file name using the parent private method
          4 $this->_file = $this->_script($name);
          5 unset($name); // remove $name from local scope
          6
          7 ob_start();
          8 $this->_run($this->_file);
          9
          10 return $this->_filter(ob_get_clean()); // filter output
          11 }

          至于run:
          1 protected function _run()
          2 {
          3 if ($this->_useViewStream && $this->useStreamWrapper()) {
          4 include zend.view:// . func_get_arg(0);
          5 } else {
          6 include func_get_arg(0);
          7 }
          8 }

          那么你就明白了最開始代碼中的第13行
          13 //$this->view->render(“sidebar.phtml”);
          其實是個幌子,哈.這句話只是得到了內容,但是呢 沒做處理!
          所以我們應該這樣
          13 echo $this->view->render(“sidebar.phtml”);
          再然后呢?參看Zend_Controller_Front類dispatch
          $this->_response->sendResponse();
          及Zend_Controller_Response_Abstract類
          1 public function outputBody()
          2 {
          3 foreach ($this->_body as $content) {
          4 echo $content;
          5 }
          6 }

          而至于第14行
          14 //$this->view(“sidebar”);
          貌似合理,瞪一眼就知道了:這句話地地道道的錯誤
          action 中沒有這個方法,__call中也沒有相應處理,不象_helper->viewRenderer(“sidebar”);在 _helper針對該情況在__call中有相應處理
          1 public function __call($method, $args)
          2 {
          3 $helper = $this->getHelper($method);
          4 if (!method_exists($helper, direct)) {
          5 require_once Zend/Controller/Action/Exception.php;
          6 throw new Zend_Controller_Action_Exception(Helper ” . $method .“ does not support overloading via direct());
          7 }
          8 return call_user_func_array(array($helper, direct), $args);
          9 }
          沒有viewRenderer這個方法,于是去尋找名為viewRenderer并且有direct方法的助手,找到了即執行這個direct方法(上面 第二部分貼過代碼了)
          至于viewRenderer這個助手存放時,要注意到他的名字是死的 就是”viewRenderer”,具體看Zend_Controller_Action_Helper_Abstract類的getName方法
          1 public function getName()
          2 {
          3 $full_class_name = get_class($this);
          4
          5 if (strpos($full_class_name, _) !== false) {
          6 $helper_name = strrchr($full_class_name, _);
          7 return ltrim($helper_name, _);
          8 } else {
          9 return $full_class_name;
          10 }
          11 }
          之所以提到這點是因為在Zend_Controller_Action_Helper_ViewRenderer注釋中你能看到這句話
          // In your action controller methods:
          $viewHelper = $this->_helper->getHelper(‘view’);
          而實際上你復制這句話到your action controller methods中去 只會出錯
          Exception information:

          Message: Action Helper by name View not found

          個人感覺php Zend Framework還是很不錯,雖然一直沒搞好調試器
          但是非常滿意于可以隨處置放var_dump


          只有注冊用戶登錄后才能發表評論。


          網站導航:
          博客園   IT新聞   Chat2DB   C++博客   博問  
           
          主站蜘蛛池模板: 麦盖提县| 保定市| 襄城县| 永善县| 潞西市| 婺源县| 亚东县| 西乌珠穆沁旗| 萝北县| 布尔津县| 闻喜县| 绥芬河市| 舞阳县| 桦川县| 罗田县| 阜康市| 新竹市| 镇宁| 边坝县| 彭阳县| 三台县| 衡阳市| 栖霞市| 皋兰县| 阳新县| 灵璧县| 永年县| 盐亭县| 桦甸市| 商洛市| 阳新县| 左贡县| 星座| 通城县| 桓仁| 昔阳县| 定南县| 金溪县| 鹤山市| 襄樊市| 潍坊市|