多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php框架 > ZendFramework > Zend Framework教程-Zend_Controller_Action動作的基類

Zend Framework教程-Zend_Controller_Action動作的基類

來源:程序員人生   發布時間:2014-05-02 18:34:28 閱讀次數:4145次

Zend_Controller_Action的實現


            Zend Framework的動作控制器需要繼承Zend_Controller_Action,Zend_Controller_Action提供了動作控制器的基本功能,具體參考如下代碼:

Zend_Controller_Action_Interface

<?phpinterface Zend_Controller_Action_Interface{    /**     * Class constructor     *     * The request and response objects should be registered with the     * controller, as should be any additional optional arguments; these will be     * available via {@link getRequest()}, {@link getResponse()}, and     * {@link getInvokeArgs()}, respectively.     *     * When overriding the constructor, please consider this usage as a best     * practice and ensure that each is registered appropriately; the easiest     * way to do so is to simply call parent::__construct($request, $response,     * $invokeArgs).     *     * After the request, response, and invokeArgs are set, the     * {@link $_helper helper broker} is initialized.     *     * Finally, {@link init()} is called as the final action of     * instantiation, and may be safely overridden to perform initialization     * tasks; as a general rule, override {@link init()} instead of the     * constructor to customize an action controller's instantiation.     *     * @param Zend_Controller_Request_Abstract $request     * @param Zend_Controller_Response_Abstract $response     * @param array $invokeArgs Any additional invocation arguments     * @return void     */    public function __construct(Zend_Controller_Request_Abstract $request,                                Zend_Controller_Response_Abstract $response,                                array $invokeArgs = array());    /**     * Dispatch the requested action     *     * @param string $action Method name of action     * @return void     */    public function dispatch($action);}

 Zend_Controller_Action

<?php  require_once 'Zend/Controller/Action/HelperBroker.php'; require_once 'Zend/Controller/Action/Interface.php'; require_once 'Zend/Controller/Front.php'; abstract class Zend_Controller_Action implements Zend_Controller_Action_Interface{     protected $_classMethods;     protected $_delimiters;     protected $_invokeArgs = array();     protected $_frontController;     protected $_request = null;     protected $_response = null;     public $viewSuffix = 'phtml';     public $view;     protected $_helper = null;     public function __construct(Zend_Controller_Request_Abstract $request, Zend_Controller_Response_Abstract $response, array $invokeArgs = array())    {        $this->setRequest($request)             ->setResponse($response)             ->_setInvokeArgs($invokeArgs);        $this->_helper = new Zend_Controller_Action_HelperBroker($this);        $this->init();    }     public function init()    {    }     public function initView()    {        if (!$this->getInvokeArg('noViewRenderer') && $this->_helper->hasHelper('viewRenderer')) {            return $this->view;        }        require_once 'Zend/View/Interface.php';        if (isset($this->view) && ($this->view instanceof Zend_View_Interface)) {            return $this->view;        }        $request = $this->getRequest();        $module  = $request->getModuleName();        $dirs    = $this->getFrontController()->getControllerDirectory();        if (empty($module) || !isset($dirs[$module])) {            $module = $this->getFrontController()->getDispatcher()->getDefaultModule();        }        $baseDir = dirname($dirs[$module]) . DIRECTORY_SEPARATOR . 'views';        if (!file_exists($baseDir) || !is_dir($baseDir)) {            require_once 'Zend/Controller/Exception.php';            throw new Zend_Controller_Exception('Missing base view directory ("' . $baseDir . '")');        }        require_once 'Zend/View.php';        $this->view = new Zend_View(array('basePath' => $baseDir));        return $this->view;    }     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        );    }     public function renderScript($script, $name = null)    {        if (!$this->getInvokeArg('noViewRenderer') && $this->_helper->hasHelper('viewRenderer')) {            return $this->_helper->viewRenderer->renderScript($script, $name);        }        $view = $this->initView();        $this->getResponse()->appendBody(            $view->render($script),            $name        );    }     public function getViewScript($action = null, $noController = null)    {        if (!$this->getInvokeArg('noViewRenderer') && $this->_helper->hasHelper('viewRenderer')) {            $viewRenderer = $this->_helper->getHelper('viewRenderer');            if (null !== $noController) {                $viewRenderer->setNoController($noController);            }            return $viewRenderer->getViewScript($action);        }        $request = $this->getRequest();        if (null === $action) {            $action = $request->getActionName();        } elseif (!is_string($action)) {            require_once 'Zend/Controller/Exception.php';            throw new Zend_Controller_Exception('Invalid action specifier for view render');        }        if (null === $this->_delimiters) {            $dispatcher = Zend_Controller_Front::getInstance()->getDispatcher();            $wordDelimiters = $dispatcher->getWordDelimiter();            $pathDelimiters = $dispatcher->getPathDelimiter();            $this->_delimiters = array_unique(array_merge($wordDelimiters, (array) $pathDelimiters));        }        $action = str_replace($this->_delimiters, '-', $action);        $script = $action . '.' . $this->viewSuffix;        if (!$noController) {            $controller = $request->getControllerName();            $controller = str_replace($this->_delimiters, '-', $controller);            $script = $controller . DIRECTORY_SEPARATOR . $script;        }        return $script;    }     public function getRequest()    {        return $this->_request;    }     public function setRequest(Zend_Controller_Request_Abstract $request)    {        $this->_request = $request;        return $this;    }     public function getResponse()    {        return $this->_response;    }     public function setResponse(Zend_Controller_Response_Abstract $response)    {        $this->_response = $response;        return $this;    }     protected function _setInvokeArgs(array $args = array())    {        $this->_invokeArgs = $args;        return $this;    }     public function getInvokeArgs()    {        return $this->_invokeArgs;    }     public function getInvokeArg($key)    {        if (isset($this->_invokeArgs[$key])) {            return $this->_invokeArgs[$key];        }        return null;    }     public function getHelper($helperName)    {        return $this->_helper->{$helperName};    }     public function getHelperCopy($helperName)    {        return clone $this->_helper->{$helperName};    }     public function setFrontController(Zend_Controller_Front $front)    {        $this->_frontController = $front;        return $this;    }     public function getFrontController()    {        // Used cache version if found        if (null !== $this->_frontController) {            return $this->_frontController;        }        // Grab singleton instance, if class has been loaded        if (class_exists('Zend_Controller_Front')) {            $this->_frontController = Zend_Controller_Front::getInstance();            return $this->_frontController;        }        // Throw exception in all other cases        require_once 'Zend/Controller/Exception.php';        throw new Zend_Controller_Exception('Front controller class has not been loaded');    }     public function preDispatch()    {    }     public function postDispatch()    {    }     public function __call($methodName, $args)    {        require_once 'Zend/Controller/Action/Exception.php';        if ('Action' == substr($methodName, -6)) {            $action = substr($methodName, 0, strlen($methodName) - 6);            throw new Zend_Controller_Action_Exception(sprintf('Action "%s" does not exist and was not trapped in __call()', $action), 404);        }        throw new Zend_Controller_Action_Exception(sprintf('Method "%s" does not exist and was not trapped in __call()', $methodName), 500);    }     public function dispatch($action)    {        // Notify helpers of action preDispatch state        $this->_helper->notifyPreDispatch();        $this->preDispatch();        if ($this->getRequest()->isDispatched()) {            if (null === $this->_classMethods) {                $this->_classMethods = get_class_methods($this);            }            // If pre-dispatch hooks introduced a redirect then stop dispatch            // @see ZF-7496            if (!($this->getResponse()->isRedirect())) {                // preDispatch() didn't change the action, so we can continue                if ($this->getInvokeArg('useCaseSensitiveActions') || in_array($action, $this->_classMethods)) {                    if ($this->getInvokeArg('useCaseSensitiveActions')) {                        trigger_error('Using case sensitive actions without word separators is deprecated; please do not rely on this "feature"');                    }                    $this->$action();                } else {                    $this->__call($action, array());                }            }            $this->postDispatch();        }        // whats actually important here is that this action controller is        // shutting down, regardless of dispatching; notify the helpers of this        // state        $this->_helper->notifyPostDispatch();    }     public function run(Zend_Controller_Request_Abstract $request = null, Zend_Controller_Response_Abstract $response = null)    {        if (null !== $request) {            $this->setRequest($request);        } else {            $request = $this->getRequest();        }        if (null !== $response) {            $this->setResponse($response);        }        $action = $request->getActionName();        if (empty($action)) {            $action = 'index';        }        $action = $action . 'Action';        $request->setDispatched(true);        $this->dispatch($action);        return $this->getResponse();    }     protected function _getParam($paramName, $default = null)    {        $value = $this->getRequest()->getParam($paramName);         if ((null === $value || '' === $value) && (null !== $default)) {            $value = $default;        }        return $value;    }     protected function _setParam($paramName, $value)    {        $this->getRequest()->setParam($paramName, $value);        return $this;    }     protected function _hasParam($paramName)    {        return null !== $this->getRequest()->getParam($paramName);    }     protected function _getAllParams()    {        return $this->getRequest()->getParams();    }     final protected function _forward($action, $controller = null, $module = null, array $params = null)    {        $request = $this->getRequest();        if (null !== $params) {            $request->setParams($params);        }        if (null !== $controller) {            $request->setControllerName($controller);            // Module should only be reset if controller has been specified            if (null !== $module) {                $request->setModuleName($module);            }        }        $request->setActionName($action)                ->setDispatched(false);    }     protected function _redirect($url, array $options = array())    {        $this->_helper->redirector->gotoUrl($url, $options);    }}


Zend_Controller_Action提供了動作和視圖的render功能,以及注冊請求和響應對象,常用助手等等。

動作控制器的常用方法

在動作控制器中常用的方法和屬性如下:

$this->_helper主要完成助手的相關操作例如:

// 只是局部控制器;當初始化加載時,對這個控制器的所有動作有效:
$this->_helper->viewRenderer->setNoRender(true);
// 全局:
$this->_helper->removeHelper('viewRenderer');

 // 也是全局,但需要和本地版本協作,以便繁殖這個控制器:
Zend_Controller_Front::getInstance()->setParam('noViewRenderer', true);

通過設置ViewRenderer的noRender標記,可以簡單地為一個獨立的視圖禁止解析(rendering): 
class FooController extends Zend_Controller_Action
{
    public function barAction()
    {
        // disable autorendering for this action only:
        $this->_helper->viewRenderer->setNoRender();
    }
}


            
禁止ViewRenderer的主要原因是如果你不需要視圖對象或者如果你不通過視圖腳本(例如,當使用動作控制器來司服網站服務協議如SOAP,XML-RPC或REST)來解析。大多數情況下,你不需要全局地禁止ViewRenderer,只選擇性地在個別控制器或動作里禁止它。 


請求對象和響應對象的相關操作


無數的對象和變量與對象一起注冊,并且每個都有訪問器方法。


請求對象:getRequest()可用來讀取調用動作請求對象。


響應對象: getResponse()可用來讀取收集最終響應的響應對象。一些典型的調用看起來象這樣:


$this->getResponse()->setHeader('Content-Type', 'text/xml');
$this->getResponse()->appendBody($content);


                
調用參數:前端控制器可能把參數傳給路由器、派遣器和動作控制器。為了讀取這些參數,可使用getInvokeArg($key);另外,用getInvokeArgs()讀取整個參數列表。


請求參數:請求對象手機請求參數,如任何_GET 或 _POST 參數,或者指定在URL的路徑信息里的用戶參數。為了讀取這些參數,可使用_getParam($key)或_getAllParams()。也可以用_setParam()來設置請求參數;當轉發到另外的動作時這很有用。


用_hasParam($key)來測試是否一個參數存在(對邏輯分支有用)。


Note: _getParam()可帶有一個可選的第二個參數,如果它不是空的,就包含一個缺省的值。用它在讀取值之前來消除對_hasParam() 的調用: 
// Use default value of 1 if id is not set
$id = $this->_getParam('id', 1);


// Instead of:
if ($this->_hasParam('id') {
    $id = $this->_getParam('id');
} else {
    $id = 1;
}


                    
視圖的相關操作


Zend_Controller_Action為視圖繼承提供了一個初步的靈活的機制。有兩個方法來完成這個:initView() 和 render();前者松散地加載$view public 屬性,后者基于當前請求的動作來解析視圖,它們使用目錄層次來決定腳本路徑。


視圖初始化


initView()初始化視圖對象。為了讀取視圖對象,render()調用initView(),但它可以在任何時候被初始化;缺省地,它用Zend_View對象來組裝$view屬性,但任何實現Zend_View_Interface的類可以使用。如果$view已經被初始化,它就簡單地返回屬性。


缺省的實現使用下面假設的目錄結構:


applicationOrModule/
    controllers/
        IndexController.php
    views/
        scripts/
            index/
                index.phtml
        helpers/
        filters/


            
換句話說,視圖腳本假定放在views/scripts/子目錄,同時假定 views子目錄還包含兄弟功能(助手和過濾器)。確定視圖腳本名稱和路徑時,先以 views/scripts/作為基路徑,然后加上以視圖腳本對應控制器命名的目錄。


解析(Rendering)視圖


render() 有下列特征:has the following signature:


string render(string $action = null,
              string $name = null,
              bool $noController = false);


            
render()解析視圖腳本。如果沒有傳遞參數,它假定請求的腳本是[controller]/[action].phtml (.phtml是$viewSuffix屬性的值)。為$action傳遞一個值將解析在[controller]子目錄中的模板。為用[controller]重寫,傳遞一個true值給$noController。最后,模板被解析到響應對象;如果你希望解析到一個在響應對象里指定的named segment,傳遞一個值給$name。


Note: 因為控制器和動作名字里可能包含分隔符如'_'、 '.' 和 '-',當決定視圖名字時,render()把它們規格化成 '-'.在內部,它使用派遣器的字和路徑分隔符來做規格化。這樣,對/foo.bar/baz-bat的請求將解析腳本foo-bar/baz-bat.phtml。如果動作方法包含camelCasing,記住當決定視圖腳本文件名的時候,這將變成由'-'分隔的字。 


一些例子:


class MyController extends Zend_Controller_Action
{
    public function fooAction()
    {
        // Renders my/foo.phtml
        $this->render();


        // Renders my/bar.phtml
        $this->render('bar');


        // Renders baz.phtml
        $this->render('baz', null, true);


        // Renders my/login.phtml to the 'form' segment of the
        // response object
        $this->render('login', 'form');


        // Renders site.phtml to the 'page' segment of the response
        // object; does not use the 'my/' subirectory
        $this->render('site', 'page', true);
    }


    public function bazBatAction()
    {
        // Renders my/baz-bat.phtml
        $this->render();
    }
}

其它

_forward($action, $controller = null, $module = null, array $params = null) :執行另外一個動作。如果在preDispatch()里調用,當前請求的動作將被跳過來支持新的動作。否則,在當前動作被處理之后,在_forward()請求的動作將被執行。

_redirect($url, array $options = array()):重定向到另外一個地方。這個方法用URL和一組可選的選項。缺省地,它執行HTTP 302 重定向。

選項可包括一個或多個下面這些:

exit:是否立即退出。如果被請求,它將干凈地關閉任何打開的會話和執行重定向。

可以用setRedirectExit()訪問器在控制器里全局地設置這個選項。

prependBase:是否預先考慮基礎URL和URL提供的請求對象一起注冊。

使用setRedirectPrependBase()訪問器,在控制器里全局地設置這個選項。

code:在重定向時要用什么HTTP代碼。缺省使用302;可以用從301到306之間的任何代碼。

使用setRedirectCode()訪問器,在控制器里全局地設置這個選項。

擴展自定義Zend_Controller_Action 

為了創建動作控制器,設計上,Zend_Controller_Action 必須被繼承。至少,需要定義控制器可能調用的動作方法。
除了為web應用程序創建有用的函數外,你可能發現在不同的控制器里重復同樣的設置和實用方法;如果這樣,創建一個繼承(extends)Zend_Controller_Action 的基礎類可能會解決問題。
Example #1 如何處理不存在的動作

如果控制器的請求包括一個未定義的動作方法,Zend_Controller_Action::__call()將被調用。__call()當然是PHP中用來重載方法的魔術方法。

缺省地,這個方法拋出一個Zend_Controller_Action_Exception 來表明在控制器里沒有發現要求的方法。如果要求的方法以'Action'結尾,就假設一個動作被請求并且不存在;這樣的錯誤導致帶有代碼為 404 的異常。所有其它方法導致帶有代碼為 500 的異常。這使你很容易地在錯誤句柄里區分是頁面沒有發現還是程序錯誤。

如果想執行其它操作,你應該重寫這個函數。例如,如果你想顯示錯誤信息,可以象下面這樣來寫:

class MyController extends Zend_Controller_Action
{
    public function __call($method, $args)
    {
        if ('Action' == substr($method, -6)) {
            // If the action method was not found, render the error
            // template
            return $this->render('error');
        }


        // all other methods throw an exception
        throw new Exception('Invalid method "'
                            . $method
                            . '" called',
                            500);
    }
}
            
另外的可能性就是你可能想轉發到缺省控制頁面:
class MyController extends Zend_Controller_Action
{
    public function indexAction()
    {
        $this->render();
    }
    public function __call($method, $args)
    {
        if ('Action' == substr($method, -6)) {
            // If the action method was not found, forward to the
            // index action
            return $this->_forward('index');
        }
        // all other methods throw an exception
        throw new Exception('Invalid method "'
                            . $method
                            . '" called',
                            500);
    }
}
            
為了定制控制器,除了重寫__call()以外,本章前面說涉及的初始化、實用程序、訪問器、視圖和派遣鉤子等方法都可以被重寫。作為例子,如果把視圖對象保存到注冊表里,你可能想用象下面的代碼來修改initView():

abstract class My_Base_Controller extends Zend_Controller_Action
{
    public function initView()
    {
        if (null === $this->view) {
            if (Zend_Registry::isRegistered('view')) {
                $this->view = Zend_Registry::get('view');
            } else {
                $this->view = new Zend_View();
                $this->view->setBasePath(dirname(__FILE__) . '/../views');
            }
        }


        return $this->view;
    }

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 波多野结衣视频免费 | 国产亚洲精品九九久在线观看 | 狂野欧美性猛交xxxx | 成人国产永久福利看片 | 中文字幕一区二区在线视频 | 亚洲天堂一区二区三区四区 | h视频免费看 | 免费视频中文字幕 | 免费视频www | 日韩欧美亚洲综合 | 久久久久久久久国产 | 毛片传媒 | 日本护士ooowww | 亚洲性hd| 午夜爽爽爽男女免费观看hd | 中文字幕 亚洲 一区二区三区 | 精品国产免费第一区二区三区日韩 | 国产欧美日韩精品第一区 | 免费视频成人 | 羞羞视频免费入口网站 | 亚洲性色永久网址 | 亚洲日本1区2区3区二区 | 亚洲国产精品嫩草影院 | 精品久久久久久中文字幕无碍 | 国产福利精品一区二区 | 日本欧美小视频 | 成年人视频免费在线观看 | 国产亚洲一区在线 | 国产91精品黄网在线观看 | 最新亚洲 | 日韩精品视频一区二区三区 | 韩国全部三级伦在线 | 99精品视频在线成人精彩视频 | 伊人久久大香线蕉综合7 | 羞羞网址 | 黄色欧美一级片 | 国产亚洲欧美视频 | 2019国内精品久久久久久 | 性一交一乱一伦 | 成人性a激情免费视频 | 波多野结衣在线网站 |