Zend Framework tutorial Zend_Helpers action assistant ViewRenderer usage detailed explanation_php example

WBOY
Release: 2016-08-04 08:56:47
Original
827 people have browsed it

This article describes the usage of the Zend_Helpers action assistant ViewRenderer in the Zend Framework tutorial. Share it with everyone for your reference, the details are as follows:

Decoupling of view layer and controller in MVC structure, and rendering. Often it is repetitive or redundant work. If a complete framework uses MVC, these operations will be properly designed. Let developers focus more on content rather than controlling the logical structure itself. In ZendFramework, this operation is mainly accomplished through the action assistant ViewRenderer. ViewRenderer automatically completes the process of establishing a view object in the controller and rendering the view;

ViewRenderer

Introduction

The ViewRenderer assistant is designed to achieve the following goals:

No need to create a view object instance within the controller; the view object will be automatically registered within the controller.
Automatically set view scripts, helpers, and filter paths based on the current module. Assigns the current module name to the class name prefix of the helper and filter classes.
Creates a globally valid view object for all dispatched controllers and actions.
Allows developers to set default view resolution options for all controllers.
Added the function of automatically parsing view scripts without intervention.
Allows developers to create their own specifications for view base paths and view script paths.

Note: If _forward(), redirect, or render is executed manually, automatic parsing will not occur. Because when you perform these actions, you are telling ViewRenderer that you have to determine the output result yourself.

Note: ViewRenderer Assistant is enabled by default.

You can set parameters through the noViewRenderer method of the front-end controller ($front->setParam('noViewRenderer', true)) or remove the helper from the helper broker stack (Zend_Controller_Action_HelperBroker::removeHelper( 'viewRenderer')) etc. to disable the helper.

If you want to modify the ViewRenderer settings before distributing the front-end controller, you can use the following two methods:

Create an instance and register your own ViewRenderer object, then pass it to the helper broker.

$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer();
$viewRenderer->setView($view)
       ->setViewSuffix('php');
Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
Copy after login

Instantly initialize and/or obtain ViewRenderer objects via a helper broker.

$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
$viewRenderer->setView($view)
       ->setViewSuffix('php');

Copy after login

API

In most uses, you only need to simply create a ViewRenderer object and then pass it to the action helper broker. The easiest way to create an instance and register it is to use the getStaticHelper() method of the helper broker:

Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');

When the action controller is instantiated for the first time, ViewRenderer will be triggered to create a view object. Each time the action controller is instantiated, it will call the init() method of ViewRenderer, set the view properties of the action controller, and call the addScriptPath() method with the path relative to the current module as a parameter; when calling, it will have a path named after the current module. Class prefix parameter that is valid for all helper and filter classes defined for this module. (this will be called with a class prefix named after the current module, effectively namespacing all helper and filter classes you define for the module. )

Every time the postDispatch() method is executed, it will execute the render() method for the current action.

For example this class:

// A controller class, foo module:
class Foo_BarController extends Zend_Controller_Action
{
  // Render bar/index.phtml by default; no action required
  public function indexAction()
  {
  }
  // Render bar/populate.phtml with variable 'foo' set to 'bar'.
  // Since view object defined at preDispatch(), it's already available.
  public function populateAction()
  {
    $this->view->foo = 'bar';
  }
}
...
// in one of your view scripts:
$this->foo(); // call Foo_View_Helper_Foo::foo()

Copy after login

ViewRenderer也定义了大量的访问器用来设定和获取视图选项。

setView($view)可以为ViewRenderer设定视图对象。以公共类属性$view获取设定值。

setNeverRender($flag = true)可以全局的启用或禁用自动解析,也就是对所有控制器都有效。如果设定为true,在所有控制器器内,postDispatch()将不会自动调用render()。getNeverRender()返回当前的设定值。

setNoRender($flag = true) 用来启用或禁用自动解析,如果设置为true,在当前控制器内,postDispatch()不会调用render()方法。这个设定在preDispatch()每次执行时会被重置。getNoRender()返回当前的设定值。

setNoController($flag = true)通知render()不要再到以控制器命名的子目录中寻找视图脚本。getNoController()返回当前值。

setNeverController($flag = true)与setNoController($flag = true)相似,但是其在全局范围内有效——也就是说,它不会在每次分发动作时重置。getNeverController()返回当前值。

setScriptAction($name)用来指定解析的视图脚本。$name是脚本的名字去掉后缀(不带控制器子目录,除非noController已开启)。如果没有指定,它将寻找以请求对象中的动作命名的视图脚本。getScriptAction()返回当前值。

setResponseSegment($name)用来指定解析到响应对象中的哪个命名片段。如果没有指定,解析到默认片断。getResponseSegment()返回当前值。

initView($path, $prefix, $options)可以指定视图的基路径,为助手和过滤器脚本设置类前缀,设定ViewRenderer选项。可以传入以下任意的标志:neverRender,noRender,noController, scriptAction,和responseSegment。

setRender($action = null, $name = null, $noController = false)可以一次设定scriptAction、responseSegment和noController。 direct()是它的别名,使得控制器中可以方便的调用。

// Render 'foo' instead of current action script
$this->_helper->viewRenderer('foo');
// render form.phtml to the 'html' response segment, without using a
// controller view script subdirectory:
$this->_helper->viewRenderer('form', 'html', true);

Copy after login

Note: setRender() 和 direct()并不会实际解析视图脚本,而是提示postDispatch()和postDispatch()解析视图。

构造函数允许可选的传入参数视图对象和ViewRenderer选项,接受与initView()一样的标志(flags):

$view  = new Zend_View(array('encoding' => 'UTF-8'));
$options = array('noController' => true, 'neverRender' => true);
$viewRenderer =
  new Zend_Controller_Action_Helper_ViewRenderer($view, $options);

Copy after login

There are several additional methods for customizing path rules, which are used to determine the view base path to add view objects, determine the view script path to find and parse the view script. Each of these methods takes one or more of the following placeholders (placehodlers).

:moduleDir refers to the base directory of the current module (usually the parent directory of the module's controller directory).
:module refers to the current module name.
:controller refers to the current controller name.
:action refers to the current module name.
:suffix refers to the current view script suffix (can be set via setViewSuffix()).

Methods related to controller path rules:

setViewBasePathSpec($spec) can change the path rules that determine the base path added to the view object. The default rule is: moduleDir/views. The current rules can be obtained at any time using getViewBasePathSpec().
setViewScriptPathSpec($spec) allows changing the path rules that determine the path to an individual view script (excluding the view script base path). The default path rule is :controller/:action.:suffix. The current rules can be obtained at any time through getViewScriptPathSpec().
setViewScriptPathNoControllerSpec($spec) allows changing the path rules that determine the path to an individual view script (minus the view script base path) when noController is in effect. The default rule is: action.:suffix, and the current rule can be obtained at any time through getViewScriptPathNoControllerSpec().
For elaborate control over path specifications, Zend_Filter_Inflector can be used. Deep down, the ViewRenderer already uses an inflector to perform path mapping. To interact with an inflector - either setting your own or modifying the default inflector, the following methods can be used:
getInflector() will get the inflector. If it does not exist in the view resolver, it creates one using default rules.
By default, it uses static rule references and static targets as suffixes and module directories; this allows different view resolvers to dynamically modify the inflector's capabilities.
setInflector($inflector, $reference) allows setting a custom inflector for use with a view resolver. If $reference is true, it will set the suffix and module directory as static references and target properties to the view resolver.

Note: Default search conventions

The view resolver does some path normalization to make view script lookup easier. The default rules are as follows:

:module: Mixed words and camelCase words are separated by dashes, and the entire string is made lowercase. For example: "FooBarBaz" becomes "foo-bar-baz".
Internally, the inflector uses the filters Zend_Filter_Word_CamelCaseToDash and Zend_Filter_StringToLower.
:controller: Mixed words and camelCase words are separated by dashes; underscores are converted to directory separators, and the entire string is lowercase. For example: "FooBar" becomes "foo-bar"; "FooBar_Admin" becomes "foo-bar/admin".
Internally, the inflector uses the filters Zend_Filter_Word_CamelCaseToDash, Zend_Filter_Word_UnderscoreToSeparator and Zend_Filter_StringToLower.
:action: Mixed words and camelCase words are separated by dashes; non-alphanumeric characters are translated into dashes, and the entire string is made lowercase. For example, "fooBar" becomes "foo-bar"; "foo-barBaz" becomes "foo-bar-baz".

Internally, inflector uses filters Zend_Filter_Word_CamelCaseToDash, Zend_Filter_PregReplace and Zend_Filter_StringToLower.

The last item in the view resolver API is about actually determining the view script path and resolving the view. Includes:

renderScript($script, $name) allows parsing scripts at specified paths, optionally named path fragments. (renderScript($script, $name) allows you to render a script with a path you specify, optionally to a named path segment.) When using this method, ViewRenderer will not automatically determine the script name, but directly to the view object The render() passes in the $script parameter.

Note: When the view has been parsed into the response object, noRender will be set to prevent the same script from being parsed multiple times.

Note: By default, Zend_Controller_Action::renderScript() proxies ViewRenderer's renderScript() method.

getViewScript($action, $vars) creates a path to the view script based on the passed action and/or variables in $vars. The keys in this array can contain all path-specific keys ('moduleDir', 'module', 'controller', 'action', and 'suffix'). Any variables passed in will be used first, otherwise the value based on the current request will be used.

getViewScript() uses viewScriptPathSpec or viewScriptPathNoControllerSpec according to the setting value of the noController flag.

Word delimiters in modules, controllers and actions will be replaced with dashes ('-'). Therefore, the controller name 'foo.bar' and the action 'baz:bat' will get the view script path 'foo-bar/baz-bat.phtml' according to the default path rules.

Note: By default, Zend_Controller_Action::getViewScript() proxy ViewRenderer's getViewScript() method.

render($action, $name, $noController)首先检查$name或 $noController参数是否传入,如果传入,则在ViewRenderer中设定相应的标志(分别是响应片段和noController)。然后传入$action参数到getViewScript(),最后传入计算的试图脚本路径到renderScript()。

Note: 注意使用render()的边际效应:传入的响应片段名称和noController标志在视图对象中存留。此外解析结束后noRender会被设置。

Note: 默认的,Zend_Controller_Action::render()代理 ViewRenderer的render()方法。

renderBySpec($action, $vars, $name)允许传入路径规则变量以确定创建的视图脚本路径。它把$action和$vars传入到getScriptPath(),将脚本路径结果和$name传入到renderScript()。

基础用法示例

Example #9 基本用法

大多数基础使用中,只需在bootstrap中使用助手经纪人简单的初始化和注册ViewRenderer 助手,然后在动作方法中设置变量。

// In your bootstrap:
Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
...
// 'foo' module, 'bar' controller:
class Foo_BarController extends Zend_Controller_Action
{
  // Render bar/index.phtml by default; no action required
  public function indexAction()
  {
  }
  // Render bar/populate.phtml with variable 'foo' set to 'bar'.
  // Since view object defined at preDispatch(), it's already available.
  public function populateAction()
  {
    $this->view->foo = 'bar';
  }
  // Renders nothing as it forwards to another action; the new action
  // will perform any rendering
  public function bazAction()
  {
    $this->_forward('index');
  }
  // Renders nothing as it redirects to another location
  public function batAction()
  {
    $this->_redirect('/index');
  }
}

Copy after login

Note: 命名规则:控制器和动作名中的单词定界符

如果控制器或者动作名称由几个单词组成,分发器要求在URL中使用特定的路径和单词定界符分隔。ViewRenderer创建路径时将控制器名称中的任何路径定界符替换成实际的路径定界符('/'),任何单词定界符替换成短线('-')。对动作/foo.bar/baz.bat的调用将分发到FooBarController.php中的FooBarController::bazBatAction(),然后解析foo-bar/baz-bat.phtml;对动作/bar_baz/baz-bat的调用将分发到Bar/BazController.php中的Bar_BazController::bazBatAction(),并解析bar/baz/baz-bat.phtml。

注意到在第二个例子中,模块依然是默认的模块,但由于路径分隔符的存在,控制器的接收到的名字为Bar_BazController,该类在文件Bar/BazController.php中。ViewRenderer模拟了控制器的目录分层。

Example #10 禁用自动解析

对于某些动作和控制器,可能希望关闭自动解析——例如,如果想发送其他类型的输出(XML,JSON等),或者更简单的不想发送任何东西。有两个选项:关闭所有的自动解析(setNeverRender()),或者仅仅关闭当前动作的自动解析(setNoRender())。

// Baz controller class, bar module:
class Bar_BazController extends Zend_Controller_Action
{
  public function fooAction()
  {
    // Don't auto render this action
    <strong>$this->_helper->viewRenderer->setNoRender();</strong>
  }
}
// Bat controller class, bar module:
class Bar_BatController extends Zend_Controller_Action
{
  public function preDispatch()
  {
    // Never auto render this controller's actions
    $this->_helper->viewRenderer->setNoRender();
  }
}

Copy after login

Note: 大多数情况下,全局的关闭自动解析(setNeverRender())没有意义,因为这样ViewRenderer做的唯一件事只是自动设置了视图对象。
Example #11 选择另外的视图脚本
有些情况下需要解析另一个脚本而非以动作命名的脚本。例如,如果你有一个控制器包含增加和编辑两个动作,它们可能都显示相同的'form'视图,尽管拥有不同的值集合(value set)。只需要使用setScriptAction()或者setRender()简单的改变脚本的名称,或者以成员方法的形式调用助手,它将调用setRender()。

// Bar controller class, foo module:
class Foo_BarController extends Zend_Controller_Action
{
  public function addAction()
  {
    // Render 'bar/form.phtml' instead of 'bar/add.phtml'
    $this->_helper->viewRenderer('form');
  }
  public function editAction()
  {
    // Render 'bar/form.phtml' instead of 'bar/edit.phtml'
    $this->_helper->viewRenderer->setScriptAction('form');
  }
  public function processAction()
  {
    // do some validation...
    if (!$valid) {
      // Render 'bar/form.phtml' instead of 'bar/process.phtml'
      $this->_helper->viewRenderer->setRender('form');
      return;
    }
    // otherwise continue processing...
  }
}

Copy after login

Example #12 修改注册的视图Modifying the registered view
如果需要修改视图对象怎么办——例如改变助手路径或者编码?可以在控制器中修改视图对象设定,或者从ViewRenderer中抓取视图对象;两种方式引用的是同一个对象。

// Bar controller class, foo module:
class Foo_BarController extends Zend_Controller_Action
{
  public function preDispatch()
  {
    // change view encoding
    $this->view->setEncoding('UTF-8');
  }
  public function bazAction()
  {
    // Get view object and set escape callback to 'htmlspecialchars'
    $view = $this->_helper->viewRenderer->view;
    $view->setEscape('htmlspecialchars');
  }
}

Copy after login

高级用法示例

Example #13 修改路径规则

有些情况下,默认的路径规则可能并不适合站点的需要。比如,希望拥有一个单独的模板树供设计人员访问(例如,如果你使用» Smarty,这是很典型的情形)。这种情况下,你可能想硬编码视图的基路径规则,为动作视图脚本路径自身创建一套规则。

假定视图的基路径(base path)为'/opt/vendor/templates',希望通过':moduleDir/:controller/:action.:suffix'引用视图脚本;如果设定了noController标志,想在顶级而不是在子目录中解析(':action.:suffix')。最终希望使用'tpl'作为视图脚本文件的后缀。

/**
 * In your bootstrap:
 */
// Different view implementation
$view = new ZF_Smarty();
$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer($view);
$viewRenderer->setViewBasePathSpec('/opt/vendor/templates')
       ->setViewScriptPathSpec(':module/:controller/:action.:suffix')
       ->setViewScriptPathNoControllerSpec(':action.:suffix')
       ->setViewSuffix('tpl');
Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);

Copy after login

Example #14 一个动作中解析多个视图脚本

有时可能需要在一个动作中解析多个视图脚本。这个非常简单,多次调用render()就行了:

class SearchController extends Zend_Controller_Action
{
  public function resultsAction()
  {
    // Assume $this->model is the current model
    $this->view->results =
      $this->model->find($this->_getParam('query', '');
    // render() by default proxies to the ViewRenderer
    // Render first the search form and then the results
    $this->render('form');
    $this->render('results');
  }
  public function formAction()
  {
    // do nothing; ViewRenderer autorenders the view script
  }
}

Copy after login

ViewRenderer的相关源码如下,仔细分析,并不难看出实现方法:

<&#63;php
/**
 * @see Zend_Controller_Action_Helper_Abstract
 */
require_once 'Zend/Controller/Action/Helper/Abstract.php';
/**
 * @see Zend_View
 */
require_once 'Zend/View.php';
/**
 * View script integration
 *
 * Zend_Controller_Action_Helper_ViewRenderer provides transparent view
 * integration for action controllers. It allows you to create a view object
 * once, and populate it throughout all actions. Several global options may be
 * set:
 *
 * - noController: if set true, render() will not look for view scripts in
 *  subdirectories named after the controller
 * - viewSuffix: what view script filename suffix to use
 *
 * The helper autoinitializes the action controller view preDispatch(). It
 * determines the path to the class file, and then determines the view base
 * directory from there. It also uses the module name as a class prefix for
 * helpers and views such that if your module name is 'Search', it will set the
 * helper class prefix to 'Search_View_Helper' and the filter class prefix to ;
 * 'Search_View_Filter'.
 *
 * Usage:
 * <code>
 * // In your bootstrap:
 * Zend_Controller_Action_HelperBroker::addHelper(new Zend_Controller_Action_Helper_ViewRenderer());
 *
 * // In your action controller methods:
 * $viewHelper = $this->_helper->getHelper('view');
 *
 * // Don't use controller subdirectories
 * $viewHelper->setNoController(true);
 *
 * // Specify a different script to render:
 * $this->_helper->viewRenderer('form');
 *
 * </code>
 *
 * @uses    Zend_Controller_Action_Helper_Abstract
 * @package  Zend_Controller
 * @subpackage Zend_Controller_Action_Helper
 * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license  http://framework.zend.com/license/new-bsd   New BSD License
 */
class Zend_Controller_Action_Helper_ViewRenderer extends Zend_Controller_Action_Helper_Abstract
{
  /**
   * @var Zend_View_Interface
   */
  public $view;
  /**
   * Word delimiters
   * @var array
   */
  protected $_delimiters;
  /**
   * @var Zend_Filter_Inflector
   */
  protected $_inflector;
  /**
   * Inflector target
   * @var string
   */
  protected $_inflectorTarget = '';
  /**
   * Current module directory
   * @var string
   */
  protected $_moduleDir = '';
  /**
   * Whether or not to autorender using controller name as subdirectory;
   * global setting (not reset at next invocation)
   * @var boolean
   */
  protected $_neverController = false;
  /**
   * Whether or not to autorender postDispatch; global setting (not reset at
   * next invocation)
   * @var boolean
   */
  protected $_neverRender   = false;
  /**
   * Whether or not to use a controller name as a subdirectory when rendering
   * @var boolean
   */
  protected $_noController  = false;
  /**
   * Whether or not to autorender postDispatch; per controller/action setting (reset
   * at next invocation)
   * @var boolean
   */
  protected $_noRender    = false;
  /**
   * Characters representing path delimiters in the controller
   * @var string|array
   */
  protected $_pathDelimiters;
  /**
   * Which named segment of the response to utilize
   * @var string
   */
  protected $_responseSegment = null;
  /**
   * Which action view script to render
   * @var string
   */
  protected $_scriptAction  = null;
  /**
   * View object basePath
   * @var string
   */
  protected $_viewBasePathSpec = ':moduleDir/views';
  /**
   * View script path specification string
   * @var string
   */
  protected $_viewScriptPathSpec = ':controller/:action.:suffix';
  /**
   * View script path specification string, minus controller segment
   * @var string
   */
  protected $_viewScriptPathNoControllerSpec = ':action.:suffix';
  /**
   * View script suffix
   * @var string
   */
  protected $_viewSuffix   = 'phtml';
  /**
   * Constructor
   *
   * Optionally set view object and options.
   *
   * @param Zend_View_Interface $view
   * @param array        $options
   * @return void
   */
  public function __construct(Zend_View_Interface $view = null, array $options = array())
  {
    if (null !== $view) {
      $this->setView($view);
    }
    if (!empty($options)) {
      $this->_setOptions($options);
    }
  }
  /**
   * Clone - also make sure the view is cloned.
   *
   * @return void
   */
  public function __clone()
  {
    if (isset($this->view) && $this->view instanceof Zend_View_Interface) {
      $this->view = clone $this->view;
    }
  }
  /**
   * Set the view object
   *
   * @param Zend_View_Interface $view
   * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface
   */
  public function setView(Zend_View_Interface $view)
  {
    $this->view = $view;
    return $this;
  }
  /**
   * Get current module name
   *
   * @return string
   */
  public function getModule()
  {
    $request = $this->getRequest();
    $module = $request->getModuleName();
    if (null === $module) {
      $module = $this->getFrontController()->getDispatcher()->getDefaultModule();
    }
    return $module;
  }
  /**
   * Get module directory
   *
   * @throws Zend_Controller_Action_Exception
   * @return string
   */
  public function getModuleDirectory()
  {
    $module  = $this->getModule();
    $moduleDir = $this->getFrontController()->getControllerDirectory($module);
    if ((null === $moduleDir) || is_array($moduleDir)) {
      /**
       * @see Zend_Controller_Action_Exception
       */
      require_once 'Zend/Controller/Action/Exception.php';
      throw new Zend_Controller_Action_Exception('ViewRenderer cannot locate module directory for module "' . $module . '"');
    }
    $this->_moduleDir = dirname($moduleDir);
    return $this->_moduleDir;
  }
  /**
   * Get inflector
   *
   * @return Zend_Filter_Inflector
   */
  public function getInflector()
  {
    if (null === $this->_inflector) {
      /**
       * @see Zend_Filter_Inflector
       */
      require_once 'Zend/Filter/Inflector.php';
      /**
       * @see Zend_Filter_PregReplace
       */
      require_once 'Zend/Filter/PregReplace.php';
      /**
       * @see Zend_Filter_Word_UnderscoreToSeparator
       */
      require_once 'Zend/Filter/Word/UnderscoreToSeparator.php';
      $this->_inflector = new Zend_Filter_Inflector();
      $this->_inflector->setStaticRuleReference('moduleDir', $this->_moduleDir) // moduleDir must be specified before the less specific 'module'
         ->addRules(array(
           ':module'   => array('Word_CamelCaseToDash', 'StringToLower'),
           ':controller' => array('Word_CamelCaseToDash', new Zend_Filter_Word_UnderscoreToSeparator('/'), 'StringToLower', new Zend_Filter_PregReplace('/\./', '-')),
           ':action'   => array('Word_CamelCaseToDash', new Zend_Filter_PregReplace('#[^a-z0-9' . preg_quote('/', '#') . ']+#i', '-'), 'StringToLower'),
         ))
         ->setStaticRuleReference('suffix', $this->_viewSuffix)
         ->setTargetReference($this->_inflectorTarget);
    }
    // Ensure that module directory is current
    $this->getModuleDirectory();
    return $this->_inflector;
  }
  /**
   * Set inflector
   *
   * @param Zend_Filter_Inflector $inflector
   * @param boolean        $reference Whether the moduleDir, target, and suffix should be set as references to ViewRenderer properties
   * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface
   */
  public function setInflector(Zend_Filter_Inflector $inflector, $reference = false)
  {
    $this->_inflector = $inflector;
    if ($reference) {
      $this->_inflector->setStaticRuleReference('suffix', $this->_viewSuffix)
         ->setStaticRuleReference('moduleDir', $this->_moduleDir)
         ->setTargetReference($this->_inflectorTarget);
    }
    return $this;
  }
  /**
   * Set inflector target
   *
   * @param string $target
   * @return void
   */
  protected function _setInflectorTarget($target)
  {
    $this->_inflectorTarget = (string) $target;
  }
  /**
   * Set internal module directory representation
   *
   * @param string $dir
   * @return void
   */
  protected function _setModuleDir($dir)
  {
    $this->_moduleDir = (string) $dir;
  }
  /**
   * Get internal module directory representation
   *
   * @return string
   */
  protected function _getModuleDir()
  {
    return $this->_moduleDir;
  }
  /**
   * Generate a class prefix for helper and filter classes
   *
   * @return string
   */
  protected function _generateDefaultPrefix()
  {
    $default = 'Zend_View';
    if (null === $this->_actionController) {
      return $default;
    }
    $class = get_class($this->_actionController);
    if (!strstr($class, '_')) {
      return $default;
    }
    $module = $this->getModule();
    if ('default' == $module) {
      return $default;
    }
    $prefix = substr($class, 0, strpos($class, '_')) . '_View';
    return $prefix;
  }
  /**
   * Retrieve base path based on location of current action controller
   *
   * @return string
   */
  protected function _getBasePath()
  {
    if (null === $this->_actionController) {
      return './views';
    }
    $inflector = $this->getInflector();
    $this->_setInflectorTarget($this->getViewBasePathSpec());
    $dispatcher = $this->getFrontController()->getDispatcher();
    $request = $this->getRequest();
    $parts = array(
      'module'   => (($moduleName = $request->getModuleName()) != '') &#63; $dispatcher->formatModuleName($moduleName) : $moduleName,
      'controller' => $request->getControllerName(),
      'action'   => $dispatcher->formatActionName($request->getActionName())
      );
    $path = $inflector->filter($parts);
    return $path;
  }
  /**
   * Set options
   *
   * @param array $options
   * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface
   */
  protected function _setOptions(array $options)
  {
    foreach ($options as $key => $value)
    {
      switch ($key) {
        case 'neverRender':
        case 'neverController':
        case 'noController':
        case 'noRender':
          $property = '_' . $key;
          $this->{$property} = ($value) &#63; true : false;
          break;
        case 'responseSegment':
        case 'scriptAction':
        case 'viewBasePathSpec':
        case 'viewScriptPathSpec':
        case 'viewScriptPathNoControllerSpec':
        case 'viewSuffix':
          $property = '_' . $key;
          $this->{$property} = (string) $value;
          break;
        default:
          break;
      }
    }
    return $this;
  }
  /**
   * Initialize the view object
   *
   * $options may contain the following keys:
   * - neverRender - flag dis/enabling postDispatch() autorender (affects all subsequent calls)
   * - noController - flag indicating whether or not to look for view scripts in subdirectories named after the controller
   * - noRender - flag indicating whether or not to autorender postDispatch()
   * - responseSegment - which named response segment to render a view script to
   * - scriptAction - what action script to render
   * - viewBasePathSpec - specification to use for determining view base path
   * - viewScriptPathSpec - specification to use for determining view script paths
   * - viewScriptPathNoControllerSpec - specification to use for determining view script paths when noController flag is set
   * - viewSuffix - what view script filename suffix to use
   *
   * @param string $path
   * @param string $prefix
   * @param array $options
   * @throws Zend_Controller_Action_Exception
   * @return void
   */
  public function initView($path = null, $prefix = null, array $options = array())
  {
    if (null === $this->view) {
      $this->setView(new Zend_View());
    }
    // Reset some flags every time
    $options['noController'] = (isset($options['noController'])) &#63; $options['noController'] : false;
    $options['noRender']   = (isset($options['noRender'])) &#63; $options['noRender'] : false;
    $this->_scriptAction   = null;
    $this->_responseSegment = null;
    // Set options first; may be used to determine other initializations
    $this->_setOptions($options);
    // Get base view path
    if (empty($path)) {
      $path = $this->_getBasePath();
      if (empty($path)) {
        /**
         * @see Zend_Controller_Action_Exception
         */
        require_once 'Zend/Controller/Action/Exception.php';
        throw new Zend_Controller_Action_Exception('ViewRenderer initialization failed: retrieved view base path is empty');
      }
    }
    if (null === $prefix) {
      $prefix = $this->_generateDefaultPrefix();
    }
    // Determine if this path has already been registered
    $currentPaths = $this->view->getScriptPaths();
    $path     = str_replace(array('/', '\\'), '/', $path);
    $pathExists  = false;
    foreach ($currentPaths as $tmpPath) {
      $tmpPath = str_replace(array('/', '\\'), '/', $tmpPath);
      if (strstr($tmpPath, $path)) {
        $pathExists = true;
        break;
      }
    }
    if (!$pathExists) {
      $this->view->addBasePath($path, $prefix);
    }
    // Register view with action controller (unless already registered)
    if ((null !== $this->_actionController) && (null === $this->_actionController->view)) {
      $this->_actionController->view    = $this->view;
      $this->_actionController->viewSuffix = $this->_viewSuffix;
    }
  }
  /**
   * init - initialize view
   *
   * @return void
   */
  public function init()
  {
    if ($this->getFrontController()->getParam('noViewRenderer')) {
      return;
    }
    $this->initView();
  }
  /**
   * Set view basePath specification
   *
   * Specification can contain one or more of the following:
   * - :moduleDir - current module directory
   * - :controller - name of current controller in the request
   * - :action - name of current action in the request
   * - :module - name of current module in the request
   *
   * @param string $path
   * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface
   */
  public function setViewBasePathSpec($path)
  {
    $this->_viewBasePathSpec = (string) $path;
    return $this;
  }
  /**
   * Retrieve the current view basePath specification string
   *
   * @return string
   */
  public function getViewBasePathSpec()
  {
    return $this->_viewBasePathSpec;
  }
  /**
   * Set view script path specification
   *
   * Specification can contain one or more of the following:
   * - :moduleDir - current module directory
   * - :controller - name of current controller in the request
   * - :action - name of current action in the request
   * - :module - name of current module in the request
   *
   * @param string $path
   * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface
   */
  public function setViewScriptPathSpec($path)
  {
    $this->_viewScriptPathSpec = (string) $path;
    return $this;
  }
  /**
   * Retrieve the current view script path specification string
   *
   * @return string
   */
  public function getViewScriptPathSpec()
  {
    return $this->_viewScriptPathSpec;
  }
  /**
   * Set view script path specification (no controller variant)
   *
   * Specification can contain one or more of the following:
   * - :moduleDir - current module directory
   * - :controller - name of current controller in the request
   * - :action - name of current action in the request
   * - :module - name of current module in the request
   *
   * :controller will likely be ignored in this variant.
   *
   * @param string $path
   * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface
   */
  public function setViewScriptPathNoControllerSpec($path)
  {
    $this->_viewScriptPathNoControllerSpec = (string) $path;
    return $this;
  }
  /**
   * Retrieve the current view script path specification string (no controller variant)
   *
   * @return string
   */
  public function getViewScriptPathNoControllerSpec()
  {
    return $this->_viewScriptPathNoControllerSpec;
  }
  /**
   * Get a view script based on an action and/or other variables
   *
   * Uses values found in current request if no values passed in $vars.
   *
   * If {@link $_noController} is set, uses {@link $_viewScriptPathNoControllerSpec};
   * otherwise, uses {@link $_viewScriptPathSpec}.
   *
   * @param string $action
   * @param array $vars
   * @return string
   */
  public function getViewScript($action = null, array $vars = array())
  {
    $request = $this->getRequest();
    if ((null === $action) && (!isset($vars['action']))) {
      $action = $this->getScriptAction();
      if (null === $action) {
        $action = $request->getActionName();
      }
      $vars['action'] = $action;
    } elseif (null !== $action) {
      $vars['action'] = $action;
    }
    $replacePattern = array('/[^a-z0-9]+$/i', '/^[^a-z0-9]+/i');
    $vars['action'] = preg_replace($replacePattern, '', $vars['action']);
    $inflector = $this->getInflector();
    if ($this->getNoController() || $this->getNeverController()) {
      $this->_setInflectorTarget($this->getViewScriptPathNoControllerSpec());
    } else {
      $this->_setInflectorTarget($this->getViewScriptPathSpec());
    }
    return $this->_translateSpec($vars);
  }
  /**
   * Set the neverRender flag (i.e., globally dis/enable autorendering)
   *
   * @param boolean $flag
   * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface
   */
  public function setNeverRender($flag = true)
  {
    $this->_neverRender = ($flag) &#63; true : false;
    return $this;
  }
  /**
   * Retrieve neverRender flag value
   *
   * @return boolean
   */
  public function getNeverRender()
  {
    return $this->_neverRender;
  }
  /**
   * Set the noRender flag (i.e., whether or not to autorender)
   *
   * @param boolean $flag
   * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface
   */
  public function setNoRender($flag = true)
  {
    $this->_noRender = ($flag) &#63; true : false;
    return $this;
  }
  /**
   * Retrieve noRender flag value
   *
   * @return boolean
   */
  public function getNoRender()
  {
    return $this->_noRender;
  }
  /**
   * Set the view script to use
   *
   * @param string $name
   * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface
   */
  public function setScriptAction($name)
  {
    $this->_scriptAction = (string) $name;
    return $this;
  }
  /**
   * Retrieve view script name
   *
   * @return string
   */
  public function getScriptAction()
  {
    return $this->_scriptAction;
  }
  /**
   * Set the response segment name
   *
   * @param string $name
   * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface
   */
  public function setResponseSegment($name)
  {
    if (null === $name) {
      $this->_responseSegment = null;
    } else {
      $this->_responseSegment = (string) $name;
    }
    return $this;
  }
  /**
   * Retrieve named response segment name
   *
   * @return string
   */
  public function getResponseSegment()
  {
    return $this->_responseSegment;
  }
  /**
   * Set the noController flag (i.e., whether or not to render into controller subdirectories)
   *
   * @param boolean $flag
   * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface
   */
  public function setNoController($flag = true)
  {
    $this->_noController = ($flag) &#63; true : false;
    return $this;
  }
  /**
   * Retrieve noController flag value
   *
   * @return boolean
   */
  public function getNoController()
  {
    return $this->_noController;
  }
  /**
   * Set the neverController flag (i.e., whether or not to render into controller subdirectories)
   *
   * @param boolean $flag
   * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface
   */
  public function setNeverController($flag = true)
  {
    $this->_neverController = ($flag) &#63; true : false;
    return $this;
  }
  /**
   * Retrieve neverController flag value
   *
   * @return boolean
   */
  public function getNeverController()
  {
    return $this->_neverController;
  }
  /**
   * Set view script suffix
   *
   * @param string $suffix
   * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface
   */
  public function setViewSuffix($suffix)
  {
    $this->_viewSuffix = (string) $suffix;
    return $this;
  }
  /**
   * Get view script suffix
   *
   * @return string
   */
  public function getViewSuffix()
  {
    return $this->_viewSuffix;
  }
  /**
   * Set options for rendering a view script
   *
   * @param string $action    View script to render
   * @param string $name     Response named segment to render to
   * @param boolean $noController Whether or not to render within a subdirectory named after the controller
   * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface
   */
  public function setRender($action = null, $name = null, $noController = null)
  {
    if (null !== $action) {
      $this->setScriptAction($action);
    }
    if (null !== $name) {
      $this->setResponseSegment($name);
    }
    if (null !== $noController) {
      $this->setNoController($noController);
    }
    return $this;
  }
  /**
   * Inflect based on provided vars
   *
   * Allowed variables are:
   * - :moduleDir - current module directory
   * - :module - current module name
   * - :controller - current controller name
   * - :action - current action name
   * - :suffix - view script file suffix
   *
   * @param array $vars
   * @return string
   */
  protected function _translateSpec(array $vars = array())
  {
    $inflector = $this->getInflector();
    $request  = $this->getRequest();
    $dispatcher = $this->getFrontController()->getDispatcher();
    $module   = $dispatcher->formatModuleName($request->getModuleName());
    $controller = $request->getControllerName();
    $action   = $dispatcher->formatActionName($request->getActionName());
    $params   = compact('module', 'controller', 'action');
    foreach ($vars as $key => $value) {
      switch ($key) {
        case 'module':
        case 'controller':
        case 'action':
        case 'moduleDir':
        case 'suffix':
          $params[$key] = (string) $value;
          break;
        default:
          break;
      }
    }
    if (isset($params['suffix'])) {
      $origSuffix = $this->getViewSuffix();
      $this->setViewSuffix($params['suffix']);
    }
    if (isset($params['moduleDir'])) {
      $origModuleDir = $this->_getModuleDir();
      $this->_setModuleDir($params['moduleDir']);
    }
    $filtered = $inflector->filter($params);
    if (isset($params['suffix'])) {
      $this->setViewSuffix($origSuffix);
    }
    if (isset($params['moduleDir'])) {
      $this->_setModuleDir($origModuleDir);
    }
    return $filtered;
  }
  /**
   * Render a view script (optionally to a named response segment)
   *
   * Sets the noRender flag to true when called.
   *
   * @param string $script
   * @param string $name
   * @return void
   */
  public function renderScript($script, $name = null)
  {
    if (null === $name) {
      $name = $this->getResponseSegment();
    }
    $this->getResponse()->appendBody(
      $this->view->render($script),
      $name
    );
    $this->setNoRender();
  }
  /**
   * Render a view based on path specifications
   *
   * Renders a view based on the view script path specifications.
   *
   * @param string $action
   * @param string $name
   * @param boolean $noController
   * @return void
   */
  public function render($action = null, $name = null, $noController = null)
  {
    $this->setRender($action, $name, $noController);
    $path = $this->getViewScript();
    $this->renderScript($path, $name);
  }
  /**
   * Render a script based on specification variables
   *
   * Pass an action, and one or more specification variables (view script suffix)
   * to determine the view script path, and render that script.
   *
   * @param string $action
   * @param array $vars
   * @param string $name
   * @return void
   */
  public function renderBySpec($action = null, array $vars = array(), $name = null)
  {
    if (null !== $name) {
      $this->setResponseSegment($name);
    }
    $path = $this->getViewScript($action, $vars);
    $this->renderScript($path);
  }
  /**
   * postDispatch - auto render a view
   *
   * Only autorenders if:
   * - _noRender is false
   * - action controller is present
   * - request has not been re-dispatched (i.e., _forward() has not been called)
   * - response is not a redirect
   *
   * @return void
   */
  public function postDispatch()
  {
    if ($this->_shouldRender()) {
      $this->render();
    }
  }
  /**
   * Should the ViewRenderer render a view script&#63;
   *
   * @return boolean
   */
  protected function _shouldRender()
  {
    return (!$this->getFrontController()->getParam('noViewRenderer')
      && !$this->_neverRender
      && !$this->_noRender
      && (null !== $this->_actionController)
      && $this->getRequest()->isDispatched()
      && !$this->getResponse()->isRedirect()
    );
  }
  /**
   * Use this helper as a method; proxies to setRender()
   *
   * @param string $action
   * @param string $name
   * @param boolean $noController
   * @return void
   */
  public function direct($action = null, $name = null, $noController = null)
  {
    $this->setRender($action, $name, $noController);
  }
}

Copy after login

更多关于zend相关内容感兴趣的读者可查看本站专题:《Zend FrameWork框架入门教程》、《php优秀开发框架总结》、《Yii框架入门及常用技巧总结》、《ThinkPHP入门教程》、《php面向对象程序设计入门教程》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》

希望本文所述对大家基于Zend Framework框架的PHP程序设计有所帮助。

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template