Skip to content

Commit e443081

Browse files
committed
Adds HeaderBag object.
1 parent 29d64f5 commit e443081

3 files changed

Lines changed: 142 additions & 1 deletion

File tree

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
},
3232
"require": {
3333
"ext-json": "*",
34-
"symfony/property-access": "^3.4|^4.4|5.*"
34+
"symfony/property-access": "^3.4|^4.4|5.*",
35+
"psr/container": "^2.0"
3536
}
3637
}

src/Helper/NotFoundException.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
namespace DevCoding\Helper;
4+
5+
use Psr\Container\NotFoundExceptionInterface;
6+
7+
class NotFoundException extends \Exception implements NotFoundExceptionInterface
8+
{
9+
}

src/Object/Internet/HeaderBag.php

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
<?php
2+
3+
namespace DevCoding\Object\Internet;
4+
5+
use DevCoding\Helper\NotFoundException;
6+
use Psr\Container\ContainerInterface;
7+
8+
/**
9+
* Container representing HTTP headers, as taken from the $_SERVER global. Note that all keys should be given without
10+
* the HTTP_ prefix.
11+
*
12+
* The concept of this class is based on the Symfony HttpFoundation component. This version is simplified and
13+
* does not contain all the same functionality.
14+
*
15+
* @author AMJones <am@jonesiscoding.com>
16+
* @license https://github.com/deviscoding/objection/blob/main/LICENSE
17+
*
18+
* @package DevCoding\Object\Internet
19+
*/
20+
class HeaderBag implements ContainerInterface
21+
{
22+
const UPPER = '_ABCDEFGHIJKLMNOPQRSTUVWXYZ';
23+
const LOWER = '-abcdefghijklmnopqrstuvwxyz';
24+
25+
/** @var array Array containing previously parsed headers */
26+
protected $headers;
27+
28+
/**
29+
* Resolves the given header key or array of header keys into a value, using the value of the first header that is
30+
* set in the $_SERVER global or this object.
31+
*
32+
* @param array|string $key_or_keys The header key, without the HTTP_ prefix
33+
*
34+
* @return mixed|null The value, or null if it cannot be resolved
35+
*/
36+
public function resolve($key_or_keys)
37+
{
38+
if (!is_array($key_or_keys))
39+
{
40+
return $this->get($key_or_keys);
41+
}
42+
else
43+
{
44+
foreach ($key_or_keys as $key)
45+
{
46+
if ($this->has($key))
47+
{
48+
return $this->get($key);
49+
}
50+
}
51+
}
52+
53+
return null;
54+
}
55+
56+
/**
57+
* Returns the value of the header key given.
58+
*
59+
* @param string $id the header key to retreive, given without the HTTP_ prefix
60+
*
61+
* @return mixed the value of the given header key
62+
*
63+
* @throws \Exception if the header is not set
64+
*/
65+
public function get(string $id)
66+
{
67+
if (!$this->has($id))
68+
{
69+
throw new NotFoundException(sprintf('The header "%s" was not found.', $id));
70+
}
71+
72+
return $this->headers[$id];
73+
}
74+
75+
/**
76+
* Evaluates whether a value is set for the given header key, which should be given without the HTTP_ prefix.
77+
*/
78+
public function has(string $id): bool
79+
{
80+
if (!isset($this->headers[$id]))
81+
{
82+
$sKey = $this->toServer($id);
83+
$sVal = $_ENV[$sKey] ?? $_SERVER[$sKey];
84+
if (!isset($sVal))
85+
{
86+
return false;
87+
}
88+
89+
$this->headers[$id] = $sVal;
90+
}
91+
92+
return true;
93+
}
94+
95+
/**
96+
* Populates the $_SERVER global with the given array of values. The array keys should be given without the HTTP_
97+
* prefix.
98+
*
99+
* @param string[] $array the array of header_key => value
100+
* @param bool $overwrite if existing values should be overwritten
101+
*
102+
* @return $this
103+
*/
104+
public function populate($array, $overwrite = false)
105+
{
106+
foreach ($array as $key => $value)
107+
{
108+
$sKey = $this->toServer($key);
109+
$sVal = $_ENV[$sKey] ?? $_SERVER[$sKey];
110+
if (!isset($sVal) || $overwrite)
111+
{
112+
// TODO: Set in ENV?
113+
$_SERVER[$sKey] = $value;
114+
}
115+
}
116+
117+
return $this;
118+
}
119+
120+
/**
121+
* Given a header key, returns the key the header would use within the $_SERVER global.
122+
*
123+
* @param string $id
124+
*
125+
* @return string
126+
*/
127+
public static function toServer($id)
128+
{
129+
return 'HTTP_'.strtr($id, self::LOWER, self::UPPER);
130+
}
131+
}

0 commit comments

Comments
 (0)