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

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 
  13. { 
  14. } 

常见使用用法

如果要发送响应输出包括消息头,使用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. } 
  7. // Or, have the front controller dispatch() process return it 
  8. $front->returnResponse(true); 
  9. $response = $front->dispatch(); 
  10. // do some processing... 
  11. // finally, echo the response 
  12. $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. { 
  4.  public function preDispatch(Zend_Controller_Request_Abstract $request) 
  5.  { 
  6.   $response = $this->getResponse(); 
  7.   $view = new Zend_View(); 
  8.   $view->setBasePath('../views/scripts'); 
  9.   $response->prepend('header', $view->render('header.phtml')); 
  10.  } 
  11.  public function postDispatch(Zend_Controller_Request_Abstract $request) 
  12.  { 
  13.   $response = $this->getResponse(); 
  14.   $view = new Zend_View(); 
  15.   $view->setBasePath('../views/scripts'); 
  16.   $response->append('footer', $view->render('footer.phtml')); 
  17.  } 
  18. } 
  19. // a sample action controller 
  20. class MyController extends Zend_Controller_Action 
  21. { 
  22.  public function fooAction() 
  23.  { 
  24.   $this->render(); 
  25.  } 
  26. } 

上面的例子中,调用/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

分享到: