Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

309 lines (268 sloc) 7.816 kb
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\HttpFoundation;
/**
* HeaderBag is a container for HTTP headers.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @api
*/
class HeaderBag
{
protected $headers;
protected $cacheControl;
/**
* Constructor.
*
* @param array $headers An array of HTTP headers
*
* @api
*/
public function __construct(array $headers = array())
{
$this->cacheControl = array();
$this->headers = array();
foreach ($headers as $key => $values) {
$this->set($key, $values);
}
}
/**
* Returns the headers as a string.
*
* @return string The headers
*/
public function __toString()
{
if (!$this->headers) {
return '';
}
$beautifier = function ($name) {
return preg_replace_callback('/\-(.)/', function ($match) { return '-'.strtoupper($match[1]); }, ucfirst($name));
};
$max = max(array_map('strlen', array_keys($this->headers))) + 1;
$content = '';
ksort($this->headers);
foreach ($this->headers as $name => $values) {
foreach ($values as $value) {
$content .= sprintf("%-{$max}s %s\r\n", $beautifier($name).':', $value);
}
}
return $content;
}
/**
* Returns the headers.
*
* @return array An array of headers
*
* @api
*/
public function all()
{
return $this->headers;
}
/**
* Returns the parameter keys.
*
* @return array An array of parameter keys
*
* @api
*/
public function keys()
{
return array_keys($this->headers);
}
/**
* Replaces the current HTTP headers by a new set.
*
* @param array $headers An array of HTTP headers
*
* @api
*/
public function replace(array $headers = array())
{
$this->headers = array();
$this->add($headers);
}
/**
* Adds new headers the current HTTP headers set.
*
* @param array $headers An array of HTTP headers
*
* @api
*/
public function add(array $headers)
{
foreach ($headers as $key => $values) {
$this->set($key, $values);
}
}
/**
* Returns a header value by name.
*
* @param string $key The header name
* @param mixed $default The default value
* @param Boolean $first Whether to return the first value or all header values
*
* @return string|array The first header value if $first is true, an array of values otherwise
*
* @api
*/
public function get($key, $default = null, $first = true)
{
$key = strtr(strtolower($key), '_', '-');
if (!array_key_exists($key, $this->headers)) {
if (null === $default) {
return $first ? null : array();
}
return $first ? $default : array($default);
}
if ($first) {
return count($this->headers[$key]) ? $this->headers[$key][0] : $default;
}
return $this->headers[$key];
}
/**
* Sets a header by name.
*
* @param string $key The key
* @param string|array $values The value or an array of values
* @param Boolean $replace Whether to replace the actual value of not (true by default)
*
* @api
*/
public function set($key, $values, $replace = true)
{
$key = strtr(strtolower($key), '_', '-');
$values = (array) $values;
if (true === $replace || !isset($this->headers[$key])) {
$this->headers[$key] = $values;
} else {
$this->headers[$key] = array_merge($this->headers[$key], $values);
}
if ('cache-control' === $key) {
$this->cacheControl = $this->parseCacheControl($values[0]);
}
}
/**
* Returns true if the HTTP header is defined.
*
* @param string $key The HTTP header
*
* @return Boolean true if the parameter exists, false otherwise
*
* @api
*/
public function has($key)
{
return array_key_exists(strtr(strtolower($key), '_', '-'), $this->headers);
}
/**
* Returns true if the given HTTP header contains the given value.
*
* @param string $key The HTTP header name
* @param string $value The HTTP value
*
* @return Boolean true if the value is contained in the header, false otherwise
*
* @api
*/
public function contains($key, $value)
{
return in_array($value, $this->get($key, null, false));
}
/**
* Removes a header.
*
* @param string $key The HTTP header name
*
* @api
*/
public function remove($key)
{
$key = strtr(strtolower($key), '_', '-');
unset($this->headers[$key]);
if ('cache-control' === $key) {
$this->cacheControl = array();
}
}
/**
* Returns the HTTP header value converted to a date.
*
* @param string $key The parameter key
* @param \DateTime $default The default value
*
* @return null|\DateTime The filtered value
*
* @throws \RuntimeException When the HTTP header is not parseable
*
* @api
*/
public function getDate($key, \DateTime $default = null)
{
if (null === $value = $this->get($key)) {
return $default;
}
if (false === $date = \DateTime::createFromFormat(DATE_RFC2822, $value)) {
throw new \RuntimeException(sprintf('The %s HTTP header is not parseable (%s).', $key, $value));
}
return $date;
}
public function addCacheControlDirective($key, $value = true)
{
$this->cacheControl[$key] = $value;
$this->set('Cache-Control', $this->getCacheControlHeader());
}
public function hasCacheControlDirective($key)
{
return array_key_exists($key, $this->cacheControl);
}
public function getCacheControlDirective($key)
{
return array_key_exists($key, $this->cacheControl) ? $this->cacheControl[$key] : null;
}
public function removeCacheControlDirective($key)
{
unset($this->cacheControl[$key]);
$this->set('Cache-Control', $this->getCacheControlHeader());
}
protected function getCacheControlHeader()
{
$parts = array();
ksort($this->cacheControl);
foreach ($this->cacheControl as $key => $value) {
if (true === $value) {
$parts[] = $key;
} else {
if (preg_match('#[^a-zA-Z0-9._-]#', $value)) {
$value = '"'.$value.'"';
}
$parts[] = "$key=$value";
}
}
return implode(', ', $parts);
}
/**
* Parses a Cache-Control HTTP header.
*
* @param string $header The value of the Cache-Control HTTP header
*
* @return array An array representing the attribute values
*/
protected function parseCacheControl($header)
{
$cacheControl = array();
preg_match_all('#([a-zA-Z][a-zA-Z_-]*)\s*(?:=(?:"([^"]*)"|([^ \t",;]*)))?#', $header, $matches, PREG_SET_ORDER);
foreach ($matches as $match) {
$cacheControl[strtolower($match[1])] = isset($match[2]) && $match[2] ? $match[2] : (isset($match[3]) ? $match[3] : true);
}
return $cacheControl;
}
}
Jump to Line
Something went wrong with that request. Please try again.