Complex classes like Request 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 Request, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
7 | class Request |
||
8 | { |
||
9 | /** |
||
10 | * Application Object |
||
11 | * |
||
12 | * @var \System\Application |
||
13 | */ |
||
14 | private $app; |
||
15 | |||
16 | /** |
||
17 | * Url |
||
18 | * |
||
19 | * @var string |
||
20 | */ |
||
21 | private $url; |
||
22 | |||
23 | /** |
||
24 | * Base Url |
||
25 | * |
||
26 | * @var string |
||
27 | */ |
||
28 | private $baseUrl; |
||
29 | |||
30 | /** |
||
31 | * Uploaded files container |
||
32 | * |
||
33 | * @var array |
||
34 | */ |
||
35 | private $files = []; |
||
36 | |||
37 | /** |
||
38 | * Host |
||
39 | * |
||
40 | * @var string |
||
41 | */ |
||
42 | private $host; |
||
43 | |||
44 | /** |
||
45 | * Constructor |
||
46 | * |
||
47 | * @param \System\Application $app |
||
48 | */ |
||
49 | public function __construct(Application $app) |
||
53 | |||
54 | /** |
||
55 | * Prepare url |
||
56 | * |
||
57 | * @return void |
||
58 | */ |
||
59 | public function prepareUrl() |
||
77 | |||
78 | /** |
||
79 | * Clean url |
||
80 | * |
||
81 | * @param string $script |
||
82 | * @param string $requestUri |
||
83 | * @return string |
||
84 | */ |
||
85 | private function cleanUrl($script, $requestUri) |
||
99 | |||
100 | /** |
||
101 | * Check if the website is secure |
||
102 | * |
||
103 | * @return bool |
||
104 | */ |
||
105 | private function isSecure() |
||
113 | |||
114 | /** |
||
115 | * Check if HTTPS is 'on' |
||
116 | * |
||
117 | * @return bool |
||
118 | */ |
||
119 | private function checkHttp() |
||
127 | |||
128 | /** |
||
129 | * Check if HTTP_X_FORWARDED_PROTO is not empty or 'https' |
||
130 | * |
||
131 | * @return bool |
||
132 | */ |
||
133 | private function checkHttpXforwardedProto() |
||
141 | |||
142 | /** |
||
143 | * Check if HTTP_X_FORWARDED_SSL is 'on' |
||
144 | * |
||
145 | * @return bool |
||
146 | */ |
||
147 | private function checkHttpXforwardedSsl() |
||
155 | |||
156 | /** |
||
157 | * Get value from spcefic request type |
||
158 | * |
||
159 | * @param array $requestType |
||
160 | * @param string $key |
||
161 | * @return mixed |
||
162 | */ |
||
163 | private function getValueOfRequest($requestType, $key) |
||
175 | |||
176 | /** |
||
177 | * Get value from $_GET by the given key |
||
178 | * |
||
179 | * @param string $key |
||
180 | * @return mixed |
||
181 | */ |
||
182 | public function get($key) |
||
186 | |||
187 | /** |
||
188 | * Get value from $_POST by the given key |
||
189 | * |
||
190 | * @param string $key |
||
191 | * @return mixed |
||
192 | */ |
||
193 | public function post($key) |
||
197 | |||
198 | /** |
||
199 | * Set value To $_POST For the given key |
||
200 | * |
||
201 | * @param string $key |
||
202 | * @param mixed $value |
||
203 | * @return mixed |
||
204 | */ |
||
205 | public function setPost($key, $value) |
||
209 | |||
210 | /** |
||
211 | * Get $_POST |
||
212 | * |
||
213 | * @return array |
||
214 | */ |
||
215 | public function posts() |
||
219 | |||
220 | /** |
||
221 | * Get $_GET |
||
222 | * |
||
223 | * @return array |
||
224 | */ |
||
225 | public function gets() |
||
229 | |||
230 | /** |
||
231 | * Get $_FILES |
||
232 | * |
||
233 | * @return array |
||
234 | */ |
||
235 | public function files() |
||
239 | |||
240 | /** |
||
241 | * Get the uploaded file object for the given input |
||
242 | * |
||
243 | * @param string $input |
||
244 | * @return array |
||
245 | */ |
||
246 | public function file($input) |
||
258 | |||
259 | /** |
||
260 | * Get value from $_SERVER by the given key |
||
261 | * |
||
262 | * @param string $key |
||
263 | * @return mixed |
||
264 | */ |
||
265 | public function server($key) |
||
269 | |||
270 | /** |
||
271 | * Get current request method |
||
272 | * |
||
273 | * @return string |
||
274 | */ |
||
275 | public function method() |
||
279 | |||
280 | /** |
||
281 | * Get the referer link |
||
282 | * |
||
283 | * @return string |
||
284 | */ |
||
285 | public function referer() |
||
289 | |||
290 | /** |
||
291 | * Get full url of the script |
||
292 | * |
||
293 | * @return string |
||
294 | */ |
||
295 | public function baseUrl() |
||
299 | |||
300 | /** |
||
301 | * Get only relative url (clean url) |
||
302 | * |
||
303 | * @return string |
||
304 | */ |
||
305 | public function url() |
||
309 | |||
310 | /** |
||
311 | * Get only host |
||
312 | * |
||
313 | * @return string |
||
314 | */ |
||
315 | public function host() |
||
319 | |||
320 | /** |
||
321 | * Check if the request to the admin panel |
||
322 | * |
||
323 | * @return bool |
||
324 | */ |
||
325 | public function isRequestToAdminManagement() |
||
335 | |||
336 | /** |
||
337 | * Check the request method |
||
338 | * |
||
339 | * @return bool |
||
340 | */ |
||
341 | public function isMatchingRequestMethod($methods = ['GET']) |
||
359 | |||
360 | /** |
||
361 | * Check if the request can be Continued |
||
362 | * @property object $load |
||
363 | * @return bool |
||
364 | */ |
||
365 | public function canRequestContinue($middlewares) |
||
381 | } |
||
382 |
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.
Let’s take a look at an example:
Our function
my_function
expects aPost
object, and outputs the author of the post. The base classPost
returns a simple string and outputting a simple string will work just fine. However, the child classBlogPost
which is a sub-type ofPost
instead decided to return anobject
, and is therefore violating the SOLID principles. If aBlogPost
were passed tomy_function
, PHP would not complain, but ultimately fail when executing thestrtoupper
call in its body.