Issues (902)

framework/web/HeaderCollection.php (1 issue)

1
<?php
2
/**
3
 * @link https://www.yiiframework.com/
4
 * @copyright Copyright (c) 2008 Yii Software LLC
5
 * @license https://www.yiiframework.com/license/
6
 */
7
8
namespace yii\web;
9
10
use yii\base\BaseObject;
11
12
/**
13
 * HeaderCollection is used by [[Response]] to maintain the currently registered HTTP headers.
14
 *
15
 * @property-read int $count The number of headers in the collection.
16
 * @property-read \ArrayIterator $iterator An iterator for traversing the headers in the collection.
17
 *
18
 * @author Qiang Xue <[email protected]>
19
 * @since 2.0
20
 */
21
class HeaderCollection extends BaseObject implements \IteratorAggregate, \ArrayAccess, \Countable
22
{
23
    /**
24
     * @var array the headers in this collection (indexed by the normalized header names)
25
     */
26
    private $_headers = [];
27
    /**
28
     * @var array the original names of the headers (indexed by the normalized header names)
29
     */
30
    private $_originalHeaderNames = [];
31
32
33
    /**
34
     * Returns an iterator for traversing the headers in the collection.
35
     * This method is required by the SPL interface [[\IteratorAggregate]].
36
     * It will be implicitly called when you use `foreach` to traverse the collection.
37
     * @return \ArrayIterator an iterator for traversing the headers in the collection.
38
     */
39 36
    #[\ReturnTypeWillChange]
40
    public function getIterator()
41
    {
42 36
        return new \ArrayIterator($this->_headers);
43
    }
44
45
    /**
46
     * Returns the number of headers in the collection.
47
     * This method is required by the SPL `Countable` interface.
48
     * It will be implicitly called when you use `count($collection)`.
49
     * @return int the number of headers in the collection.
50
     */
51 3
    #[\ReturnTypeWillChange]
52
    public function count()
53
    {
54 3
        return $this->getCount();
55
    }
56
57
    /**
58
     * Returns the number of headers in the collection.
59
     * @return int the number of headers in the collection.
60
     */
61 3
    #[\ReturnTypeWillChange]
62
    public function getCount()
63
    {
64 3
        return count($this->_headers);
65
    }
66
67
    /**
68
     * Returns the named header(s).
69
     * @param string $name the name of the header to return
70
     * @param mixed $default the value to return in case the named header does not exist
71
     * @param bool $first whether to only return the first header of the specified name.
72
     * If false, all headers of the specified name will be returned.
73
     * @return string|array|null the named header(s). If `$first` is true, a string will be returned;
74
     * If `$first` is false, an array will be returned.
75
     */
76 205
    public function get($name, $default = null, $first = true)
77
    {
78 205
        $normalizedName = strtolower($name);
79 205
        if (isset($this->_headers[$normalizedName])) {
80 134
            return $first ? reset($this->_headers[$normalizedName]) : $this->_headers[$normalizedName];
81
        }
82
83 104
        return $default;
84
    }
85
86
    /**
87
     * Adds a new header.
88
     * If there is already a header with the same name, it will be replaced.
89
     * @param string $name the name of the header
90
     * @param string $value the value of the header
91
     * @return $this the collection object itself
92
     */
93 152
    public function set($name, $value = '')
94
    {
95 152
        $normalizedName = strtolower($name);
96 152
        $this->_headers[$normalizedName] = (array) $value;
97 152
        $this->_originalHeaderNames[$normalizedName] = $name;
98
99 152
        return $this;
100
    }
101
102
    /**
103
     * Adds a new header.
104
     * If there is already a header with the same name, the new one will
105
     * be appended to it instead of replacing it.
106
     * @param string $name the name of the header
107
     * @param string $value the value of the header
108
     * @return $this the collection object itself
109
     */
110 127
    public function add($name, $value)
111
    {
112 127
        $normalizedName = strtolower($name);
113 127
        $this->_headers[$normalizedName][] = $value;
114 127
        if (!\array_key_exists($normalizedName, $this->_originalHeaderNames)) {
115 127
            $this->_originalHeaderNames[$normalizedName] = $name;
116
        }
117
118 127
        return $this;
119
    }
120
121
    /**
122
     * Sets a new header only if it does not exist yet.
123
     * If there is already a header with the same name, the new one will be ignored.
124
     * @param string $name the name of the header
125
     * @param string $value the value of the header
126
     * @return $this the collection object itself
127
     */
128 9
    public function setDefault($name, $value)
129
    {
130 9
        $normalizedName = strtolower($name);
131 9
        if (empty($this->_headers[$normalizedName])) {
132 9
            $this->_headers[$normalizedName][] = $value;
133 9
            $this->_originalHeaderNames[$normalizedName] = $name;
134
        }
135
136 9
        return $this;
137
    }
138
139
    /**
140
     * Returns a value indicating whether the named header exists.
141
     * @param string $name the name of the header
142
     * @return bool whether the named header exists
143
     */
144 175
    public function has($name)
145
    {
146 175
        return isset($this->_headers[strtolower($name)]);
147
    }
148
149
    /**
150
     * Removes a header.
151
     * @param string $name the name of the header to be removed.
152
     * @return array|null the value of the removed header. Null is returned if the header does not exist.
153
     */
154 246
    public function remove($name)
155
    {
156 246
        $normalizedName = strtolower($name);
157 246
        if (isset($this->_headers[$normalizedName])) {
158 39
            $value = $this->_headers[$normalizedName];
159 39
            unset($this->_headers[$normalizedName], $this->_originalHeaderNames[$normalizedName]);
160 39
            return $value;
161
        }
162
163 245
        return null;
164
    }
165
166
    /**
167
     * Removes all headers.
168
     */
169 1
    public function removeAll()
170
    {
171 1
        $this->_headers = [];
172 1
        $this->_originalHeaderNames = [];
173
    }
174
175
    /**
176
     * Returns the collection as a PHP array.
177
     * @return array the array representation of the collection.
178
     * The array keys are header names, and the array values are the corresponding header values.
179
     */
180 13
    public function toArray()
181
    {
182 13
        return $this->_headers;
183
    }
184
185
    /**
186
     * Returns the collection as a PHP array but instead of using normalized header names as keys (like [[toArray()]])
187
     * it uses original header names (case-sensitive).
188
     * @return array the array representation of the collection.
189
     * @since 2.0.45
190
     */
191 15
    public function toOriginalArray()
192
    {
193 15
        return \array_map(function ($normalizedName) {
194 14
            return $this->_headers[$normalizedName];
195 15
        }, \array_flip($this->_originalHeaderNames));
196
    }
197
198
    /**
199
     * Populates the header collection from an array.
200
     * @param array $array the headers to populate from
201
     * @since 2.0.3
202
     */
203 12
    public function fromArray(array $array)
204
    {
205 12
        foreach ($array as $name => $value) {
206 12
            $this->set($name, $value);
207
        }
208
    }
209
210
    /**
211
     * Returns whether there is a header with the specified name.
212
     * This method is required by the SPL interface [[\ArrayAccess]].
213
     * It is implicitly called when you use something like `isset($collection[$name])`.
214
     * @param string $name the header name
215
     * @return bool whether the named header exists
216
     */
217 4
    #[\ReturnTypeWillChange]
218
    public function offsetExists($name)
219
    {
220 4
        return $this->has($name);
221
    }
222
223
    /**
224
     * Returns the header with the specified name.
225
     * This method is required by the SPL interface [[\ArrayAccess]].
226
     * It is implicitly called when you use something like `$header = $collection[$name];`.
227
     * This is equivalent to [[get()]].
228
     * @param string $name the header name
229
     * @return string|null the header value with the specified name, null if the named header does not exist.
230
     */
231 1
    #[\ReturnTypeWillChange]
232
    public function offsetGet($name)
233
    {
234 1
        return $this->get($name);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->get($name) also could return the type array which is incompatible with the documented return type null|string.
Loading history...
235
    }
236
237
    /**
238
     * Adds the header to the collection.
239
     * This method is required by the SPL interface [[\ArrayAccess]].
240
     * It is implicitly called when you use something like `$collection[$name] = $header;`.
241
     * This is equivalent to [[add()]].
242
     * @param string $name the header name
243
     * @param string $value the header value to be added
244
     */
245 1
    #[\ReturnTypeWillChange]
246
    public function offsetSet($name, $value)
247
    {
248 1
        $this->set($name, $value);
249
    }
250
251
    /**
252
     * Removes the named header.
253
     * This method is required by the SPL interface [[\ArrayAccess]].
254
     * It is implicitly called when you use something like `unset($collection[$name])`.
255
     * This is equivalent to [[remove()]].
256
     * @param string $name the header name
257
     */
258 1
    #[\ReturnTypeWillChange]
259
    public function offsetUnset($name)
260
    {
261 1
        $this->remove($name);
262
    }
263
}
264