当前位置:首页 > CMS教程 > 其它CMS > 列表

Zend Framework教程之响应对象的封装Zend_Controller_Response实例详解

发布:smiling 来源: PHP粉丝网  添加日期:2021-07-13 15:53:37 浏览: 评论:0 

这篇文章主要介绍了Zend Framework教程之响应对象的封装Zend_Controller_Response用法,结合实例形式详细分析了响应对象的逻辑原理与相关使用技巧,需要的朋友可以参考下

本文实例讲述了Zend Framework教程之响应对象的封装Zend_Controller_Response用法。分享给大家供大家参考,具体如下:

概述

响应对象逻辑上是请求对象的搭档.目的在于收集消息体和/或消息头,因而可能返回大批的结果。

Zend_Controller_Response响应对象的基本实现

  1. ├── Response 
  2. │   ├── Abstract.php 
  3. │   ├── Cli.php 
  4. │   ├── Exception.php 
  5. │   ├── Http.php 
  6. │   └── HttpTestCase.php 

Zend_Controller_Response_Abstract

  1. abstract class Zend_Controller_Response_Abstract 
  2.  /** 
  3.   * Body content 
  4.   * @var array 
  5.   */ 
  6.  protected $_body = array(); 
  7.  /** 
  8.   * Exception stack 
  9.   * @var Exception 
  10.   */ 
  11.  protected $_exceptions = array(); 
  12.  /** 
  13.   * Array of headers. Each header is an array with keys 'name' and 'value' 
  14.   * @var array 
  15.   */ 
  16.  protected $_headers = array(); 
  17.  /** 
  18.   * Array of raw headers. Each header is a single string, the entire header to emit 
  19.   * @var array 
  20.   */ 
  21.  protected $_headersRaw = array(); 
  22.  /** 
  23.   * HTTP response code to use in headers 
  24.   * @var int 
  25.   */ 
  26.  protected $_httpResponseCode = 200; 
  27.  /** 
  28.   * Flag; is this response a redirect? 
  29.   * @var boolean 
  30.   */ 
  31.  protected $_isRedirect = false; 
  32.  /** 
  33.   * Whether or not to render exceptions; off by default 
  34.   * @var boolean 
  35.   */ 
  36.  protected $_renderExceptions = false; 
  37.  /** 
  38.   * Flag; if true, when header operations are called after headers have been 
  39.   * sent, an exception will be raised; otherwise, processing will continue 
  40.   * as normal. Defaults to true. 
  41.   * 
  42.   * @see canSendHeaders() 
  43.   * @var boolean 
  44.   */ 
  45.  public $headersSentThrowsException = true; 
  46.  /** 
  47.   * Normalize a header name 
  48.   * 
  49.   * Normalizes a header name to X-Capitalized-Names 
  50.   * 
  51.   * @param string $name 
  52.   * @return string 
  53.   */ 
  54.  protected function _normalizeHeader($name
  55.  { 
  56.   $filtered = str_replace(array('-''_'), ' ', (string) $name); 
  57.   $filtered = ucwords(strtolower($filtered)); 
  58.   $filtered = str_replace(' ''-'$filtered); 
  59.   return $filtered
  60.  } 
  61.  /** 
  62.   * Set a header 
  63.   * 
  64.   * If $replace is true, replaces any headers already defined with that 
  65.   * $name. 
  66.   * 
  67.   * @param string $name 
  68.   * @param string $value 
  69.   * @param boolean $replace 
  70.   * @return Zend_Controller_Response_Abstract 
  71.   */ 
  72.  public function setHeader($name$value$replace = false) 
  73.  { 
  74.   $this->canSendHeaders(true); 
  75.   $name = $this->_normalizeHeader($name); 
  76.   $value = (string) $value
  77.   if ($replace) { 
  78.    foreach ($this->_headers as $key => $header) { 
  79.     if ($name == $header['name']) { 
  80.      unset($this->_headers[$key]); 
  81.     } 
  82.    } 
  83.   } 
  84.   $this->_headers[] = array
  85.    'name' => $name
  86.    'value' => $value
  87.    'replace' => $replace 
  88.   ); 
  89.   return $this
  90.  } 
  91.  /** 
  92.   * Set redirect URL 
  93.   * 
  94.   * Sets Location header and response code. Forces replacement of any prior 
  95.   * redirects. 
  96.   * 
  97.   * @param string $url 
  98.   * @param int $code 
  99.   * @return Zend_Controller_Response_Abstract 
  100.   */ 
  101.  public function setRedirect($url$code = 302) 
  102.  { 
  103.   $this->canSendHeaders(true); 
  104.   $this->setHeader('Location'$url, true) 
  105.     ->setHttpResponseCode($code); 
  106.   return $this
  107.  } 
  108.  /** 
  109.   * Is this a redirect? 
  110.   * 
  111.   * @return boolean 
  112.   */ 
  113.  public function isRedirect() 
  114.  { 
  115.   return $this->_isRedirect; 
  116.  } 
  117.  /** 
  118.   * Return array of headers; see {@link $_headers} for format 
  119.   * 
  120.   * @return array 
  121.   */ 
  122.  public function getHeaders() 
  123.  { 
  124.   return $this->_headers; 
  125.  } 
  126.  /** 
  127.   * Clear headers 
  128.   * 
  129.   * @return Zend_Controller_Response_Abstract 
  130.   */ 
  131.  public function clearHeaders() 
  132.  { 
  133.   $this->_headers = array(); 
  134.   return $this
  135.  } 
  136.  /** 
  137.   * Clears the specified HTTP header 
  138.   * 
  139.   * @param string $name 
  140.   * @return Zend_Controller_Response_Abstract 
  141.   */ 
  142.  public function clearHeader($name
  143.  { 
  144.   if (! count($this->_headers)) { 
  145.    return $this
  146.   } 
  147.   foreach ($this->_headers as $index => $header) { 
  148.    if ($name == $header['name']) { 
  149.     unset($this->_headers[$index]); 
  150.    } 
  151.   } 
  152.   return $this
  153.  } 
  154.  /** 
  155.   * Set raw HTTP header 
  156.   * 
  157.   * Allows setting non key => value headers, such as status codes 
  158.   * 
  159.   * @param string $value 
  160.   * @return Zend_Controller_Response_Abstract 
  161.   */ 
  162.  public function setRawHeader($value
  163.  { 
  164.   $this->canSendHeaders(true); 
  165.   if ('Location' == substr($value, 0, 8)) { 
  166.    $this->_isRedirect = true; 
  167.   } 
  168.   $this->_headersRaw[] = (string) $value
  169.   return $this
  170.  } 
  171.  /** 
  172.   * Retrieve all {@link setRawHeader() raw HTTP headers} 
  173.   * 
  174.   * @return array 
  175.   */ 
  176.  public function getRawHeaders() 
  177.  { 
  178.   return $this->_headersRaw; 
  179.  } 
  180.  /** 
  181.   * Clear all {@link setRawHeader() raw HTTP headers} 
  182.   * 
  183.   * @return Zend_Controller_Response_Abstract 
  184.   */ 
  185.  public function clearRawHeaders() 
  186.  { 
  187.   $this->_headersRaw = array(); 
  188.   return $this
  189.  } 
  190.  /** 
  191.   * Clears the specified raw HTTP header 
  192.   * 
  193.   * @param string $headerRaw 
  194.   * @return Zend_Controller_Response_Abstract 
  195.   */ 
  196.  public function clearRawHeader($headerRaw
  197.  { 
  198.   if (! count($this->_headersRaw)) { 
  199.    return $this
  200.   } 
  201.   $key = array_search($headerRaw$this->_headersRaw); 
  202.   if ($key !== false) { 
  203.    unset($this->_headersRaw[$key]); 
  204.   } 
  205.   return $this
  206.  } 
  207.  /** 
  208.   * Clear all headers, normal and raw 
  209.   * 
  210.   * @return Zend_Controller_Response_Abstract 
  211.   */ 
  212.  public function clearAllHeaders() 
  213.  { 
  214.   return $this->clearHeaders() 
  215.      ->clearRawHeaders(); 
  216.  } 
  217.  /** 
  218.   * Set HTTP response code to use with headers 
  219.   * 
  220.   * @param int $code 
  221.   * @return Zend_Controller_Response_Abstract 
  222.   */ 
  223.  public function setHttpResponseCode($code
  224.  { 
  225.   if (!is_int($code) || (100 > $code) || (599 < $code)) { 
  226.    require_once 'Zend/Controller/Response/Exception.php'
  227.    throw new Zend_Controller_Response_Exception('Invalid HTTP response code'); 
  228.   } 
  229.   if ((300 <= $code) && (307 >= $code)) { 
  230.    $this->_isRedirect = true; 
  231.   } else { 
  232.    $this->_isRedirect = false; 
  233.   } 
  234.   $this->_httpResponseCode = $code
  235.   return $this
  236.  } 
  237.  /** 
  238.   * Retrieve HTTP response code 
  239.   * 
  240.   * @return int 
  241.   */ 
  242.  public function getHttpResponseCode() 
  243.  { 
  244.   return $this->_httpResponseCode; 
  245.  } 
  246.  /** 
  247.   * Can we send headers? 
  248.   * 
  249.   * @param boolean $throw Whether or not to throw an exception if headers have been sent; defaults to false 
  250.   * @return boolean 
  251.   * @throws Zend_Controller_Response_Exception 
  252.   */ 
  253.  public function canSendHeaders($throw = false) 
  254.  { 
  255.   $ok = headers_sent($file$line); 
  256.   if ($ok && $throw && $this->headersSentThrowsException) { 
  257.    require_once 'Zend/Controller/Response/Exception.php'
  258.    throw new Zend_Controller_Response_Exception('Cannot send headers; headers already sent in ' . $file . ', line ' . $line); 
  259.   } 
  260.   return !$ok
  261.  } 
  262.  /** 
  263.   * Send all headers 
  264.   * 
  265.   * Sends any headers specified. If an {@link setHttpResponseCode() HTTP response code} 
  266.   * has been specified, it is sent with the first header. 
  267.   * 
  268.   * @return Zend_Controller_Response_Abstract 
  269.   */ 
  270.  public function sendHeaders() 
  271.  { 
  272.   // Only check if we can send headers if we have headers to send 
  273.   if (count($this->_headersRaw) || count($this->_headers) || (200 != $this->_httpResponseCode)) { 
  274.    $this->canSendHeaders(true); 
  275.   } elseif (200 == $this->_httpResponseCode) { 
  276.    // Haven't changed the response code, and we have no headers 
  277.    return $this
  278.   } 
  279.   $httpCodeSent = false; 
  280.   foreach ($this->_headersRaw as $header) { 
  281.    if (!$httpCodeSent && $this->_httpResponseCode) { 
  282.     header($header, true, $this->_httpResponseCode); 
  283.     $httpCodeSent = true; 
  284.    } else { 
  285.     header($header); 
  286.    } 
  287.   } 
  288.   foreach ($this->_headers as $header) { 
  289.    if (!$httpCodeSent && $this->_httpResponseCode) { 
  290.     header($header['name'] . ': ' . $header['value'], $header['replace'], $this->_httpResponseCode); 
  291.     $httpCodeSent = true; 
  292.    } else { 
  293.     header($header['name'] . ': ' . $header['value'], $header['replace']); 
  294.    } 
  295.   } 
  296.   if (!$httpCodeSent) { 
  297.    header('HTTP/1.1 ' . $this->_httpResponseCode); 
  298.    $httpCodeSent = true; 
  299.   } 
  300.   return $this
  301.  } 
  302.  /** 
  303.   * Set body content 
  304.   * 
  305.   * If $name is not passed, or is not a string, resets the entire body and 
  306.   * sets the 'default' key to $content. 
  307.   * 
  308.   * If $name is a string, sets the named segment in the body array to 
  309.   * $content. 
  310.   * 
  311.   * @param string $content 
  312.   * @param null|string $name 
  313.   * @return Zend_Controller_Response_Abstract 
  314.   */ 
  315.  public function setBody($content$name = null) 
  316.  { 
  317.   if ((null === $name) || !is_string($name)) { 
  318.    $this->_body = array('default' => (string) $content); 
  319.   } else { 
  320.    $this->_body[$name] = (string) $content
  321.   } 
  322.   return $this
  323.  } 
  324.  /** 
  325.   * Append content to the body content 
  326.   * 
  327.   * @param string $content 
  328.   * @param null|string $name 
  329.   * @return Zend_Controller_Response_Abstract 
  330.   */ 
  331.  public function appendBody($content$name = null) 
  332.  { 
  333.   if ((null === $name) || !is_string($name)) { 
  334.    if (isset($this->_body['default'])) { 
  335.     $this->_body['default'] .= (string) $content
  336.    } else { 
  337.     return $this->append('default'$content); 
  338.    } 
  339.   } elseif (isset($this->_body[$name])) { 
  340.    $this->_body[$name] .= (string) $content
  341.   } else { 
  342.    return $this->append($name$content); 
  343.   } 
  344.   return $this
  345.  } 
  346.  /** 
  347.   * Clear body array 
  348.   * 
  349.   * With no arguments, clears the entire body array. Given a $name, clears 
  350.   * just that named segment; if no segment matching $name exists, returns 
  351.   * false to indicate an error. 
  352.   * 
  353.   * @param string $name Named segment to clear 
  354.   * @return boolean 
  355.   */ 
  356.  public function clearBody($name = null) 
  357.  { 
  358.   if (null !== $name) { 
  359.    $name = (string) $name
  360.    if (isset($this->_body[$name])) { 
  361.     unset($this->_body[$name]); 
  362.     return true; 
  363.    } 
  364.    return false; 
  365.   } 
  366.   $this->_body = array(); 
  367.   return true; 
  368.  } 
  369.  /** 
  370.   * Return the body content 
  371.   * 
  372.   * If $spec is false, returns the concatenated values of the body content 
  373.   * array. If $spec is boolean true, returns the body content array. If 
  374.   * $spec is a string and matches a named segment, returns the contents of 
  375.   * that segment; otherwise, returns null. 
  376.   * 
  377.   * @param boolean $spec 
  378.   * @return string|array|null 
  379.   */ 
  380.  public function getBody($spec = false) 
  381.  { 
  382.   if (false === $spec) { 
  383.    ob_start(); 
  384.    $this->outputBody(); 
  385.    return ob_get_clean(); 
  386.   } elseif (true === $spec) { 
  387.    return $this->_body; 
  388.   } elseif (is_string($spec) && isset($this->_body[$spec])) { 
  389.    return $this->_body[$spec]; 
  390.   } 
  391.   return null; 
  392.  } 
  393.  /** 
  394.   * Append a named body segment to the body content array 
  395.   * 
  396.   * If segment already exists, replaces with $content and places at end of 
  397.   * array. 
  398.   * 
  399.   * @param string $name 
  400.   * @param string $content 
  401.   * @return Zend_Controller_Response_Abstract 
  402.   */ 
  403.  public function append($name$content
  404.  { 
  405.   if (!is_string($name)) { 
  406.    require_once 'Zend/Controller/Response/Exception.php'
  407.    throw new Zend_Controller_Response_Exception('Invalid body segment key ("' . gettype($name) . '")'); 
  408.   } 
  409.   if (isset($this->_body[$name])) { 
  410.    unset($this->_body[$name]); 
  411.   } 
  412.   $this->_body[$name] = (string) $content
  413.   return $this
  414.  } 
  415.  /** 
  416.   * Prepend a named body segment to the body content array 
  417.   * 
  418.   * If segment already exists, replaces with $content and places at top of 
  419.   * array. 
  420.   * 
  421.   * @param string $name 
  422.   * @param string $content 
  423.   * @return void 
  424.   */ 
  425.  public function prepend($name$content
  426.  { 
  427.   if (!is_string($name)) { 
  428.    require_once 'Zend/Controller/Response/Exception.php'
  429.    throw new Zend_Controller_Response_Exception('Invalid body segment key ("' . gettype($name) . '")'); 
  430.   } 
  431.   if (isset($this->_body[$name])) { 
  432.    unset($this->_body[$name]); 
  433.   } 
  434.   $new = array($name => (string) $content); 
  435.   $this->_body = $new + $this->_body; 
  436.   return $this
  437.  } 
  438.  /** 
  439.   * Insert a named segment into the body content array 
  440.   * 
  441.   * @param string $name 
  442.   * @param string $content 
  443.   * @param string $parent 
  444.   * @param boolean $before Whether to insert the new segment before or 
  445.   * after the parent. Defaults to false (after) 
  446.   * @return Zend_Controller_Response_Abstract 
  447.   */ 
  448.  public function insert($name$content$parent = null, $before = false) 
  449.  { 
  450.   if (!is_string($name)) { 
  451.    require_once 'Zend/Controller/Response/Exception.php'
  452.    throw new Zend_Controller_Response_Exception('Invalid body segment key ("' . gettype($name) . '")'); 
  453.   } 
  454.   if ((null !== $parent) && !is_string($parent)) { 
  455.    require_once 'Zend/Controller/Response/Exception.php'
  456.    throw new Zend_Controller_Response_Exception('Invalid body segment parent key ("' . gettype($parent) . '")'); 
  457.   } 
  458.   if (isset($this->_body[$name])) { 
  459.    unset($this->_body[$name]); 
  460.   } 
  461.   if ((null === $parent) || !isset($this->_body[$parent])) { 
  462.    return $this->append($name$content); 
  463.   } 
  464.   $ins = array($name => (string) $content); 
  465.   $keys = array_keys($this->_body); 
  466.   $loc = array_search($parent$keys); 
  467.   if (!$before) { 
  468.    // Increment location if not inserting before 
  469.    ++$loc
  470.   } 
  471.   if (0 === $loc) { 
  472.    // If location of key is 0, we're prepending 
  473.    $this->_body = $ins + $this->_body; 
  474.   } elseif ($loc >= (count($this->_body))) { 
  475.    // If location of key is maximal, we're appending 
  476.    $this->_body = $this->_body + $ins
  477.   } else { 
  478.    // Otherwise, insert at location specified 
  479.    $pre = array_slice($this->_body, 0, $loc); 
  480.    $post = array_slice($this->_body, $loc); 
  481.    $this->_body = $pre + $ins + $post
  482.   } 
  483.   return $this
  484.  } 
  485.  /** 
  486.   * Echo the body segments 
  487.   * 
  488.   * @return void 
  489.   */ 
  490.  public function outputBody() 
  491.  { 
  492.   $body = implode(''$this->_body); 
  493.   echo $body
  494.  } 
  495.  /** 
  496.   * Register an exception with the response 
  497.   * 
  498.   * @param Exception $e 
  499.   * @return Zend_Controller_Response_Abstract 
  500.   */ 
  501.  public function setException(Exception $e
  502.  { 
  503.   $this->_exceptions[] = $e
  504.   return $this
  505.  } 
  506.  /** 
  507.   * Retrieve the exception stack 
  508.   * 
  509.   * @return array 
  510.   */ 
  511.  public function getException() 
  512.  { 
  513.   return $this->_exceptions; 
  514.  } 
  515.  /** 
  516.   * Has an exception been registered with the response? 
  517.   * 
  518.   * @return boolean 
  519.   */ 
  520.  public function isException() 
  521.  { 
  522.   return !emptyempty($this->_exceptions); 
  523.  } 
  524.  /** 
  525.   * Does the response object contain an exception of a given type? 
  526.   * 
  527.   * @param string $type 
  528.   * @return boolean 
  529.   */ 
  530.  public function hasExceptionOfType($type
  531.  { 
  532.   foreach ($this->_exceptions as $e) { 
  533.    if ($e instanceof $type) { 
  534.     return true; 
  535.    } 
  536.   } 
  537.   return false; 
  538.  } 
  539.  /** 
  540.   * Does the response object contain an exception with a given message? 
  541.   * 
  542.   * @param string $message 
  543.   * @return boolean 
  544.   */ 
  545.  public function hasExceptionOfMessage($message
  546.  { 
  547.   foreach ($this->_exceptions as $e) { 
  548.    if ($message == $e->getMessage()) { 
  549.     return true; 
  550.    } 
  551.   } 
  552.   return false; 
  553.  } 
  554.  /** 
  555.   * Does the response object contain an exception with a given code? 
  556.   * 
  557.   * @param int $code 
  558.   * @return boolean 
  559.   */ 
  560.  public function hasExceptionOfCode($code
  561.  { 
  562.   $code = (int) $code
  563.   foreach ($this->_exceptions as $e) { 
  564.    if ($code == $e->getCode()) { 
  565.     return true; 
  566.    } 
  567.   } 
  568.   return false; 
  569.  } 
  570.  /** 
  571.   * Retrieve all exceptions of a given type 
  572.   * 
  573.   * @param string $type 
  574.   * @return false|array 
  575.   */ 
  576.  public function getExceptionByType($type
  577.  { 
  578.   $exceptions = array(); 
  579.   foreach ($this->_exceptions as $e) { 
  580.    if ($e instanceof $type) { 
  581.     $exceptions[] = $e
  582.    } 
  583.   } 
  584.   if (emptyempty($exceptions)) { 
  585.    $exceptions = false; 
  586.   } 
  587.   return $exceptions
  588.  } 
  589.  /** 
  590.   * Retrieve all exceptions of a given message 
  591.   * 
  592.   * @param string $message 
  593.   * @return false|array 
  594.   */ 
  595.  public function getExceptionByMessage($message
  596.  { 
  597.   $exceptions = array(); 
  598.   foreach ($this->_exceptions as $e) { 
  599.    if ($message == $e->getMessage()) { 
  600.     $exceptions[] = $e
  601.    } 
  602.   } 
  603.   if (emptyempty($exceptions)) { 
  604.    $exceptions = false; 
  605.   } 
  606.   return $exceptions
  607.  } 
  608.  /** 
  609.   * Retrieve all exceptions of a given code 
  610.   * 
  611.   * @param mixed $code 
  612.   * @return void 
  613.   */ 
  614.  public function getExceptionByCode($code
  615.  { 
  616.   $code  = (int) $code
  617.   $exceptions = array(); 
  618.   foreach ($this->_exceptions as $e) { 
  619.    if ($code == $e->getCode()) { 
  620.     $exceptions[] = $e
  621.    } 
  622.   } 
  623.   if (emptyempty($exceptions)) { 
  624.    $exceptions = false; 
  625.   } 
  626.   return $exceptions
  627.  } 
  628.  /** 
  629.   * Whether or not to render exceptions (off by default) 
  630.   * 
  631.   * If called with no arguments or a null argument, returns the value of the 
  632.   * flag; otherwise, sets it and returns the current value. 
  633.   * 
  634.   * @param boolean $flag Optional 
  635.   * @return boolean 
  636.   */ 
  637.  public function renderExceptions($flag = null) 
  638.  { 
  639.   if (null !== $flag) { 
  640.    $this->_renderExceptions = $flag ? true : false; 
  641.   } 
  642.   return $this->_renderExceptions; 
  643.  } 
  644.  /** 
  645.   * Send the response, including all headers, rendering exceptions if so 
  646.   * requested. 
  647.   * 
  648.   * @return void 
  649.   */ 
  650.  public function sendResponse() 
  651.  { 
  652.   $this->sendHeaders(); 
  653.   if ($this->isException() && $this->renderExceptions()) { 
  654.    $exceptions = ''
  655.    foreach ($this->getException() as $e) { 
  656.     $exceptions .= $e->__toString() . "\n"
  657.    } 
  658.    echo $exceptions
  659.    return
  660.   } 
  661.   $this->outputBody(); 
  662.  } 
  663.  /** 
  664.   * Magic __toString functionality 
  665.   * 
  666.   * Proxies to {@link sendResponse()} and returns response value as string 
  667.   * using output buffering. 
  668.   * 
  669.   * @return string 
  670.   */ 
  671.  public function __toString() 
  672.  { 
  673.   ob_start(); 
  674.   $this->sendResponse(); 
  675.   return ob_get_clean(); 
  676.  } 

Zend_Controller_Response_Http

  1. /** Zend_Controller_Response_Abstract */ 
  2. require_once 'Zend/Controller/Response/Abstract.php'
  3. /** 
  4.  * Zend_Controller_Response_Http 
  5.  * 
  6.  * HTTP response for controllers 
  7.  * 
  8.  * @uses Zend_Controller_Response_Abstract 
  9.  * @package Zend_Controller 
  10.  * @subpackage Response 
  11.  */ 
  12. class Zend_Controller_Response_Http extends Zend_Controller_Response_Abstract 

常见使用用法

如果要发送响应输出包括消息头,使用sendResponse()。

$response->sendResponse();

Note: 默认地,前端控制器完成分发请求后调用sendResponse();一般地,你不需要调用它,但是,如果你想处理响应或者用它来测试你可以使用Zend_Controller_Front::returnResponse(true)设置returnResponse 标志覆盖默认行为:

  1. $front->returnResponse(true); 
  2. $response = $front->dispatch(); 
  3. // do some more processing, such as logging... 
  4. // and then send the output: 
  5. $response->sendResponse(); 

在动作控制器中使用响应对象,把结果写进响应对象,而不是直接渲染输出和发送消息头:

  1. // Within an action controller action: 
  2. // Set a header 
  3. $this->getResponse() 
  4.  ->setHeader('Content-Type''text/html'
  5.  ->appendBody($content); 

这样做,可以在显示内容之前,将所有消息头一次发送。

Note: 如果使用动作控制器的 视图集成(view integration),你不需要在相应对象中设置渲染的视图脚本,因为Zend_Controller_Action::render() 默认完成了这些。

如果程序中发生了异常,检查响应对象的isException() 标志,使用getException()获取异常。此外,可以创建定制的响应对象重定向到错误页面,记录异常消息,漂亮的格式化异常消息等。

在前端控制器执行dispatch()后可以获得响应对象,或者请求前端控制器返回响应对象代替渲染输出。

  1. // retrieve post-dispatch: 
  2. $front->dispatch(); 
  3. $response = $front->getResponse(); 
  4. if ($response->isException()) { 
  5.  // log, mail, etc... 
  6. // Or, have the front controller dispatch() process return it 
  7. $front->returnResponse(true); 
  8. $response = $front->dispatch(); 
  9. // do some processing... 
  10. // finally, echo the response 
  11. $response->sendResponse(); 

默认地,异常消息是不显示的。可以通过调用renderExceptions()覆盖默认设置,或者启用前端控制器的throwExceptions():

  1. $response->renderExceptions(true); 
  2. $front->dispatch($request$response); 
  3. // or: 
  4. $front->returnResponse(true); 
  5. $response = $front->dispatch(); 
  6. $response->renderExceptions(); 
  7. $response->sendResponse(); 
  8. // or: 
  9. $front->throwExceptions(true); 
  10. $front->dispatch(); 

处理消息头

如上文所述,响应对象的一项重要职责是收集和发出HTTP响应消息头,相应地存在大量的方法:

canSendHeaders() 用来判别消息头是否已发送,该方法带有一个可选的标志指示消息头已发出时是否抛出异常。可以通过设置headersSentThrowsException 属性为false来覆盖默认设置。

setHeader($name, $value, $replace = false)用来设置单独的消息头。默认的不会替换已经存在的同名消息头,但可以设置$replace 为true强制替换.

设置消息头前,该方法先检查canSendHeaders()看操作是否允许,并请求抛出异常。

setRedirect($url, $code = 302) 设置HTTP定位消息头准备重定向,如果提供HTTP状态码,重定向将会使用该状态码。

其内部调用setHeader()并使$replace 标志呈打开状态确保只发送一次定位消息头。

getHeaders() 返回一个消息头数组,每个元素都是一个带有'name'和'value'键的数组。

clearHeaders() 清除所有注册的键值消息头。

setRawHeader() 设置没有键值对的原始消息头,比如HTTP状态消息头。

getRawHeaders() 返回所有注册的原始消息头。

clearRawHeaders()清除所有的原始消息头。

clearAllHeaders() 清除所有的消息头,包括原始消息头和键值消息头。

除了上述方法,还有获取和设置当前请求HTTP响应码的访问器, setHttpResponseCode() 和 getHttpResponseCode().

命名片段

相应对象支持“命名片段”。允许你将消息体分割成不同的片段,并呈一定顺序排列。因此输出的是以特定次序返回的。在其内部,主体内容被存储为一个数组,大量的访问器方法可以用来指示数组内位置和名称。

举例来说,你可以使用preDispatch() 钩子来向响应对象中加入页头,然后在动作控制器中加入主体内容,最后在postDispatch()钩子中加入页脚。

  1. // Assume that this plugin class is registered with the front controller 
  2. class MyPlugin extends Zend_Controller_Plugin_Abstract 
  3.  public function preDispatch(Zend_Controller_Request_Abstract $request
  4.  { 
  5.   $response = $this->getResponse(); 
  6.   $view = new Zend_View(); 
  7.   $view->setBasePath('../views/scripts'); 
  8.   $response->prepend('header'$view->render('header.phtml')); 
  9.  } 
  10.  public function postDispatch(Zend_Controller_Request_Abstract $request
  11.  { 
  12.   $response = $this->getResponse(); 
  13.   $view = new Zend_View(); 
  14.   $view->setBasePath('../views/scripts'); 
  15.   $response->append('footer'$view->render('footer.phtml')); 
  16.  } 
  17. // a sample action controller 
  18. class MyController extends Zend_Controller_Action 
  19.  public function fooAction() 
  20.  { 
  21.   $this->render(); 
  22.  } 

上面的例子中,调用/my/foo会使得最终响应对象中的内容呈现下面的结构:

  1. array
  2.  'header' => ..., // header content 
  3.  'default' => ..., // body content from MyController::fooAction() 
  4.  'footer' => ... // footer content 
  5. ); 

渲染响应时,会按照数组中元素顺序来渲染。

大量的方法可以用来处理命名片段:

setBody() 和 appendBody() 都允许传入一个$name参数,指示一个命名片段。如果提供了这个参数,将会覆盖指定的命名片段,如果该片段不存在就创建一个。如果没有传入$name参数到setBody(),将会重置整个主体内容。如果没有传入$name参数到appendBody(),内容被附加到'default'命名片段。

prepend($name, $content) 将创建一个$name命名片段并放置在数组的开始位置。如果该片段存在,将首先移除。

append($name, $content) 将创建一个$name命名片段,并放置在数组的结尾位置。 如果该片段存在,将首先移除。

insert($name, $content, $parent = null, $before = false) 将创建一个$name命名片段。如果提供$parent参数,新的片段视$before的值决定放置在

$parent的前面或者后面。如果该片段存在,将首先移除。

clearBody($name = null) 如果$name参数提供,将删除该片段,否则删除全部。

getBody($spec = false) 如果$spec参数为一个片段名称,将可以获取到该字段。若$spec参数为false,将返回字符串格式的命名片段顺序链。如果$spec参数为true,返回主体内容数组。

在响应对象中测试异常

如上文所述,默认的,分发过程中的异常发生会在响应对象中注册。异常会注册在一个堆中,允许你抛出所有异常--程序异常,分发异常,插件异常等。如果你要检查或者记录特定的异常,你可能想要使用响应对象的异常API:

setException(Exception $e) 注册一个异常。

isException() 判断该异常是否注册。

getException() 返回整个异常堆。

hasExceptionOfType($type) 判断特定类的异常是否在堆中。

hasExceptionOfMessage($message) 判断带有指定消息的异常是否在堆中。

hasExceptionOfCode($code) 判断带有指定代码的异常是否在堆中。

getExceptionByType($type) 获取堆中特定类的所有异常。如果没有则返回false,否则返回数组。

getExceptionByMessage($message) 获取堆中带有特定消息的所有异常。如果没有则返回false,否则返回数组。

getExceptionByCode($code) 获取堆中带有特定编码的所有异常。如果没有则返回false,否则返回数组。

renderExceptions($flag) 设置标志指示当发送响应时是否发送其中的异常。

自定义响应对象

响应对象的目的首先在于从大量的动作和插件中收集消息头和内容,然后返回到客户端;其次,响应对象也收集发生的任何异常,以处理或者返回这些异常,再或者对终端用户隐藏它们。

响应的基类是Zend_Controller_Response_Abstract,创建的任何子类必须继承这个类或它的衍生类。前面的章节中已经列出了大量可用的方法。

自定义响应对象的原因包括基于请求环境修改返回的内容的输出方式(例如:在CLI和PHP-GTK请求中不发送消息头)增加返回存储在命名片段中内容的最终视图的功能等等。

Tags: Zend_Controller_Response

分享到: