HeaderBag

class HeaderBag implements IteratorAggregate, Countable

HeaderBag is a container for HTTP headers.

Properties

protected $headers
protected $cacheControl

Methods

public __construct(array $headers = array()) No description
public string __toString() Returns the headers as a string.
public array all() Returns the headers.
public array keys() Returns the parameter keys.
public replace(array $headers = array()) Replaces the current HTTP headers by a new set.
public add(array $headers) Adds new headers the current HTTP headers set.
public string|string[] get(string $key, string|string[] $default = null, bool $first = true) Returns a header value by name.
public set(string $key, string|string[] $values, bool $replace = true) Sets a header by name.
public bool has(string $key) Returns true if the HTTP header is defined.
public bool contains(string $key, string $value) Returns true if the given HTTP header contains the given value.
public remove(string $key) Removes a header.
public null|DateTime getDate(string $key, DateTime $default = null) Returns the HTTP header value converted to a date.
public addCacheControlDirective(string $key, mixed $value = true) Adds a custom Cache-Control directive.
public bool hasCacheControlDirective(string $key) Returns true if the Cache-Control directive is defined.
public mixed|null getCacheControlDirective(string $key) Returns a Cache-Control directive value by name.
public removeCacheControlDirective(string $key) Removes a Cache-Control directive.
public ArrayIterator getIterator() Returns an iterator for headers.
public int count() Returns the number of headers.
protected getCacheControlHeader() No description
protected array parseCacheControl(string $header) Parses a Cache-Control HTTP header.

Details

at line 27

__construct()

public __construct(array $headers = array())

Parameters

array $headers An array of HTTP headers
at line 39

__toString()

public string __toString()

Returns the headers as a string.

Return Value

string The headers
at line 63

all()

public array all()

Returns the headers.

Return Value

array An array of headers
at line 73

keys()

public array keys()

Returns the parameter keys.

Return Value

array An array of parameter keys
at line 83

replace()

public replace(array $headers = array())

Replaces the current HTTP headers by a new set.

Parameters

array $headers An array of HTTP headers
at line 94

add()

public add(array $headers)

Adds new headers the current HTTP headers set.

Parameters

array $headers An array of HTTP headers
at line 110

get()

public string|string[] get(string $key, string|string[] $default = null, bool $first = true)

Returns a header value by name.

Parameters

string $key The header name
string|string[] $default The default value
bool $first Whether to return the first value or all header values

Return Value

string|string[] The first header value or default value if $first is true, an array of values otherwise
at line 137

set()

public set(string $key, string|string[] $values, bool $replace = true)

Sets a header by name.

Parameters

string $key The key
string|string[] $values The value or an array of values
bool $replace Whether to replace the actual value or not (true by default)
at line 169

has()

public bool has(string $key)

Returns true if the HTTP header is defined.

Parameters

string $key The HTTP header

Return Value

bool true if the parameter exists, false otherwise
at line 182

contains()

public bool contains(string $key, string $value)

Returns true if the given HTTP header contains the given value.

Parameters

string $key The HTTP header name
string $value The HTTP value

Return Value

bool true if the value is contained in the header, false otherwise
at line 192

remove()

public remove(string $key)

Removes a header.

Parameters

string $key The HTTP header name
at line 213

getDate()

public null|DateTime getDate(string $key, DateTime $default = null)

Returns the HTTP header value converted to a date.

Parameters

string $key The parameter key
DateTime $default The default value

Return Value

null|DateTime The parsed DateTime or the default value if the header does not exist

Exceptions

RuntimeException When the HTTP header is not parseable
at line 232

addCacheControlDirective()

public addCacheControlDirective(string $key, mixed $value = true)

Adds a custom Cache-Control directive.

Parameters

string $key The Cache-Control directive name
mixed $value The Cache-Control directive value
at line 246

hasCacheControlDirective()

public bool hasCacheControlDirective(string $key)

Returns true if the Cache-Control directive is defined.

Parameters

string $key The Cache-Control directive

Return Value

bool true if the directive exists, false otherwise
at line 258

getCacheControlDirective()

public mixed|null getCacheControlDirective(string $key)

Returns a Cache-Control directive value by name.

Parameters

string $key The directive name

Return Value

mixed|null The directive value if defined, null otherwise
at line 268

removeCacheControlDirective()

public removeCacheControlDirective(string $key)

Removes a Cache-Control directive.

Parameters

string $key The Cache-Control directive
at line 280

getIterator()

public ArrayIterator getIterator()

Returns an iterator for headers.

Return Value

ArrayIterator An \ArrayIterator instance
at line 290

count()

public int count()

Returns the number of headers.

Return Value

int The number of headers
at line 295

getCacheControlHeader()

protected getCacheControlHeader()
at line 321

parseCacheControl()

protected array parseCacheControl(string $header)

Parses a Cache-Control HTTP header.

Parameters

string $header The value of the Cache-Control HTTP header

Return Value

array An array representing the attribute values

Source code

<?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 App\Khan\Component\HttpFoundation;

/**
 * HeaderBag is a container for HTTP headers.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class HeaderBag implements \IteratorAggregate, \Countable
{
    protected $headers = array();
    protected $cacheControl = array();

    /**
     * @param array $headers An array of HTTP headers
     */
    public function __construct(array $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 (!$headers = $this->all()) {
            return '';
        }

        ksort($headers);
        $max = max(array_map('strlen', array_keys($headers))) + 1;
        $content = '';
        foreach ($headers as $name => $values) {
            $name = ucwords($name, '-');
            foreach ($values as $value) {
                $content .= sprintf("%-{$max}s %s\r\n", $name.':', $value);
            }
        }

        return $content;
    }

    /**
     * Returns the headers.
     *
     * @return array An array of headers
     */
    public function all()
    {
        return $this->headers;
    }

    /**
     * Returns the parameter keys.
     *
     * @return array An array of parameter keys
     */
    public function keys()
    {
        return array_keys($this->all());
    }

    /**
     * Replaces the current HTTP headers by a new set.
     *
     * @param array $headers An array of HTTP headers
     */
    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
     */
    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 string|string[] $default The default value
     * @param bool            $first   Whether to return the first value or all header values
     *
     * @return string|string[] The first header value or default value if $first is true, an array of values otherwise
     */
    public function get($key, $default = null, $first = true)
    {
        $key = str_replace('_', '-', strtolower($key));
        $headers = $this->all();

        if (!array_key_exists($key, $headers)) {
            if (null === $default) {
                return $first ? null : array();
            }

            return $first ? $default : array($default);
        }

        if ($first) {
            return \count($headers[$key]) ? $headers[$key][0] : $default;
        }

        return $headers[$key];
    }

    /**
     * Sets a header by name.
     *
     * @param string          $key     The key
     * @param string|string[] $values  The value or an array of values
     * @param bool            $replace Whether to replace the actual value or not (true by default)
     */
    public function set($key, $values, $replace = true)
    {
        $key = str_replace('_', '-', strtolower($key));

        if (\is_array($values)) {
            $values = array_values($values);

            if (true === $replace || !isset($this->headers[$key])) {
                $this->headers[$key] = $values;
            } else {
                $this->headers[$key] = array_merge($this->headers[$key], $values);
            }
        } else {
            if (true === $replace || !isset($this->headers[$key])) {
                $this->headers[$key] = array($values);
            } else {
                $this->headers[$key][] = $values;
            }
        }

        if ('cache-control' === $key) {
            $this->cacheControl = $this->parseCacheControl(implode(', ', $this->headers[$key]));
        }
    }

    /**
     * Returns true if the HTTP header is defined.
     *
     * @param string $key The HTTP header
     *
     * @return bool true if the parameter exists, false otherwise
     */
    public function has($key)
    {
        return array_key_exists(str_replace('_', '-', strtolower($key)), $this->all());
    }

    /**
     * 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 bool true if the value is contained in the header, false otherwise
     */
    public function contains($key, $value)
    {
        return in_array($value, $this->get($key, null, false));
    }

    /**
     * Removes a header.
     *
     * @param string $key The HTTP header name
     */
    public function remove($key)
    {
        $key = str_replace('_', '-', 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 parsed DateTime or the default value if the header does not exist
     *
     * @throws \RuntimeException When the HTTP header is not parseable
     */
    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;
    }

    /**
     * Adds a custom Cache-Control directive.
     *
     * @param string $key   The Cache-Control directive name
     * @param mixed  $value The Cache-Control directive value
     */
    public function addCacheControlDirective($key, $value = true)
    {
        $this->cacheControl[$key] = $value;

        $this->set('Cache-Control', $this->getCacheControlHeader());
    }

    /**
     * Returns true if the Cache-Control directive is defined.
     *
     * @param string $key The Cache-Control directive
     *
     * @return bool true if the directive exists, false otherwise
     */
    public function hasCacheControlDirective($key)
    {
        return array_key_exists($key, $this->cacheControl);
    }

    /**
     * Returns a Cache-Control directive value by name.
     *
     * @param string $key The directive name
     *
     * @return mixed|null The directive value if defined, null otherwise
     */
    public function getCacheControlDirective($key)
    {
        return array_key_exists($key, $this->cacheControl) ? $this->cacheControl[$key] : null;
    }

    /**
     * Removes a Cache-Control directive.
     *
     * @param string $key The Cache-Control directive
     */
    public function removeCacheControlDirective($key)
    {
        unset($this->cacheControl[$key]);

        $this->set('Cache-Control', $this->getCacheControlHeader());
    }

    /**
     * Returns an iterator for headers.
     *
     * @return \ArrayIterator An \ArrayIterator instance
     */
    public function getIterator()
    {
        return new \ArrayIterator($this->headers);
    }

    /**
     * Returns the number of headers.
     *
     * @return int The number of headers
     */
    public function count()
    {
        return count($this->headers);
    }

    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[3]) ? $match[3] : (isset($match[2]) ? $match[2] : true);
        }

        return $cacheControl;
    }
}