Complex classes like Uri 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 Uri, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
18 | final class Uri implements UriInterface |
||
19 | { |
||
20 | private const SCHEMES = ['http' => 80, 'https' => 443]; |
||
21 | |||
22 | private const CHAR_UNRESERVED = 'a-zA-Z0-9_\-\.~'; |
||
23 | |||
24 | private const CHAR_SUB_DELIMS = '!\$&\'\(\)\*\+,;='; |
||
25 | |||
26 | /** @var string Uri scheme. */ |
||
27 | private $scheme = ''; |
||
28 | |||
29 | /** @var string Uri user info. */ |
||
30 | private $userInfo = ''; |
||
31 | |||
32 | /** @var string Uri host. */ |
||
33 | private $host = ''; |
||
34 | |||
35 | /** @var int|null Uri port. */ |
||
36 | private $port; |
||
37 | |||
38 | /** @var string Uri path. */ |
||
39 | private $path = ''; |
||
40 | |||
41 | /** @var string Uri query string. */ |
||
42 | private $query = ''; |
||
43 | |||
44 | /** @var string Uri fragment. */ |
||
45 | private $fragment = ''; |
||
46 | |||
47 | 145 | public function __construct(string $uri = '') |
|
48 | { |
||
49 | 145 | if ('' !== $uri) { |
|
50 | 125 | if (false === $parts = \parse_url($uri)) { |
|
51 | 4 | throw new \InvalidArgumentException("Unable to parse URI: $uri"); |
|
52 | } |
||
53 | |||
54 | 121 | $this->applyParts($parts); |
|
55 | } |
||
56 | 141 | } |
|
57 | |||
58 | 65 | public function __toString(): string |
|
62 | |||
63 | 8 | public function getScheme(): string |
|
67 | |||
68 | 71 | public function getAuthority(): string |
|
85 | |||
86 | 7 | public function getUserInfo(): string |
|
90 | |||
91 | 86 | public function getHost(): string |
|
95 | |||
96 | 41 | public function getPort(): ?int |
|
100 | |||
101 | 23 | public function getPath(): string |
|
105 | |||
106 | 19 | public function getQuery(): string |
|
110 | |||
111 | 17 | public function getFragment(): string |
|
115 | |||
116 | 12 | public function withScheme($scheme): self |
|
132 | 5 | ||
133 | 5 | public function withUserInfo($user, $password = null): self |
|
149 | |||
150 | public function withHost($host): self |
||
165 | 6 | ||
166 | public function withPort($port): self |
||
177 | 8 | ||
178 | public function withPath($path): self |
||
189 | 5 | ||
190 | public function withQuery($query): self |
||
201 | 5 | ||
202 | public function withFragment($fragment): self |
||
213 | 121 | ||
214 | 121 | /** |
|
215 | 121 | * Apply parse_url parts to a URI. |
|
216 | 121 | * |
|
217 | 121 | * @param array $parts Array of parse_url parts to apply |
|
218 | 121 | */ |
|
219 | 121 | private function applyParts(array $parts): void |
|
232 | 40 | ||
233 | /** |
||
234 | * Create a URI string from its various parts. |
||
235 | 65 | */ |
|
236 | 40 | private static function createUriString(string $scheme, string $authority, string $path, string $query, string $fragment): string |
|
274 | |||
275 | 59 | /** |
|
276 | * Is a given port non-standard for the current scheme? |
||
277 | 59 | */ |
|
278 | 5 | private static function isNonStandardPort(string $scheme, int $port): bool |
|
282 | |||
283 | private function filterPort($port): ?int |
||
296 | 6 | ||
297 | private function filterPath($path): string |
||
305 | |||
306 | private function filterQueryAndFragment($str): string |
||
314 | |||
315 | private static function rawurlencodeMatchZero(array $match): string |
||
319 | } |
||
320 |