Complex classes like Curl 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 Curl, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
10 | class Curl { |
||
11 | |||
12 | const VERSION = '7.2.0'; |
||
13 | const DEFAULT_TIMEOUT = 20; |
||
14 | |||
15 | public $retryCount = 3; |
||
16 | |||
17 | public $curl; |
||
18 | public $id = null; |
||
19 | |||
20 | public $error = false; |
||
21 | public $errorCode = 0; |
||
22 | public $errorMessage = null; |
||
23 | |||
24 | public $curlError = false; |
||
25 | public $curlErrorCode = 0; |
||
26 | public $curlErrorMessage = null; |
||
27 | |||
28 | public $httpError = false; |
||
29 | public $httpStatusCode = 0; |
||
30 | public $httpErrorMessage = null; |
||
31 | |||
32 | public $baseUrl = null; |
||
33 | public $url = null; |
||
34 | public $requestHeaders = null; |
||
35 | public $responseHeaders = null; |
||
36 | public $rawResponseHeaders = ''; |
||
37 | public $responseCookies = array(); |
||
38 | public $response = null; |
||
39 | public $rawResponse = null; |
||
40 | |||
41 | public $beforeSendFunction = null; |
||
42 | public $downloadCompleteFunction = null; |
||
43 | public $successFunction = null; |
||
44 | public $errorFunction = null; |
||
45 | public $completeFunction = null; |
||
46 | public $fileHandle = null; |
||
47 | |||
48 | private $cookies = array(); |
||
49 | private $headers = array(); |
||
50 | private $options = array(); |
||
51 | |||
52 | private $jsonDecoder = null; |
||
53 | private $jsonPattern = '/^(?:application|text)\/(?:[a-z]+(?:[\.-][0-9a-z]+){0,}[\+\.]|x-)?json(?:-[a-z]+)?/i'; |
||
54 | private $xmlDecoder = null; |
||
55 | private $xmlPattern = '~^(?:text/|application/(?:atom\+|rss\+)?)xml~i'; |
||
56 | private $defaultDecoder = null; |
||
57 | |||
58 | public static $RFC2616 = array( |
||
59 | // RFC2616: "any CHAR except CTLs or separators". |
||
60 | // CHAR = <any US-ASCII character (octets 0 - 127)> |
||
61 | // CTL = <any US-ASCII control character |
||
62 | // (octets 0 - 31) and DEL (127)> |
||
|
|||
63 | // separators = "(" | ")" | "<" | ">" | "@" |
||
64 | // | "," | ";" | ":" | "\" | <"> |
||
65 | // | "/" | "[" | "]" | "?" | "=" |
||
66 | // | "{" | "}" | SP | HT |
||
67 | // SP = <US-ASCII SP, space (32)> |
||
68 | // HT = <US-ASCII HT, horizontal-tab (9)> |
||
69 | // <"> = <US-ASCII double-quote mark (34)> |
||
70 | '!', '#', '$', '%', '&', "'", '*', '+', '-', '.', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', |
||
71 | 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', |
||
72 | 'Y', 'Z', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', |
||
73 | 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '|', '~', |
||
74 | ); |
||
75 | public static $RFC6265 = array( |
||
76 | // RFC6265: "US-ASCII characters excluding CTLs, whitespace DQUOTE, comma, semicolon, and backslash". |
||
77 | // %x21 |
||
78 | '!', |
||
79 | // %x23-2B |
||
80 | '#', '$', '%', '&', "'", '(', ')', '*', '+', |
||
81 | // %x2D-3A |
||
82 | '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', |
||
83 | // %x3C-5B |
||
84 | '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', |
||
85 | 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', |
||
86 | // %x5D-7E |
||
87 | ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', |
||
88 | 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', |
||
89 | ); |
||
90 | |||
91 | private static $deferredProperties = array( |
||
92 | 'effectiveUrl', |
||
93 | 'rfc2616', |
||
94 | 'rfc6265', |
||
95 | 'totalTime', |
||
96 | ); |
||
97 | |||
98 | /** |
||
99 | * Construct |
||
100 | * |
||
101 | * @access public |
||
102 | * @param $base_url |
||
103 | * @throws \ErrorException |
||
104 | */ |
||
105 | 1 | public function __construct($base_url = null) |
|
123 | |||
124 | /** |
||
125 | * Before Send |
||
126 | * |
||
127 | * @access public |
||
128 | * @param $callback |
||
129 | */ |
||
130 | public function beforeSend($callback) |
||
134 | |||
135 | /** |
||
136 | * Build Post Data |
||
137 | * |
||
138 | * @access public |
||
139 | * @param $data |
||
140 | * |
||
141 | * @return array|string |
||
142 | */ |
||
143 | public function buildPostData($data) |
||
185 | |||
186 | /** |
||
187 | * Call |
||
188 | * |
||
189 | * @access public |
||
190 | */ |
||
191 | 3 | public function call() |
|
200 | |||
201 | /** |
||
202 | * Close |
||
203 | * |
||
204 | * @access public |
||
205 | */ |
||
206 | public function close() |
||
216 | |||
217 | /** |
||
218 | * Complete |
||
219 | * |
||
220 | * @access public |
||
221 | * @param $callback |
||
222 | */ |
||
223 | public function complete($callback) |
||
227 | |||
228 | /** |
||
229 | * Progress |
||
230 | * |
||
231 | * @access public |
||
232 | * @param $callback |
||
233 | */ |
||
234 | public function progress($callback) |
||
239 | |||
240 | /** |
||
241 | * Delete |
||
242 | * |
||
243 | * @access public |
||
244 | * @param $url |
||
245 | * @param $query_parameters |
||
246 | * @param $data |
||
247 | * |
||
248 | * @return string |
||
249 | */ |
||
250 | public function delete($url, $query_parameters = array(), $data = array()) |
||
263 | |||
264 | /** |
||
265 | * Download Complete |
||
266 | * |
||
267 | * @access private |
||
268 | * @param $fh |
||
269 | */ |
||
270 | private function downloadComplete($fh) |
||
298 | |||
299 | /** |
||
300 | * Download |
||
301 | * |
||
302 | * @access public |
||
303 | * @param $url |
||
304 | * @param $mixed_filename |
||
305 | * |
||
306 | * @return boolean |
||
307 | */ |
||
308 | public function download($url, $mixed_filename) |
||
343 | |||
344 | /** |
||
345 | * Error |
||
346 | * |
||
347 | * @access public |
||
348 | * @param $callback |
||
349 | */ |
||
350 | public function error($callback) |
||
354 | |||
355 | /** |
||
356 | * Exec |
||
357 | * |
||
358 | * @access public |
||
359 | * @param $ch |
||
360 | * |
||
361 | * @return mixed Returns the value provided by parseResponse. |
||
362 | */ |
||
363 | 3 | public function exec($ch = null) |
|
429 | |||
430 | /** |
||
431 | * Get |
||
432 | * |
||
433 | * @access public |
||
434 | * @param $url |
||
435 | * @param $data |
||
436 | * |
||
437 | * @return mixed Returns the value provided by exec. |
||
438 | */ |
||
439 | 3 | public function get($url, $data = array()) |
|
450 | |||
451 | /** |
||
452 | * Get Info |
||
453 | * |
||
454 | * @access public |
||
455 | * @param $opt |
||
456 | * |
||
457 | * @return mixed |
||
458 | */ |
||
459 | 3 | public function getInfo($opt = null) |
|
470 | |||
471 | /** |
||
472 | * Get Opt |
||
473 | * |
||
474 | * @access public |
||
475 | * @param $option |
||
476 | * |
||
477 | * @return mixed |
||
478 | */ |
||
479 | 3 | public function getOpt($option) |
|
483 | |||
484 | /** |
||
485 | * Head |
||
486 | * |
||
487 | * @access public |
||
488 | * @param $url |
||
489 | * @param $data |
||
490 | * |
||
491 | * @return string |
||
492 | */ |
||
493 | public function head($url, $data = array()) |
||
504 | |||
505 | /** |
||
506 | * Header Callback |
||
507 | * |
||
508 | * @access public |
||
509 | * @param $ch |
||
510 | * @param $header |
||
511 | * |
||
512 | * @return integer |
||
513 | */ |
||
514 | 3 | public function headerCallback($ch, $header) |
|
522 | |||
523 | /** |
||
524 | * Options |
||
525 | * |
||
526 | * @access public |
||
527 | * @param $url |
||
528 | * @param $data |
||
529 | * |
||
530 | * @return string |
||
531 | */ |
||
532 | public function options($url, $data = array()) |
||
543 | |||
544 | /** |
||
545 | * Patch |
||
546 | * |
||
547 | * @access public |
||
548 | * @param $url |
||
549 | * @param $data |
||
550 | * |
||
551 | * @return string |
||
552 | */ |
||
553 | public function patch($url, $data = array()) |
||
569 | |||
570 | /** |
||
571 | * Post |
||
572 | * |
||
573 | * @access public |
||
574 | * @param $url |
||
575 | * @param $data |
||
576 | * @param $follow_303_with_post |
||
577 | * If true, will cause 303 redirections to be followed using a POST request (default: false). |
||
578 | * Notes: |
||
579 | * - Redirections are only followed if the CURLOPT_FOLLOWLOCATION option is set to true. |
||
580 | * - According to the HTTP specs (see [1]), a 303 redirection should be followed using |
||
581 | * the GET method. 301 and 302 must not. |
||
582 | * - In order to force a 303 redirection to be performed using the same method, the |
||
583 | * underlying cURL object must be set in a special state (the CURLOPT_CURSTOMREQUEST |
||
584 | * option must be set to the method to use after the redirection). Due to a limitation |
||
585 | * of the cURL extension of PHP < 5.5.11 ([2], [3]) and of HHVM, it is not possible |
||
586 | * to reset this option. Using these PHP engines, it is therefore impossible to |
||
587 | * restore this behavior on an existing php-curl-class Curl object. |
||
588 | * |
||
589 | * @return string |
||
590 | * |
||
591 | * [1] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.2 |
||
592 | * [2] https://github.com/php/php-src/pull/531 |
||
593 | * [3] http://php.net/ChangeLog-5.php#5.5.11 |
||
594 | */ |
||
595 | public function post($url, $data = array(), $follow_303_with_post = false) |
||
627 | |||
628 | /** |
||
629 | * Put |
||
630 | * |
||
631 | * @access public |
||
632 | * @param $url |
||
633 | * @param $data |
||
634 | * |
||
635 | * @return string |
||
636 | */ |
||
637 | public function put($url, $data = array()) |
||
656 | |||
657 | /** |
||
658 | * Search |
||
659 | * |
||
660 | * @access public |
||
661 | * @param $url |
||
662 | * @param $data |
||
663 | * |
||
664 | * @return string |
||
665 | */ |
||
666 | public function search($url, $data = array()) |
||
685 | |||
686 | /** |
||
687 | * Set Basic Authentication |
||
688 | * |
||
689 | * @access public |
||
690 | * @param $username |
||
691 | * @param $password |
||
692 | */ |
||
693 | public function setBasicAuthentication($username, $password = '') |
||
698 | |||
699 | /** |
||
700 | * Set Digest Authentication |
||
701 | * |
||
702 | * @access public |
||
703 | * @param $username |
||
704 | * @param $password |
||
705 | */ |
||
706 | public function setDigestAuthentication($username, $password = '') |
||
711 | |||
712 | /** |
||
713 | * Set Cookie |
||
714 | * |
||
715 | * @access public |
||
716 | * @param $key |
||
717 | * @param $value |
||
718 | */ |
||
719 | public function setCookie($key, $value) |
||
744 | |||
745 | /** |
||
746 | * Set Cookies |
||
747 | * |
||
748 | * @access public |
||
749 | * @param $cookies |
||
750 | */ |
||
751 | public function setCookies($cookies) |
||
779 | |||
780 | /** |
||
781 | * Get Cookie |
||
782 | * |
||
783 | * @access public |
||
784 | * @param $key |
||
785 | * |
||
786 | * @return mixed |
||
787 | */ |
||
788 | public function getCookie($key) |
||
792 | |||
793 | /** |
||
794 | * Get Response Cookie |
||
795 | * |
||
796 | * @access public |
||
797 | * @param $key |
||
798 | * |
||
799 | * @return mixed |
||
800 | */ |
||
801 | public function getResponseCookie($key) |
||
805 | |||
806 | /** |
||
807 | * Set Max Filesize |
||
808 | * |
||
809 | * @access public |
||
810 | * @param $bytes |
||
811 | */ |
||
812 | public function setMaxFilesize($bytes) |
||
830 | |||
831 | /** |
||
832 | * Set Port |
||
833 | * |
||
834 | * @access public |
||
835 | * @param $port |
||
836 | */ |
||
837 | public function setPort($port) |
||
841 | |||
842 | /** |
||
843 | * Set Connect Timeout |
||
844 | * |
||
845 | * @access public |
||
846 | * @param $seconds |
||
847 | */ |
||
848 | public function setConnectTimeout($seconds) |
||
852 | |||
853 | /** |
||
854 | * Set Cookie String |
||
855 | * |
||
856 | * @access public |
||
857 | * @param $string |
||
858 | * |
||
859 | * @return bool |
||
860 | */ |
||
861 | public function setCookieString($string) |
||
865 | |||
866 | /** |
||
867 | * Set Cookie File |
||
868 | * |
||
869 | * @access public |
||
870 | * @param $cookie_file |
||
871 | * |
||
872 | * @return boolean |
||
873 | */ |
||
874 | public function setCookieFile($cookie_file) |
||
878 | |||
879 | /** |
||
880 | * Set Cookie Jar |
||
881 | * |
||
882 | * @access public |
||
883 | * @param $cookie_jar |
||
884 | * |
||
885 | * @return boolean |
||
886 | */ |
||
887 | public function setCookieJar($cookie_jar) |
||
891 | |||
892 | /** |
||
893 | * Set Default JSON Decoder |
||
894 | * |
||
895 | * @access public |
||
896 | * @param $assoc |
||
897 | * @param $depth |
||
898 | * @param $options |
||
899 | */ |
||
900 | 1 | public function setDefaultJsonDecoder() |
|
920 | |||
921 | /** |
||
922 | * Set Default XML Decoder |
||
923 | * |
||
924 | * @access public |
||
925 | */ |
||
926 | public function setDefaultXmlDecoder() |
||
936 | |||
937 | /** |
||
938 | * Set Default Decoder |
||
939 | * |
||
940 | * @access public |
||
941 | * @param $decoder string|callable |
||
942 | */ |
||
943 | public function setDefaultDecoder($decoder = 'json') |
||
955 | |||
956 | /** |
||
957 | * Set Default Timeout |
||
958 | * |
||
959 | * @access public |
||
960 | */ |
||
961 | 1 | public function setDefaultTimeout() |
|
965 | |||
966 | /** |
||
967 | * Set Default User Agent |
||
968 | * |
||
969 | * @access public |
||
970 | */ |
||
971 | 1 | public function setDefaultUserAgent() |
|
979 | |||
980 | /** |
||
981 | * Set Header |
||
982 | * |
||
983 | * Add extra header to include in the request. |
||
984 | * |
||
985 | * @access public |
||
986 | * @param $key |
||
987 | * @param $value |
||
988 | */ |
||
989 | public function setHeader($key, $value) |
||
998 | |||
999 | /** |
||
1000 | * Set Headers |
||
1001 | * |
||
1002 | * Add extra headers to include in the request. |
||
1003 | * |
||
1004 | * @access public |
||
1005 | * @param $headers |
||
1006 | */ |
||
1007 | public function setHeaders($headers) |
||
1019 | |||
1020 | /** |
||
1021 | * Set JSON Decoder |
||
1022 | * |
||
1023 | * @access public |
||
1024 | * @param $function |
||
1025 | */ |
||
1026 | public function setJsonDecoder($function) |
||
1032 | |||
1033 | /** |
||
1034 | * Set XML Decoder |
||
1035 | * |
||
1036 | * @access public |
||
1037 | * @param $function |
||
1038 | */ |
||
1039 | public function setXmlDecoder($function) |
||
1045 | |||
1046 | /** |
||
1047 | * Set Opt |
||
1048 | * |
||
1049 | * @access public |
||
1050 | * @param $option |
||
1051 | * @param $value |
||
1052 | * |
||
1053 | * @return boolean |
||
1054 | */ |
||
1055 | 3 | public function setOpt($option, $value) |
|
1071 | |||
1072 | /** |
||
1073 | * Set Opts |
||
1074 | * |
||
1075 | * @access public |
||
1076 | * @param $options |
||
1077 | * |
||
1078 | * @return boolean |
||
1079 | * Returns true if all options were successfully set. If an option could not be successfully set, false is |
||
1080 | * immediately returned, ignoring any future options in the options array. Similar to curl_setopt_array(). |
||
1081 | */ |
||
1082 | public function setOpts($options) |
||
1091 | |||
1092 | /** |
||
1093 | * Set Referer |
||
1094 | * |
||
1095 | * @access public |
||
1096 | * @param $referer |
||
1097 | */ |
||
1098 | public function setReferer($referer) |
||
1102 | |||
1103 | /** |
||
1104 | * Set Referrer |
||
1105 | * |
||
1106 | * @access public |
||
1107 | * @param $referrer |
||
1108 | */ |
||
1109 | public function setReferrer($referrer) |
||
1113 | |||
1114 | /** |
||
1115 | * Set Timeout |
||
1116 | * |
||
1117 | * @access public |
||
1118 | * @param $seconds |
||
1119 | */ |
||
1120 | 3 | public function setTimeout($seconds) |
|
1124 | |||
1125 | /** |
||
1126 | * Set Url |
||
1127 | * |
||
1128 | * @access public |
||
1129 | * @param $url |
||
1130 | * @param $data |
||
1131 | */ |
||
1132 | 3 | public function setUrl($url, $data = array()) |
|
1138 | |||
1139 | /** |
||
1140 | * Set User Agent |
||
1141 | * |
||
1142 | * @access public |
||
1143 | * @param $user_agent |
||
1144 | */ |
||
1145 | 1 | public function setUserAgent($user_agent) |
|
1149 | |||
1150 | /** |
||
1151 | * Success |
||
1152 | * |
||
1153 | * @access public |
||
1154 | * @param $callback |
||
1155 | */ |
||
1156 | public function success($callback) |
||
1160 | |||
1161 | /** |
||
1162 | * Unset Header |
||
1163 | * |
||
1164 | * Remove extra header previously set using Curl::setHeader(). |
||
1165 | * |
||
1166 | * @access public |
||
1167 | * @param $key |
||
1168 | */ |
||
1169 | public function unsetHeader($key) |
||
1178 | |||
1179 | /** |
||
1180 | * Remove Header |
||
1181 | * |
||
1182 | * Remove an internal header from the request. |
||
1183 | * Using `curl -H "Host:" ...' is equivalent to $curl->removeHeader('Host');. |
||
1184 | * |
||
1185 | * @access public |
||
1186 | * @param $key |
||
1187 | */ |
||
1188 | public function removeHeader($key) |
||
1192 | |||
1193 | /** |
||
1194 | * Verbose |
||
1195 | * |
||
1196 | * @access public |
||
1197 | * @param bool $on |
||
1198 | * @param resource $output |
||
1199 | */ |
||
1200 | public function verbose($on = true, $output = STDERR) |
||
1210 | |||
1211 | /** |
||
1212 | * Destruct |
||
1213 | * |
||
1214 | * @access public |
||
1215 | */ |
||
1216 | public function __destruct() |
||
1220 | |||
1221 | public function __get($name) |
||
1229 | |||
1230 | /** |
||
1231 | * Get Effective Url |
||
1232 | * |
||
1233 | * @access private |
||
1234 | */ |
||
1235 | private function __get_effectiveUrl() |
||
1239 | |||
1240 | /** |
||
1241 | * Get RFC 2616 |
||
1242 | * |
||
1243 | * @access private |
||
1244 | */ |
||
1245 | private function __get_rfc2616() |
||
1249 | |||
1250 | /** |
||
1251 | * Get RFC 6265 |
||
1252 | * |
||
1253 | * @access private |
||
1254 | */ |
||
1255 | private function __get_rfc6265() |
||
1259 | |||
1260 | /** |
||
1261 | * Get Total Time |
||
1262 | * |
||
1263 | * @access private |
||
1264 | */ |
||
1265 | private function __get_totalTime() |
||
1269 | |||
1270 | /** |
||
1271 | * Build Url |
||
1272 | * |
||
1273 | * @access private |
||
1274 | * @param $url |
||
1275 | * @param $data |
||
1276 | * |
||
1277 | * @return string |
||
1278 | */ |
||
1279 | 3 | private function buildURL($url, $data = array()) |
|
1283 | |||
1284 | /** |
||
1285 | * Parse Headers |
||
1286 | * |
||
1287 | * @access private |
||
1288 | * @param $raw_headers |
||
1289 | * |
||
1290 | * @return array |
||
1291 | */ |
||
1292 | 3 | private function parseHeaders($raw_headers) |
|
1312 | |||
1313 | /** |
||
1314 | * Parse Request Headers |
||
1315 | * |
||
1316 | * @access private |
||
1317 | * @param $raw_headers |
||
1318 | * |
||
1319 | * @return array |
||
1320 | */ |
||
1321 | 3 | private function parseRequestHeaders($raw_headers) |
|
1331 | |||
1332 | /** |
||
1333 | * Parse Response |
||
1334 | * |
||
1335 | * @access private |
||
1336 | * @param $response_headers |
||
1337 | * @param $raw_response |
||
1338 | * |
||
1339 | * @return mixed |
||
1340 | * Provided the content-type is determined to be json or xml: |
||
1341 | * Returns stdClass object when the default json decoder is used and the content-type is json. |
||
1342 | * Returns SimpleXMLElement object when the default xml decoder is used and the content-type is xml. |
||
1343 | */ |
||
1344 | 3 | private function parseResponse($response_headers, $raw_response) |
|
1368 | |||
1369 | /** |
||
1370 | * Parse Response Headers |
||
1371 | * |
||
1372 | * @access private |
||
1373 | * @param $raw_response_headers |
||
1374 | * |
||
1375 | * @return array |
||
1376 | */ |
||
1377 | 3 | private function parseResponseHeaders($raw_response_headers) |
|
1396 | |||
1397 | } |
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.