Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like Http 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 Http, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
14 | class Http |
||
15 | { |
||
16 | |||
17 | protected $request; |
||
18 | |||
19 | /** |
||
20 | * @var string |
||
21 | */ |
||
22 | protected $pathInfo; |
||
23 | |||
24 | /** |
||
25 | * @var string |
||
26 | */ |
||
27 | protected $requestUri; |
||
28 | /** |
||
29 | * @var string |
||
30 | */ |
||
31 | protected $baseUrl; |
||
32 | |||
33 | /** |
||
34 | * Normalizes a query string. |
||
35 | * |
||
36 | * It builds a normalized query string, where keys/value pairs are alphabetized, |
||
37 | * have consistent escaping and unneeded delimiters are removed. |
||
38 | * |
||
39 | * @param string $qs Query string |
||
40 | * |
||
41 | * @return string A normalized query string for the Request |
||
42 | */ |
||
43 | 1 | public static function normalizeQueryString($qs) |
|
73 | |||
74 | /** |
||
75 | * Generates a normalized URI (URL) for the Request. |
||
76 | * |
||
77 | * @return string A normalized URI (URL) for the Request |
||
78 | * |
||
79 | * @see getQueryString() |
||
80 | */ |
||
81 | 1 | public function getUri() |
|
88 | |||
89 | /** |
||
90 | * Generates the normalized query string for the Request. |
||
91 | * |
||
92 | * It builds a normalized query string, where keys/value pairs are alphabetized |
||
93 | * and have consistent escaping. |
||
94 | * |
||
95 | * @return string|null A normalized query string for the Request |
||
96 | */ |
||
97 | 1 | public function getQueryString() |
|
103 | |||
104 | /** |
||
105 | * @return mixed |
||
106 | */ |
||
107 | 8 | public function getRequest() |
|
111 | |||
112 | /* |
||
113 | * The following methods are derived from code of the Zend Framework (1.10dev - 2010-01-24) |
||
114 | * |
||
115 | * Code subject to the new BSD license (http://framework.zend.com/license/new-bsd). |
||
116 | * |
||
117 | * Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
||
118 | */ |
||
119 | |||
120 | /** |
||
121 | * @param mixed $request |
||
122 | */ |
||
123 | 8 | public function setRequest($request) |
|
127 | |||
128 | /** |
||
129 | * Gets the scheme and HTTP host. |
||
130 | * |
||
131 | * If the URL was called with basic authentication, the user |
||
132 | * and the password are not added to the generated string. |
||
133 | * |
||
134 | * @return string The scheme and HTTP host |
||
135 | */ |
||
136 | 8 | public function getSchemeAndHttpHost() |
|
140 | |||
141 | /** |
||
142 | * Gets the request's scheme. |
||
143 | * |
||
144 | * @return string |
||
145 | */ |
||
146 | 8 | public function getScheme() |
|
150 | |||
151 | /** |
||
152 | * @return bool |
||
153 | */ |
||
154 | 8 | public function isSecure() |
|
160 | |||
161 | /** |
||
162 | * Returns the HTTP host being requested. |
||
163 | * |
||
164 | * The port name will be appended to the host if it's non-standard. |
||
165 | * |
||
166 | * @return string |
||
167 | */ |
||
168 | 8 | public function getHttpHost() |
|
178 | |||
179 | /** |
||
180 | * @return mixed |
||
181 | */ |
||
182 | 8 | public function getPort() |
|
186 | |||
187 | /** |
||
188 | * Returns the host name. |
||
189 | * |
||
190 | * This method can read the client host name from the "X-Forwarded-Host" header |
||
191 | * when trusted proxies were set via "setTrustedProxies()". |
||
192 | * |
||
193 | * The "X-Forwarded-Host" header must contain the client host name. |
||
194 | * |
||
195 | * If your reverse proxy uses a different header name than "X-Forwarded-Host", |
||
196 | * configure it via "setTrustedHeaderName()" with the "client-host" key. |
||
197 | * |
||
198 | * @return string |
||
199 | * |
||
200 | * @throws \UnexpectedValueException when the host name is invalid |
||
201 | */ |
||
202 | 8 | public function getHost() |
|
223 | |||
224 | /** |
||
225 | * Returns the root URL from which this request is executed. |
||
226 | * |
||
227 | * The base URL never ends with a /. |
||
228 | * |
||
229 | * This is similar to getBasePath(), except that it also includes the |
||
230 | * script filename (e.g. index.php) if one exists. |
||
231 | * |
||
232 | * @return string The raw URL (i.e. not urldecoded) |
||
233 | */ |
||
234 | 8 | public function getBaseUrl() |
|
241 | |||
242 | /** |
||
243 | * Returns the requested URI (path and query string). |
||
244 | * |
||
245 | * @return string The raw URI (i.e. not URI decoded) |
||
246 | */ |
||
247 | 8 | public function getRequestUri() |
|
254 | |||
255 | /** |
||
256 | * @return bool|mixed |
||
257 | */ |
||
258 | View Code Duplication | public function getSubdomain() |
|
270 | |||
271 | /** |
||
272 | * @return mixed |
||
273 | */ |
||
274 | public function getServerName() |
||
278 | |||
279 | /** |
||
280 | * @return bool|mixed|string |
||
281 | */ |
||
282 | View Code Duplication | public function getRootDomain() |
|
296 | |||
297 | /* |
||
298 | * Returns the prefix as encoded in the string when the string starts with |
||
299 | * the given prefix, false otherwise. |
||
300 | * |
||
301 | * @param string $string The urlencoded string |
||
302 | * @param string $prefix The prefix not encoded |
||
303 | * |
||
304 | * @return string|false The prefix as it is encoded in $string, or false |
||
305 | */ |
||
306 | |||
307 | /** |
||
308 | * @return bool |
||
309 | */ |
||
310 | public function isConsole() |
||
321 | |||
322 | /** |
||
323 | * Prepares the base URL. |
||
324 | * |
||
325 | * @return string |
||
326 | */ |
||
327 | 8 | protected function prepareBaseUrl() |
|
381 | |||
382 | /** |
||
383 | * @return string |
||
384 | */ |
||
385 | 8 | protected function prepareRequestUri() |
|
423 | |||
424 | /** |
||
425 | * @param $string |
||
426 | * @param $prefix |
||
427 | * @return bool |
||
428 | */ |
||
429 | 7 | private function getUrlencodedPrefix($string, $prefix) |
|
441 | } |
||
442 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.