Zend_Controller_Action of the action base class in the Zend Framework tutorial

Source: Internet
Author: User
Tags server website throw exception zend framework

Zend_Controller_Action of the action base class in the Zend Framework tutorial

This example describes the Zend_Controller_Action base class of the action in the Zend Framework tutorial. We will share this with you for your reference. The details are as follows:

Implementation of Zend_Controller_Action

The action controller of Zend Framework must inherit Zend_Controller_Action. Zend_Controller_Action provides the basic functions of the Action controller. For details, refer to the following code:

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

<?phprequire_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 provides the render function for actions and views, as well as registering request and response objects and common assistants.

Common methods of action Controller

The common methods and attributes in the Action controller are as follows:

$ This-> _ helper mainly completes operations related to the assistant, for example:

// Only a local Controller; When initializing and loading, all actions on this controller are valid: $ this-> _ helper-> viewRenderer-> setNoRender (true); // Global: $ this-> _ helper-> removeHelper ('viewrenderer'); // It is also global, but it needs to work with the local version to reproduce this controller: Zend_Controller_Front: getInstance () -> setParam ('noviewrenderer', true );

By setting the noRender tag of ViewRenderer, you can simply disable parsing (rendering) for an independent view ):

class FooController extends Zend_Controller_Action{  public function barAction()  {    // disable autorendering for this action only:    $this->_helper->viewRenderer->setNoRender();  }}

The main reason for disabling ViewRenderer is that if you do not need a view object or if you do not use a View Script (for example, when using an action controller to run server website service protocols such as SOAP, XML-RPC, or REST). In most cases, you do not need to globally disable ViewRenderer, but choose to disable it in some controllers or actions.

Operations related to the request object and response object

Countless objects and variables are registered with the object, and each has an accessor method.

Request object: getRequest () can be used to read the call Action request object.

Response object: getResponse () can be used to read the response object for collecting final responses. Some typical calls look like this:

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

Call parameters: the front-end controller may pass the parameters to the router, dispatcher, and Action controller. To read these parameters, you can use getInvokeArg ($ key). In addition, you can use getInvokeArgs () to read the entire parameter list.

Request Parameters: the mobile phone request parameters of the request object, such as any _ GET or _ POST parameters, or user parameters specified in the URL path information. To read these parameters, use _ getParam ($ key) or _ getAllParams (). You can also use _ setParam () to set request parameters. This is useful when another action is forwarded.

Use _ hasParam ($ key) to test whether a parameter exists (useful for logical branches ).

Note: _ getParam () can contain an optional second parameter. If it is not empty, it contains a default value. Before reading a value, it is used to eliminate the call to _ 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;}

View-related operations

Zend_Controller_Action provides a flexible mechanism for view inheritance. There are two methods to accomplish this: initView () and render (); the former is loosely loaded with the $ view public attribute, and the latter is parsed based on the action of the current request, they use directory levels to determine the script path.

View Initialization

InitView () initializes the view object. To read the view object, render () calls initView (), but it can be initialized at any time. By default, it uses the Zend_View object to assemble the $ view attribute, however, any class that implements Zend_View_Interface can be used. If $ view has been initialized, it simply returns attributes.

The default implementation uses the following directory structure:

ApplicationOrModule/
Controllers/
IndexController. php
Views/
Scripts/
Index/
Index. phtml
Helpers/
Filters/

In other words, it is assumed that the View Script is placed in the views/scripts/sub-directory, and that the views sub-directory also contains the sibling function (helper and filter ). When determining the View Script Name and path, first use views/scripts/as the base path, and then add the directory named after the Controller corresponding to the View Script.

Resolution (Rendering) view

Render () has the following features: has the following signature:

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

Render () parses the View Script. If no parameter is passed, it is assumed that the request script is [controller]/[action]. phtml (. phtml is the value of the $ viewSuffix attribute ). Passing a value for $ action will parse the template in the [controller] subdirectory. To rewrite with [controller], pass a value of true to $ noController. Finally, the template is parsed to the response object. If you want to resolve it to a named segment specified in the response object, pass a value to $ name.

Note: The Controller and action name may contain delimiters such as '_' and '_','. 'and'-'. When the view name is determined, render () converts them '-'. internally, it uses the word and path Separator of the dispatcher for normalization. As a result, requests to/foo. bar/baz-bat will parse the script foo-bar/baz-bat.phtml. If the action method contains camelCasing, remember that when the View Script file name is determined, this will be separated.

Some examples:

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();  }}

Others

_ Forward ($ action, $ controller = null, $ module = null, array $ params = null): execute another action. If it is called in preDispatch (), the action of the current request will be skipped to support new actions. Otherwise, after the current action is processed, the action in the _ forward () request will be executed.

_ Redirect ($ url, array $ options = array (): redirects to another place. This method uses a URL and a set of Optional options. By default, it performs HTTP 302 redirection.

The options include one or more of the following:

Exit: whether to exit immediately. If requested, it will cleanly close any opened sessions and execute redirection.

You can use setRedirectExit () accessors to set this option globally in the controller.

PrependBase: determines whether to register the basic URL with the request object provided by the URL.

Use setRedirectPrependBase () accessors to set this option globally in the controller.

Code: the HTTP code used for redirection. By default, 302 is used. Any code from 301 to 306 can be used.

Use setRedirectCode () accessors to set this option globally in the controller.

Extended custom Zend_Controller_Action

To create an action controller, Zend_Controller_Action must be inherited. At least, define the action methods that the Controller may call.

In addition to creating useful functions for web applications, you may find that the same settings and practical methods are repeated in different controllers. In this case, create an extends) the basic class of Zend_Controller_Action may solve the problem.

Example #1 How to Handle nonexistent actions

If the Controller request contains an undefined action method, Zend_Controller_Action ::__ call () will be called. _ Call () is of course a magic Method Used in PHP to overload methods.

By default, this method throws a Zend_Controller_Action_Exception to indicate that no required method is found in the controller. If the requested method ends with 'action', it is assumed that an Action is requested and does not exist. Such an error causes an exception with Code 404. All other methods cause exceptions with code 500. This makes it easy for you to distinguish between page not found or program error in the error handle.

If you want to perform other operations, you should rewrite this function. For example, if you want to display an error message, you can write it as follows:

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);  }}

Another possibility is that you may want to forward it to the default control page:

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);  }}

In addition to rewriting _ call (), the initialization, utilities, accessors, views, dispatch hooks, and other methods mentioned earlier in this chapter can be overwritten. As an example, if you save the view object to the Registry, you may want to use the following code to modify 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;  }}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.