Complex classes like Response often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Response, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 34 | class Response |
||
| 35 | { |
||
| 36 | use Options; |
||
| 37 | |||
| 38 | /** |
||
| 39 | * @var string HTTP protocol version |
||
| 40 | */ |
||
| 41 | protected $protocol = '1.1'; |
||
| 42 | |||
| 43 | /** |
||
| 44 | * @var integer response code equal to HTTP status codes |
||
| 45 | */ |
||
| 46 | protected $code = 200; |
||
| 47 | |||
| 48 | /** |
||
| 49 | * @var string|null HTTP Phrase |
||
| 50 | */ |
||
| 51 | protected $phrase; |
||
| 52 | |||
| 53 | /** |
||
| 54 | * @var array list of headers |
||
| 55 | */ |
||
| 56 | protected $headers = array(); |
||
| 57 | |||
| 58 | /** |
||
| 59 | * @var array list of cookies |
||
| 60 | */ |
||
| 61 | protected $cookies = array(); |
||
| 62 | |||
| 63 | /** |
||
| 64 | * @var mixed result can be Controller|Layout |
||
| 65 | */ |
||
| 66 | protected $body; |
||
| 67 | |||
| 68 | /** |
||
| 69 | * @var string CLI|HTML|JSON |
||
| 70 | */ |
||
| 71 | protected $type = 'HTML'; |
||
| 72 | |||
| 73 | /** |
||
| 74 | * send |
||
| 75 | * |
||
| 76 | * @throws NotAcceptableException |
||
| 77 | */ |
||
| 78 | public function send() |
||
| 132 | |||
| 133 | /** |
||
| 134 | * Set Response Type, one of JSON, HTML or CLI |
||
| 135 | * |
||
| 136 | * @param $type |
||
| 137 | */ |
||
| 138 | public function switchType($type) |
||
| 153 | |||
| 154 | /** |
||
| 155 | * Gets the HTTP protocol version as a string |
||
| 156 | * |
||
| 157 | * The string MUST contain only the HTTP version number (e.g., "1.1", "1.0"). |
||
| 158 | * |
||
| 159 | * @return string HTTP protocol version. |
||
| 160 | */ |
||
| 161 | 1 | public function getProtocolVersion() |
|
| 165 | |||
| 166 | /** |
||
| 167 | * Gets the response Status-Code |
||
| 168 | * |
||
| 169 | * The Status-Code is a 3-digit integer result code of the server's attempt |
||
| 170 | * to understand and satisfy the request. |
||
| 171 | * |
||
| 172 | * @return integer status code. |
||
| 173 | */ |
||
| 174 | public function getStatusCode() |
||
| 178 | |||
| 179 | /** |
||
| 180 | * Sets the status code of this response |
||
| 181 | * |
||
| 182 | * @param integer $code the 3-digit integer result code to set. |
||
| 183 | * @return void |
||
| 184 | */ |
||
| 185 | 1 | public function setStatusCode($code) |
|
| 189 | |||
| 190 | /** |
||
| 191 | * Gets the response Reason-Phrase, a short textual description of the Status-Code |
||
| 192 | * |
||
| 193 | * Because a Reason-Phrase is not a required element in response |
||
| 194 | * Status-Line, the Reason-Phrase value MAY be null. Implementations MAY |
||
| 195 | * choose to return the default RFC 2616 recommended reason phrase for the |
||
| 196 | * response's Status-Code. |
||
| 197 | * |
||
| 198 | * @return string|null reason phrase, or null if unknown. |
||
| 199 | */ |
||
| 200 | 2 | public function getReasonPhrase() |
|
| 204 | |||
| 205 | /** |
||
| 206 | * Sets the Reason-Phrase of the response |
||
| 207 | * |
||
| 208 | * If no Reason-Phrase is specified, implementations MAY choose to default |
||
| 209 | * to the RFC 2616 recommended reason phrase for the response's Status-Code. |
||
| 210 | * |
||
| 211 | * @param string $phrase the Reason-Phrase to set. |
||
| 212 | */ |
||
| 213 | 1 | public function setReasonPhrase($phrase) |
|
| 217 | |||
| 218 | /** |
||
| 219 | * Retrieve a header by the given case-insensitive name as a string |
||
| 220 | * |
||
| 221 | * This method returns all of the header values of the given |
||
| 222 | * case-insensitive header name as a string concatenated together using |
||
| 223 | * a comma. |
||
| 224 | * |
||
| 225 | * @param string $header case-insensitive header name. |
||
| 226 | * @return string |
||
| 227 | */ |
||
| 228 | 2 | public function getHeader($header) |
|
| 236 | |||
| 237 | /** |
||
| 238 | * Retrieves a header by the given case-insensitive name as an array of strings |
||
| 239 | * |
||
| 240 | * @param string $header Case-insensitive header name. |
||
| 241 | * @return string[] |
||
| 242 | */ |
||
| 243 | 1 | public function getHeaderAsArray($header) |
|
| 251 | |||
| 252 | /** |
||
| 253 | * Checks if a header exists by the given case-insensitive name |
||
| 254 | * |
||
| 255 | * @param string $header case-insensitive header name. |
||
| 256 | * @return bool returns true if any header names match the given header |
||
| 257 | * name using a case-insensitive string comparison. Returns false if |
||
| 258 | * no matching header name is found in the message. |
||
| 259 | */ |
||
| 260 | 1 | public function hasHeader($header) |
|
| 264 | |||
| 265 | /** |
||
| 266 | * Sets a header, replacing any existing values of any headers with the |
||
| 267 | * same case-insensitive name |
||
| 268 | * |
||
| 269 | * The header name is case-insensitive. The header values MUST be a string |
||
| 270 | * or an array of strings. |
||
| 271 | * |
||
| 272 | * @param string $header header name |
||
| 273 | * @param string|string[] $value header value(s) |
||
| 274 | * @return void |
||
| 275 | */ |
||
| 276 | 1 | public function setHeader($header, $value) |
|
| 280 | |||
| 281 | /** |
||
| 282 | * Appends a header value for the specified header |
||
| 283 | * |
||
| 284 | * Existing values for the specified header will be maintained. The new |
||
| 285 | * value will be appended to the existing list. |
||
| 286 | * |
||
| 287 | * @param string $header header name to add |
||
| 288 | * @param string $value value of the header |
||
| 289 | * @return void |
||
| 290 | */ |
||
| 291 | 1 | public function addHeader($header, $value) |
|
| 299 | |||
| 300 | /** |
||
| 301 | * Remove a specific header by case-insensitive name. |
||
| 302 | * |
||
| 303 | * @param string $header HTTP header to remove |
||
| 304 | * @return void |
||
| 305 | */ |
||
| 306 | 1 | public function removeHeader($header) |
|
| 310 | |||
| 311 | /** |
||
| 312 | * Gets all message headers |
||
| 313 | * |
||
| 314 | * The keys represent the header name as it will be sent over the wire, and |
||
| 315 | * each value is an array of strings associated with the header. |
||
| 316 | * |
||
| 317 | * // Represent the headers as a string |
||
| 318 | * foreach ($message->getHeaders() as $name => $values) { |
||
| 319 | * echo $name . ": " . implode(", ", $values); |
||
| 320 | * } |
||
| 321 | * |
||
| 322 | * @return array returns an associative array of the message's headers. |
||
| 323 | */ |
||
| 324 | 1 | public function getHeaders() |
|
| 328 | |||
| 329 | /** |
||
| 330 | * Sets headers, replacing any headers that have already been set on the message |
||
| 331 | * |
||
| 332 | * The array keys MUST be a string. The array values must be either a |
||
| 333 | * string or an array of strings. |
||
| 334 | * |
||
| 335 | * @param array $headers Headers to set. |
||
| 336 | * @return void |
||
| 337 | */ |
||
| 338 | 1 | public function setHeaders(array $headers) |
|
| 342 | |||
| 343 | /** |
||
| 344 | * Merges in an associative array of headers. |
||
| 345 | * |
||
| 346 | * Each array key MUST be a string representing the case-insensitive name |
||
| 347 | * of a header. Each value MUST be either a string or an array of strings. |
||
| 348 | * For each value, the value is appended to any existing header of the same |
||
| 349 | * name, or, if a header does not already exist by the given name, then the |
||
| 350 | * header is added. |
||
| 351 | * |
||
| 352 | * @param array $headers Associative array of headers to add to the message |
||
| 353 | * @return void |
||
| 354 | */ |
||
| 355 | 1 | public function addHeaders(array $headers) |
|
| 359 | |||
| 360 | /** |
||
| 361 | * Remove all headers |
||
| 362 | * |
||
| 363 | * @return void |
||
| 364 | */ |
||
| 365 | 2 | public function removeHeaders() |
|
| 369 | |||
| 370 | /** |
||
| 371 | * Set response body |
||
| 372 | * |
||
| 373 | * @param mixed $body |
||
| 374 | * @return void |
||
| 375 | */ |
||
| 376 | 2 | public function setBody($body) |
|
| 380 | |||
| 381 | /** |
||
| 382 | * Get response body |
||
| 383 | * |
||
| 384 | * @return Controller|Layout |
||
| 385 | */ |
||
| 386 | public function getBody() |
||
| 390 | |||
| 391 | /** |
||
| 392 | * Clear response body |
||
| 393 | * |
||
| 394 | * @return void |
||
| 395 | */ |
||
| 396 | 1 | public function clearBody() |
|
| 400 | |||
| 401 | /** |
||
| 402 | * Set Cookie |
||
| 403 | * |
||
| 404 | * @param string $name |
||
| 405 | * @param string $value |
||
| 406 | * @param int|string|\DateTime $expire |
||
| 407 | * @param string $path |
||
| 408 | * @param string $domain |
||
| 409 | * @param bool $secure |
||
| 410 | * @param bool $httpOnly |
||
| 411 | * @return void |
||
| 412 | */ |
||
| 413 | 5 | public function setCookie( |
|
| 451 | |||
| 452 | /** |
||
| 453 | * Get Cookie by name |
||
| 454 | * |
||
| 455 | * @param string $name |
||
| 456 | * @return array|null |
||
| 457 | */ |
||
| 458 | 2 | public function getCookie($name) |
|
| 462 | |||
| 463 | /** |
||
| 464 | * Process Cookies to Header |
||
| 465 | * |
||
| 466 | * Set-Cookie: <name>=<value>[; <name>=<value>]... |
||
| 467 | * [; expires=<date>][; domain=<domain_name>] |
||
| 468 | * [; path=<some_path>][; secure][; httponly] |
||
| 469 | * |
||
| 470 | * @return void |
||
| 471 | */ |
||
| 472 | protected function sendCookies() |
||
| 478 | } |
||
| 479 |
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignorePhpDoc annotation to the duplicate definition and it will be ignored.