詳細介紹php Zend Framework中的render使用方法

來源:互聯網
上載者:User

http://www.pkphp.com/2010/01/09/zend-framework-render-intro/


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

那麼如何確定及輸出內容呢,就是進行render了,不過這個render卻是有好幾個的,下面列出這幾個情形
<?php
class IndexController extends Zend_Controller_Action
{
 public function contactAction()
 {
 //$this->render(“index”);
 //$this->render();
 //$this->renderScript(“sidebar.phtml”);


 //$this->_helper->viewRenderer(“sidebar”);

 //$this->view->render(“sidebar.phtml”);
 //$this->view(“sidebar”);

 }
}
?>

總結下來,似乎就是這三中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函數代碼
public function render($action = null, $name = null, $noController = false)
{
if (!$this->getInvokeArg(‘noViewRenderer‘) && $this->_helper->hasHelper(‘viewRenderer‘)) {
return $this->_helper->viewRenderer->render($action, $name, $noController);
}

$view = $this->initView();
$script = $this->getViewScript($action, $noController);

 $this->getResponse()->appendBody(
 $view->render($script),
 $name
 );
 }
可以看到一種情形是利用(代理)了視圖助手類(viewRenderer)的render方法
另一種是禁用助手時的情形 就得親自上陣了,這也就是render()出現的原因,你禁用了視圖助手後要輸出本action對應視圖內容可以使用render()來完成

2.通過視圖助手viewRenderer

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

可以看到調用了其中各個助手的postDispatch();
而viewRenderer正是其中的一個助手,其postDispatch方法如下
public function postDispatch()
{
if ($this->_shouldRender()) {
$this->render();
}
}
正是在這裡視圖助手幫你進行了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中,你可能注意到這句話了
 $this->getResponse()->appendBody(
 $view->render($script),
 $name
 );
而我們再看看viewRenderer的render(),viewRenderer的render方法其實是調用了renderScript方法,代碼如下
 public function renderScript($script, $name = null)
 {
 if (null === $name) {
 $name = $this->getResponseSegment();
 }

 $this->getResponse()->appendBody(
 $this->view->render($script),
 $name
 );

 $this->setNoRender();
 }
可以看到這裡跟action的render有點類似,也有同樣的那句話.
就是說action的render和viewRenderer的render其實都是調用Zend_View的render,拿到內容而後置放到response中

Zend_View的render:
 public function render($name)
 {
 // find the script file name using the parent private method
 $this->_file = $this->_script($name);
 unset($name); // remove $name from local scope

 ob_start();
 $this->_run($this->_file);

 return $this->_filter(ob_get_clean()); // filter output
 }

至於run:
protected function _run()
{
if ($this->_useViewStream && $this->useStreamWrapper()) {
include ‘zend.view://‘ . func_get_arg(0);
} else {
include func_get_arg(0);
}
}

那麼你就明白了最開始代碼中的第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類
public function outputBody()
{
foreach ($this->_body as $content) {
echo $content;
}
}

而至於第14行
14 //$this->view(“sidebar”);
貌似合理,瞪一眼就知道了:這句話地地道道的錯誤
action 中沒有這個方法,__call中也沒有相應處理,不象_helper->viewRenderer(“sidebar”);在 _helper針對該情況在__call中有相應處理
 public function __call($method, $args)
 {
 $helper = $this->getHelper($method);
 if (!method_exists($helper, ‘direct‘)) {
 require_once ‘Zend/Controller/Action/Exception.php‘;
 throw new Zend_Controller_Action_Exception(‘Helper ”‘ . $method .‘“ does not support overloading via direct()‘);
 }
 return call_user_func_array(array($helper, ‘direct‘), $args);
 }
沒有viewRenderer這個方法,於是去尋找名為viewRenderer並且有direct方法的助手,找到了即執行這個direct方法(上面第二部分貼過代碼了)
至於viewRenderer這個助手存放時,要注意到他的名字是死的 就是”viewRenderer”,具體看Zend_Controller_Action_Helper_Abstract類的getName方法
 public function getName()
 {
 $full_class_name = get_class($this);

 if (strpos($full_class_name, ‘_‘) !== false) {
 $helper_name = strrchr($full_class_name, ‘_‘);
 return ltrim($helper_name, ‘_‘);
 } else {
 return $full_class_name;
 }
 }
之所以提到這點是因為在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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.