1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Saxulum\HttpMessage; |
4
|
|
|
|
5
|
|
|
use Psr\Http\Message\ResponseInterface; |
6
|
|
|
|
7
|
|
|
final class Response extends AbstractMessage implements ResponseInterface |
8
|
|
|
{ |
9
|
|
|
/** |
10
|
|
|
* @var int|null |
11
|
|
|
*/ |
12
|
|
|
private $statusCode; |
13
|
|
|
|
14
|
|
|
/** |
15
|
|
|
* @var string|null |
16
|
|
|
*/ |
17
|
|
|
private $reasonPhrase; |
18
|
|
|
|
19
|
|
|
const REASON_PHRASE_100 = 'Continue'; |
20
|
|
|
const REASON_PHRASE_101 = 'Switching Protocols'; |
21
|
|
|
const REASON_PHRASE_102 = 'Processing'; |
22
|
|
|
const REASON_PHRASE_200 = 'OK'; |
23
|
|
|
const REASON_PHRASE_201 = 'Created'; |
24
|
|
|
const REASON_PHRASE_202 = 'Accepted'; |
25
|
|
|
const REASON_PHRASE_203 = 'Non-Authoritative Information'; |
26
|
|
|
const REASON_PHRASE_204 = 'No Content'; |
27
|
|
|
const REASON_PHRASE_205 = 'Reset Content'; |
28
|
|
|
const REASON_PHRASE_206 = 'Partial Content'; |
29
|
|
|
const REASON_PHRASE_207 = 'Multi-Status'; |
30
|
|
|
const REASON_PHRASE_208 = 'Already Reported'; |
31
|
|
|
const REASON_PHRASE_226 = 'IM Used'; |
32
|
|
|
const REASON_PHRASE_300 = 'Multiple Choices'; |
33
|
|
|
const REASON_PHRASE_301 = 'Moved Permanently'; |
34
|
|
|
const REASON_PHRASE_302 = 'Found'; |
35
|
|
|
const REASON_PHRASE_303 = 'See Other'; |
36
|
|
|
const REASON_PHRASE_304 = 'Not Modified'; |
37
|
|
|
const REASON_PHRASE_305 = 'Use Proxy'; |
38
|
|
|
const REASON_PHRASE_306 = '(reserved)'; |
39
|
|
|
const REASON_PHRASE_307 = 'Temporary Redirect'; |
40
|
|
|
const REASON_PHRASE_308 = 'Permanent Redirect'; |
41
|
|
|
const REASON_PHRASE_400 = 'Bad Request'; |
42
|
|
|
const REASON_PHRASE_401 = 'Unauthorized'; |
43
|
|
|
const REASON_PHRASE_402 = 'Payment Required'; |
44
|
|
|
const REASON_PHRASE_403 = 'Forbidden'; |
45
|
|
|
const REASON_PHRASE_404 = 'Not Found'; |
46
|
|
|
const REASON_PHRASE_405 = 'Method Not Allowed'; |
47
|
|
|
const REASON_PHRASE_406 = 'Not Acceptable'; |
48
|
|
|
const REASON_PHRASE_407 = 'Proxy Authentication Required'; |
49
|
|
|
const REASON_PHRASE_408 = 'Request Time-out'; |
50
|
|
|
const REASON_PHRASE_409 = 'Conflict'; |
51
|
|
|
const REASON_PHRASE_410 = 'Gone'; |
52
|
|
|
const REASON_PHRASE_411 = 'Length Required'; |
53
|
|
|
const REASON_PHRASE_412 = 'Precondition Failed'; |
54
|
|
|
const REASON_PHRASE_413 = 'Request Entity Too Large'; |
55
|
|
|
const REASON_PHRASE_414 = 'Request-URL Too Long'; |
56
|
|
|
const REASON_PHRASE_415 = 'Unsupported Media Type'; |
57
|
|
|
const REASON_PHRASE_416 = 'Requested range not satisfiable'; |
58
|
|
|
const REASON_PHRASE_417 = 'Expectation Failed'; |
59
|
|
|
const REASON_PHRASE_418 = 'I’m a teapot'; |
60
|
|
|
const REASON_PHRASE_420 = 'Policy Not Fulfilled'; |
61
|
|
|
const REASON_PHRASE_421 = 'There are too many connections from your internet address'; |
62
|
|
|
const REASON_PHRASE_422 = 'Unprocessable Entity'; |
63
|
|
|
const REASON_PHRASE_423 = 'Locked'; |
64
|
|
|
const REASON_PHRASE_424 = 'Failed Dependency'; |
65
|
|
|
const REASON_PHRASE_425 = 'Unordered Collection'; |
66
|
|
|
const REASON_PHRASE_426 = 'Upgrade Required'; |
67
|
|
|
const REASON_PHRASE_428 = 'Precondition Required'; |
68
|
|
|
const REASON_PHRASE_429 = 'Too Many Requests'; |
69
|
|
|
const REASON_PHRASE_431 = 'Request Header Fields Too Large'; |
70
|
|
|
const REASON_PHRASE_444 = 'No Response'; |
71
|
|
|
const REASON_PHRASE_449 = 'The request should be retried after doing the appropriate action'; |
72
|
|
|
const REASON_PHRASE_451 = 'Unavailable For Legal Reasons'; |
73
|
|
|
const REASON_PHRASE_500 = 'Internal Server Error'; |
74
|
|
|
const REASON_PHRASE_501 = 'Not Implemented'; |
75
|
|
|
const REASON_PHRASE_502 = 'Bad Gateway'; |
76
|
|
|
const REASON_PHRASE_503 = 'Service Unavailable'; |
77
|
|
|
const REASON_PHRASE_504 = 'Gateway Time-out'; |
78
|
|
|
const REASON_PHRASE_505 = 'HTTP Version not supported'; |
79
|
|
|
const REASON_PHRASE_506 = 'Variant Also Negotiates'; |
80
|
|
|
const REASON_PHRASE_507 = 'Insufficient Storage'; |
81
|
|
|
const REASON_PHRASE_508 = 'Loop Detected'; |
82
|
|
|
const REASON_PHRASE_509 = 'Bandwidth Limit Exceeded'; |
83
|
|
|
const REASON_PHRASE_510 = 'Not Extended'; |
84
|
|
|
|
85
|
|
|
/** |
86
|
|
|
* @var ResponseInterface|null |
87
|
|
|
*/ |
88
|
|
|
protected $__previous; |
89
|
|
|
|
90
|
|
|
/** |
91
|
|
|
* @param int $statusCode |
92
|
|
|
* @param string $reasonPhrase |
93
|
|
|
* @param string $protocolVersion |
94
|
|
|
* @param array $headers |
95
|
|
|
* @param string|null $body |
96
|
|
|
* @param ResponseInterface|null $__previous |
97
|
|
|
*/ |
98
|
|
|
public function __construct( |
99
|
|
|
int $statusCode = null, |
100
|
|
|
string $reasonPhrase = null, |
101
|
|
|
string $protocolVersion = null, |
102
|
|
|
array $headers = [], |
103
|
|
|
string $body = null, |
104
|
|
|
ResponseInterface $__previous = null |
105
|
|
|
) { |
106
|
|
|
$this->statusCode = $statusCode; |
107
|
|
|
$this->reasonPhrase = $reasonPhrase; |
108
|
|
|
$this->protocolVersion = $protocolVersion; |
109
|
|
|
$this->headers = $headers; |
110
|
|
|
$this->body = $body; |
|
|
|
|
111
|
|
|
$this->__previous = $__previous; |
112
|
|
|
} |
113
|
|
|
|
114
|
|
|
/** |
115
|
|
|
* {@inheritdoc} |
116
|
|
|
*/ |
117
|
|
|
public function getStatusCode() |
118
|
|
|
{ |
119
|
|
|
return (int) $this->statusCode; |
120
|
|
|
} |
121
|
|
|
|
122
|
|
|
/** |
123
|
|
|
* {@inheritdoc} |
124
|
|
|
*/ |
125
|
|
|
public function withStatus($code, $reasonPhrase = '') |
126
|
|
|
{ |
127
|
|
|
return $this->with(['statusCode' => $code, 'reasonPhrase' => $reasonPhrase]); |
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
/** |
131
|
|
|
* {@inheritdoc} |
132
|
|
|
*/ |
133
|
|
|
public function getReasonPhrase() |
134
|
|
|
{ |
135
|
|
|
return (string) $this->reasonPhrase; |
136
|
|
|
} |
137
|
|
|
|
138
|
|
|
/** |
139
|
|
|
* @param array $parameters |
140
|
|
|
* |
141
|
|
|
* @return Response |
142
|
|
|
*/ |
143
|
|
View Code Duplication |
protected function with(array $parameters): self |
|
|
|
|
144
|
|
|
{ |
145
|
|
|
$defaults = [ |
146
|
|
|
'statusCode' => $this->statusCode, |
147
|
|
|
'reasonPhrase' => $this->reasonPhrase, |
148
|
|
|
'protocolVersion' => $this->protocolVersion, |
149
|
|
|
'headers' => $this->headers, |
150
|
|
|
'body' => $this->body, |
151
|
|
|
]; |
152
|
|
|
|
153
|
|
|
$arguments = array_values(array_replace($defaults, $parameters, ['__previous' => $this])); |
154
|
|
|
|
155
|
|
|
return new static(...$arguments); |
|
|
|
|
156
|
|
|
} |
157
|
|
|
} |
158
|
|
|
|
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.