198 lines
5.1 KiB
PHP
198 lines
5.1 KiB
PHP
<?php
|
|
/**
|
|
* Slim Framework (http://slimframework.com)
|
|
*
|
|
* @link https://github.com/slimphp/Slim
|
|
* @copyright Copyright (c) 2011-2015 Josh Lockhart
|
|
* @license https://github.com/slimphp/Slim/blob/3.x/LICENSE.md (MIT License)
|
|
*/
|
|
namespace Slim\Http;
|
|
|
|
use Slim\Collection;
|
|
use Slim\Interfaces\Http\HeadersInterface;
|
|
|
|
/**
|
|
* Headers
|
|
*
|
|
* This class represents a collection of HTTP headers
|
|
* that is used in both the HTTP request and response objects.
|
|
* It also enables header name case-insensitivity when
|
|
* getting or setting a header value.
|
|
*
|
|
* Each HTTP header can have multiple values. This class
|
|
* stores values into an array for each header name. When
|
|
* you request a header value, you receive an array of values
|
|
* for that header.
|
|
*/
|
|
class Headers extends Collection implements HeadersInterface
|
|
{
|
|
/**
|
|
* Special HTTP headers that do not have the "HTTP_" prefix
|
|
*
|
|
* @var array
|
|
*/
|
|
protected static $special = [
|
|
'CONTENT_TYPE' => 1,
|
|
'CONTENT_LENGTH' => 1,
|
|
'PHP_AUTH_USER' => 1,
|
|
'PHP_AUTH_PW' => 1,
|
|
'PHP_AUTH_DIGEST' => 1,
|
|
'AUTH_TYPE' => 1,
|
|
];
|
|
|
|
/**
|
|
* Create new headers collection with data extracted from
|
|
* the application Environment object
|
|
*
|
|
* @param Environment $environment The Slim application Environment
|
|
*
|
|
* @return self
|
|
*/
|
|
public static function createFromEnvironment(Environment $environment)
|
|
{
|
|
$data = [];
|
|
foreach ($environment as $key => $value) {
|
|
$key = strtoupper($key);
|
|
if (isset(static::$special[$key]) || strpos($key, 'HTTP_') === 0) {
|
|
if ($key !== 'HTTP_CONTENT_LENGTH') {
|
|
$data[$key] = $value;
|
|
}
|
|
}
|
|
}
|
|
|
|
return new static($data);
|
|
}
|
|
|
|
/**
|
|
* Return array of HTTP header names and values.
|
|
* This method returns the _original_ header name
|
|
* as specified by the end user.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function all()
|
|
{
|
|
$all = parent::all();
|
|
$out = [];
|
|
foreach ($all as $key => $props) {
|
|
$out[$props['originalKey']] = $props['value'];
|
|
}
|
|
|
|
return $out;
|
|
}
|
|
|
|
/**
|
|
* Set HTTP header value
|
|
*
|
|
* This method sets a header value. It replaces
|
|
* any values that may already exist for the header name.
|
|
*
|
|
* @param string $key The case-insensitive header name
|
|
* @param string $value The header value
|
|
*/
|
|
public function set($key, $value)
|
|
{
|
|
if (!is_array($value)) {
|
|
$value = [$value];
|
|
}
|
|
parent::set($this->normalizeKey($key), [
|
|
'value' => $value,
|
|
'originalKey' => $key
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Get HTTP header value
|
|
*
|
|
* @param string $key The case-insensitive header name
|
|
* @param mixed $default The default value if key does not exist
|
|
*
|
|
* @return string[]
|
|
*/
|
|
public function get($key, $default = null)
|
|
{
|
|
if ($this->has($key)) {
|
|
return parent::get($this->normalizeKey($key))['value'];
|
|
}
|
|
|
|
return $default;
|
|
}
|
|
|
|
/**
|
|
* Get HTTP header key as originally specified
|
|
*
|
|
* @param string $key The case-insensitive header name
|
|
* @param mixed $default The default value if key does not exist
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getOriginalKey($key, $default = null)
|
|
{
|
|
if ($this->has($key)) {
|
|
return parent::get($this->normalizeKey($key))['originalKey'];
|
|
}
|
|
|
|
return $default;
|
|
}
|
|
|
|
/**
|
|
* Add HTTP header value
|
|
*
|
|
* This method appends a header value. Unlike the set() method,
|
|
* this method _appends_ this new value to any values
|
|
* that already exist for this header name.
|
|
*
|
|
* @param string $key The case-insensitive header name
|
|
* @param array|string $value The new header value(s)
|
|
*/
|
|
public function add($key, $value)
|
|
{
|
|
$oldValues = $this->get($key, []);
|
|
$newValues = is_array($value) ? $value : [$value];
|
|
$this->set($key, array_merge($oldValues, array_values($newValues)));
|
|
}
|
|
|
|
/**
|
|
* Does this collection have a given header?
|
|
*
|
|
* @param string $key The case-insensitive header name
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function has($key)
|
|
{
|
|
return parent::has($this->normalizeKey($key));
|
|
}
|
|
|
|
/**
|
|
* Remove header from collection
|
|
*
|
|
* @param string $key The case-insensitive header name
|
|
*/
|
|
public function remove($key)
|
|
{
|
|
parent::remove($this->normalizeKey($key));
|
|
}
|
|
|
|
/**
|
|
* Normalize header name
|
|
*
|
|
* This method transforms header names into a
|
|
* normalized form. This is how we enable case-insensitive
|
|
* header names in the other methods in this class.
|
|
*
|
|
* @param string $key The case-insensitive header name
|
|
*
|
|
* @return string Normalized header name
|
|
*/
|
|
public function normalizeKey($key)
|
|
{
|
|
$key = strtr(strtolower($key), '_', '-');
|
|
if (strpos($key, 'http-') === 0) {
|
|
$key = substr($key, 5);
|
|
}
|
|
|
|
return $key;
|
|
}
|
|
}
|