Complex classes like Url 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 Url, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 8 | class Url implements UriInterface |
||
| 9 | { |
||
| 10 | /** |
||
| 11 | * @var int[] |
||
| 12 | */ |
||
| 13 | private $schemes = [ |
||
| 14 | 'http' => 80, |
||
| 15 | 'https' => 443, |
||
| 16 | ]; |
||
| 17 | |||
| 18 | /** |
||
| 19 | * @var string|null url scheme |
||
| 20 | */ |
||
| 21 | private $scheme; |
||
| 22 | |||
| 23 | /** |
||
| 24 | * @var string|null url host |
||
| 25 | */ |
||
| 26 | private $host; |
||
| 27 | |||
| 28 | /** |
||
| 29 | * @var int|null url port |
||
| 30 | */ |
||
| 31 | private $port; |
||
| 32 | |||
| 33 | /** |
||
| 34 | * @var string|null url user |
||
| 35 | */ |
||
| 36 | private $user; |
||
| 37 | |||
| 38 | /** |
||
| 39 | * @var string|null url pass |
||
| 40 | */ |
||
| 41 | private $pass; |
||
| 42 | |||
| 43 | /** |
||
| 44 | * @var string|null url path |
||
| 45 | */ |
||
| 46 | private $path; |
||
| 47 | |||
| 48 | /** |
||
| 49 | * @var string|null url query string |
||
| 50 | */ |
||
| 51 | private $query; |
||
| 52 | |||
| 53 | /** |
||
| 54 | * @var string|null url fragment |
||
| 55 | */ |
||
| 56 | private $fragment; |
||
| 57 | |||
| 58 | /** |
||
| 59 | * 获取实例. |
||
| 60 | * |
||
| 61 | * @param null|UriInterface $url |
||
| 62 | * |
||
| 63 | * @return static |
||
| 64 | */ |
||
| 65 | 12 | public static function instance($url = null) |
|
| 69 | |||
| 70 | /** |
||
| 71 | * Url constructor. |
||
| 72 | * |
||
| 73 | * @param null|string|string[]|UriInterface $url |
||
| 74 | */ |
||
| 75 | 12 | final protected function __construct($url = null) |
|
| 85 | |||
| 86 | /** |
||
| 87 | * 解析 Psr 标准库的url. |
||
| 88 | * |
||
| 89 | * @param UriInterface $url |
||
| 90 | * |
||
| 91 | * @return $this |
||
| 92 | */ |
||
| 93 | 4 | private function parsePsrUrl(UriInterface $url) |
|
| 109 | |||
| 110 | /** |
||
| 111 | * 解析字符串url. |
||
| 112 | * |
||
| 113 | * @param string $url |
||
| 114 | * |
||
| 115 | * @return $this |
||
| 116 | */ |
||
| 117 | 9 | private function parseStringUrl($url) |
|
| 129 | |||
| 130 | /** |
||
| 131 | * 解析数组url. |
||
| 132 | * |
||
| 133 | * @param string[]|int[] $parts |
||
| 134 | * |
||
| 135 | * @return $this |
||
| 136 | */ |
||
| 137 | 10 | private function parseArrayUrl(array $parts) |
|
| 150 | |||
| 151 | /** |
||
| 152 | * 填充 Psr 标准库的url. |
||
| 153 | * |
||
| 154 | * @param UriInterface $url |
||
| 155 | * |
||
| 156 | * @return UriInterface |
||
| 157 | */ |
||
| 158 | public function fillPsrUri(UriInterface $url) |
||
| 168 | |||
| 169 | /** |
||
| 170 | * {@inheritdoc} |
||
| 171 | */ |
||
| 172 | 10 | public function getScheme() |
|
| 176 | |||
| 177 | /** |
||
| 178 | * {@inheritdoc} |
||
| 179 | */ |
||
| 180 | 8 | public function getAuthority() |
|
| 199 | |||
| 200 | /** |
||
| 201 | * {@inheritdoc} |
||
| 202 | */ |
||
| 203 | 8 | public function getUserInfo() |
|
| 217 | |||
| 218 | /** |
||
| 219 | * 获取 url user. |
||
| 220 | * |
||
| 221 | * @return string |
||
| 222 | */ |
||
| 223 | 8 | public function getUser() |
|
| 227 | |||
| 228 | /** |
||
| 229 | * 获取 url pass. |
||
| 230 | * |
||
| 231 | * @return string |
||
| 232 | */ |
||
| 233 | 2 | public function getPass() |
|
| 237 | |||
| 238 | /** |
||
| 239 | * {@inheritdoc} |
||
| 240 | */ |
||
| 241 | 8 | public function getHost() |
|
| 245 | |||
| 246 | /** |
||
| 247 | * {@inheritdoc} |
||
| 248 | */ |
||
| 249 | 8 | public function getPort() |
|
| 259 | |||
| 260 | /** |
||
| 261 | * {@inheritdoc} |
||
| 262 | */ |
||
| 263 | 8 | public function getPath() |
|
| 271 | |||
| 272 | /** |
||
| 273 | * {@inheritdoc} |
||
| 274 | */ |
||
| 275 | 8 | public function getQuery() |
|
| 279 | |||
| 280 | /** |
||
| 281 | * 获取query数组. |
||
| 282 | * |
||
| 283 | * @return array |
||
| 284 | */ |
||
| 285 | 2 | public function getQueryArray() |
|
| 296 | |||
| 297 | /** |
||
| 298 | * 是否存在query的key. |
||
| 299 | * |
||
| 300 | * @param string $key |
||
| 301 | * |
||
| 302 | * @return bool |
||
| 303 | */ |
||
| 304 | public function hasQueryKey($key) |
||
| 310 | |||
| 311 | /** |
||
| 312 | * 是否存在query的key. |
||
| 313 | * |
||
| 314 | * @param string $key |
||
| 315 | * @param mixed $default |
||
| 316 | * |
||
| 317 | * @return array|string |
||
| 318 | */ |
||
| 319 | public function getQueryValue($key, $default = null) |
||
| 325 | |||
| 326 | /** |
||
| 327 | * {@inheritdoc} |
||
| 328 | */ |
||
| 329 | 8 | public function getFragment() |
|
| 333 | |||
| 334 | /** |
||
| 335 | * Return the string representation as a URI reference. |
||
| 336 | * |
||
| 337 | * @return string |
||
| 338 | */ |
||
| 339 | 8 | public function toString() |
|
| 370 | |||
| 371 | /** |
||
| 372 | * {@inheritdoc} |
||
| 373 | */ |
||
| 374 | public function withScheme($scheme) |
||
| 381 | |||
| 382 | /** |
||
| 383 | * {@inheritdoc} |
||
| 384 | */ |
||
| 385 | public function withUserInfo($user, $password = null) |
||
| 393 | |||
| 394 | /** |
||
| 395 | * {@inheritdoc} |
||
| 396 | */ |
||
| 397 | public function withHost($host) |
||
| 404 | |||
| 405 | /** |
||
| 406 | * {@inheritdoc} |
||
| 407 | */ |
||
| 408 | public function withPort($port) |
||
| 415 | |||
| 416 | /** |
||
| 417 | * {@inheritdoc} |
||
| 418 | */ |
||
| 419 | public function withPath($path) |
||
| 426 | |||
| 427 | /** |
||
| 428 | * {@inheritdoc} |
||
| 429 | */ |
||
| 430 | public function withQuery($query) |
||
| 437 | |||
| 438 | /** |
||
| 439 | * Return an instance with the specified query array. |
||
| 440 | * |
||
| 441 | * @param array $queryArray |
||
| 442 | * |
||
| 443 | * @return static |
||
| 444 | */ |
||
| 445 | public function withQueryArray(array $queryArray) |
||
| 449 | |||
| 450 | /** |
||
| 451 | * Create a new URI with a specific query string value removed. |
||
| 452 | * |
||
| 453 | * @param string|int $key |
||
| 454 | * |
||
| 455 | * @return static |
||
| 456 | */ |
||
| 457 | public function withoutQueryValue($key) |
||
| 467 | |||
| 468 | /** |
||
| 469 | * Create a new URI with a specific query string value. |
||
| 470 | * |
||
| 471 | * @param string $key |
||
| 472 | * @param string|int $value |
||
| 473 | * |
||
| 474 | * @return static |
||
| 475 | */ |
||
| 476 | public function withQueryValue($key, $value) |
||
| 483 | |||
| 484 | /** |
||
| 485 | * {@inheritdoc} |
||
| 486 | */ |
||
| 487 | public function withFragment($fragment) |
||
| 494 | |||
| 495 | /** |
||
| 496 | * {@inheritdoc} |
||
| 497 | */ |
||
| 498 | 2 | public function __toString() |
|
| 502 | |||
| 503 | /** |
||
| 504 | * Is a given port non-standard for the current scheme? |
||
| 505 | * |
||
| 506 | * @return bool |
||
| 507 | */ |
||
| 508 | 8 | private function isNonStandardPort() |
|
| 521 | |||
| 522 | /** |
||
| 523 | * is url string. |
||
| 524 | * |
||
| 525 | * @param mixed $url |
||
| 526 | * |
||
| 527 | * @return bool |
||
| 528 | */ |
||
| 529 | 9 | public static function isUrlString($url) |
|
| 533 | } |
||
| 534 |
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
$accountIdthat can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theidproperty of an instance of theAccountclass. 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.