Complex classes like HTTPClient 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 HTTPClient, and based on these observations, apply Extract Interface, too.
| 1 | <?php  | 
            ||
| 100 | class HTTPClient { | 
            ||
| 101 | //set these if you like  | 
            ||
| 102 | var $agent; // User agent  | 
            ||
| 103 | var $http; // HTTP version defaults to 1.0  | 
            ||
| 104 | var $timeout; // read timeout (seconds)  | 
            ||
| 105 | var $cookies;  | 
            ||
| 106 | var $referer;  | 
            ||
| 107 | var $max_redirect;  | 
            ||
| 108 | var $max_bodysize;  | 
            ||
| 109 | var $max_bodysize_abort = true; // if set, abort if the response body is bigger than max_bodysize  | 
            ||
| 110 | var $header_regexp; // if set this RE must match against the headers, else abort  | 
            ||
| 111 | var $headers;  | 
            ||
| 112 | var $debug;  | 
            ||
| 113 | var $start = 0.0; // for timings  | 
            ||
| 114 | var $keep_alive = true; // keep alive rocks  | 
            ||
| 115 | |||
| 116 | // don't set these, read on error  | 
            ||
| 117 | var $error;  | 
            ||
| 118 | var $redirect_count;  | 
            ||
| 119 | |||
| 120 | // read these after a successful request  | 
            ||
| 121 | var $status;  | 
            ||
| 122 | var $resp_body;  | 
            ||
| 123 | var $resp_headers;  | 
            ||
| 124 | |||
| 125 | // set these to do basic authentication  | 
            ||
| 126 | var $user;  | 
            ||
| 127 | var $pass;  | 
            ||
| 128 | |||
| 129 | // set these if you need to use a proxy  | 
            ||
| 130 | var $proxy_host;  | 
            ||
| 131 | var $proxy_port;  | 
            ||
| 132 | var $proxy_user;  | 
            ||
| 133 | var $proxy_pass;  | 
            ||
| 134 | var $proxy_ssl; //boolean set to true if your proxy needs SSL  | 
            ||
| 135 | var $proxy_except; // regexp of URLs to exclude from proxy  | 
            ||
| 136 | |||
| 137 | // list of kept alive connections  | 
            ||
| 138 | static $connections = array();  | 
            ||
| 139 | |||
| 140 | // what we use as boundary on multipart/form-data posts  | 
            ||
| 141 | var $boundary = '---DokuWikiHTTPClient--4523452351';  | 
            ||
| 142 | |||
| 143 | /**  | 
            ||
| 144 | * Constructor.  | 
            ||
| 145 | *  | 
            ||
| 146 | * @author Andreas Gohr <[email protected]>  | 
            ||
| 147 | */  | 
            ||
| 148 |     function __construct(){ | 
            ||
| 149 | $this->agent = 'Mozilla/4.0 (compatible; DokuWiki HTTP Client; '.PHP_OS.')';  | 
            ||
| 150 | $this->timeout = 15;  | 
            ||
| 151 | $this->cookies = array();  | 
            ||
| 152 | $this->referer = '';  | 
            ||
| 153 | $this->max_redirect = 3;  | 
            ||
| 154 | $this->redirect_count = 0;  | 
            ||
| 155 | $this->status = 0;  | 
            ||
| 156 | $this->headers = array();  | 
            ||
| 157 | $this->http = '1.0';  | 
            ||
| 158 | $this->debug = false;  | 
            ||
| 159 | $this->max_bodysize = 0;  | 
            ||
| 160 | $this->header_regexp= '';  | 
            ||
| 161 |         if(extension_loaded('zlib')) $this->headers['Accept-encoding'] = 'gzip'; | 
            ||
| 162 | $this->headers['Accept'] = 'text/xml,application/xml,application/xhtml+xml,'.  | 
            ||
| 163 | 'text/html,text/plain,image/png,image/jpeg,image/gif,*/*';  | 
            ||
| 164 | $this->headers['Accept-Language'] = 'en-us';  | 
            ||
| 165 | }  | 
            ||
| 166 | |||
| 167 | |||
| 168 | /**  | 
            ||
| 169 | * Simple function to do a GET request  | 
            ||
| 170 | *  | 
            ||
| 171 | * Returns the wanted page or false on an error;  | 
            ||
| 172 | *  | 
            ||
| 173 | * @param string $url The URL to fetch  | 
            ||
| 174 | * @param bool $sloppy304 Return body on 304 not modified  | 
            ||
| 175 | * @return false|string response body, false on error  | 
            ||
| 176 | *  | 
            ||
| 177 | * @author Andreas Gohr <[email protected]>  | 
            ||
| 178 | */  | 
            ||
| 179 |     function get($url,$sloppy304=false){ | 
            ||
| 180 | if(!$this->sendRequest($url)) return false;  | 
            ||
| 181 | if($this->status == 304 && $sloppy304) return $this->resp_body;  | 
            ||
| 182 | if($this->status < 200 || $this->status > 206) return false;  | 
            ||
| 183 | return $this->resp_body;  | 
            ||
| 184 | }  | 
            ||
| 185 | |||
| 186 | /**  | 
            ||
| 187 | * Simple function to do a GET request with given parameters  | 
            ||
| 188 | *  | 
            ||
| 189 | * Returns the wanted page or false on an error.  | 
            ||
| 190 | *  | 
            ||
| 191 | * This is a convenience wrapper around get(). The given parameters  | 
            ||
| 192 | * will be correctly encoded and added to the given base URL.  | 
            ||
| 193 | *  | 
            ||
| 194 | * @param string $url The URL to fetch  | 
            ||
| 195 | * @param array $data Associative array of parameters  | 
            ||
| 196 | * @param bool $sloppy304 Return body on 304 not modified  | 
            ||
| 197 | * @return false|string response body, false on error  | 
            ||
| 198 | *  | 
            ||
| 199 | * @author Andreas Gohr <[email protected]>  | 
            ||
| 200 | */  | 
            ||
| 201 |     function dget($url,$data,$sloppy304=false){ | 
            ||
| 202 |         if(strpos($url,'?')){ | 
            ||
| 203 | $url .= '&';  | 
            ||
| 204 |         }else{ | 
            ||
| 205 | $url .= '?';  | 
            ||
| 206 | }  | 
            ||
| 207 | $url .= $this->_postEncode($data);  | 
            ||
| 208 | return $this->get($url,$sloppy304);  | 
            ||
| 209 | }  | 
            ||
| 210 | |||
| 211 | /**  | 
            ||
| 212 | * Simple function to do a POST request  | 
            ||
| 213 | *  | 
            ||
| 214 | * Returns the resulting page or false on an error;  | 
            ||
| 215 | *  | 
            ||
| 216 | * @param string $url The URL to fetch  | 
            ||
| 217 | * @param array $data Associative array of parameters  | 
            ||
| 218 | * @return false|string response body, false on error  | 
            ||
| 219 | * @author Andreas Gohr <[email protected]>  | 
            ||
| 220 | */  | 
            ||
| 221 |     function post($url,$data){ | 
            ||
| 226 | |||
| 227 | /**  | 
            ||
| 228 | * Send an HTTP request  | 
            ||
| 229 | *  | 
            ||
| 230 | * This method handles the whole HTTP communication. It respects set proxy settings,  | 
            ||
| 231 | * builds the request headers, follows redirects and parses the response.  | 
            ||
| 232 | *  | 
            ||
| 233 | * Post data should be passed as associative array. When passed as string it will be  | 
            ||
| 234 | * sent as is. You will need to setup your own Content-Type header then.  | 
            ||
| 235 | *  | 
            ||
| 236 | * @param string $url - the complete URL  | 
            ||
| 237 | * @param mixed $data - the post data either as array or raw data  | 
            ||
| 238 | * @param string $method - HTTP Method usually GET or POST.  | 
            ||
| 239 | * @return bool - true on success  | 
            ||
| 240 | *  | 
            ||
| 241 | * @author Andreas Goetz <[email protected]>  | 
            ||
| 242 | * @author Andreas Gohr <[email protected]>  | 
            ||
| 243 | */  | 
            ||
| 244 |     function sendRequest($url,$data='',$method='GET'){ | 
            ||
| 557 | |||
| 558 | /**  | 
            ||
| 559 | * Tries to establish a CONNECT tunnel via Proxy  | 
            ||
| 560 | *  | 
            ||
| 561 | * Protocol, Servername and Port will be stripped from the request URL when a successful CONNECT happened  | 
            ||
| 562 | *  | 
            ||
| 563 | * @param resource &$socket  | 
            ||
| 564 | * @param string &$requesturl  | 
            ||
| 565 | * @throws HTTPClientException when a tunnel is needed but could not be established  | 
            ||
| 566 | * @return bool true if a tunnel was established  | 
            ||
| 567 | */  | 
            ||
| 568 |     function _ssltunnel(&$socket, &$requesturl){ | 
            ||
| 569 | if(!$this->proxy_host) return false;  | 
            ||
| 570 | $requestinfo = parse_url($requesturl);  | 
            ||
| 571 | if($requestinfo['scheme'] != 'https') return false;  | 
            ||
| 572 | if(!$requestinfo['port']) $requestinfo['port'] = 443;  | 
            ||
| 573 | |||
| 574 | // build request  | 
            ||
| 575 |         $request  = "CONNECT {$requestinfo['host']}:{$requestinfo['port']} HTTP/1.0".HTTP_NL; | 
            ||
| 576 |         $request .= "Host: {$requestinfo['host']}".HTTP_NL; | 
            ||
| 577 |         if($this->proxy_user) { | 
            ||
| 578 | $request .= 'Proxy-Authorization: Basic '.base64_encode($this->proxy_user.':'.$this->proxy_pass).HTTP_NL;  | 
            ||
| 579 | }  | 
            ||
| 580 | $request .= HTTP_NL;  | 
            ||
| 581 | |||
| 582 |         $this->_debug('SSL Tunnel CONNECT',$request); | 
            ||
| 583 | $this->_sendData($socket, $request, 'SSL Tunnel CONNECT');  | 
            ||
| 584 | |||
| 585 | // read headers from socket  | 
            ||
| 586 | $r_headers = '';  | 
            ||
| 587 |         do{ | 
            ||
| 588 | $r_line = $this->_readLine($socket, 'headers');  | 
            ||
| 589 | $r_headers .= $r_line;  | 
            ||
| 590 | }while($r_line != "\r\n" && $r_line != "\n");  | 
            ||
| 591 | |||
| 592 |         $this->_debug('SSL Tunnel Response',$r_headers); | 
            ||
| 593 |         if(preg_match('/^HTTP\/1\.[01] 200/i',$r_headers)){ | 
            ||
| 594 | // set correct peer name for verification (enabled since PHP 5.6)  | 
            ||
| 595 | stream_context_set_option($socket, 'ssl', 'peer_name', $requestinfo['host']);  | 
            ||
| 596 | |||
| 597 | // because SSLv3 is mostly broken, we try TLS connections here first.  | 
            ||
| 598 | // according to https://github.com/splitbrain/dokuwiki/commit/c05ef534 we had problems with certain  | 
            ||
| 599 | // setups with this solution before, but we have no usable test for that and TLS should be the more  | 
            ||
| 600 | // common crypto by now  | 
            ||
| 601 |             if (@stream_socket_enable_crypto($socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) { | 
            ||
| 602 | $requesturl = $requestinfo['path'].  | 
            ||
| 603 | (!empty($requestinfo['query'])?'?'.$requestinfo['query']:'');  | 
            ||
| 604 | return true;  | 
            ||
| 605 | }  | 
            ||
| 606 | |||
| 607 | // if the above failed, this will most probably not work either, but we can try  | 
            ||
| 608 |             if (@stream_socket_enable_crypto($socket, true, STREAM_CRYPTO_METHOD_SSLv3_CLIENT)) { | 
            ||
| 609 | $requesturl = $requestinfo['path'].  | 
            ||
| 610 | (!empty($requestinfo['query'])?'?'.$requestinfo['query']:'');  | 
            ||
| 611 | return true;  | 
            ||
| 612 | }  | 
            ||
| 613 | |||
| 614 |             throw new HTTPClientException('Failed to set up crypto for secure connection to '.$requestinfo['host'], -151); | 
            ||
| 615 | }  | 
            ||
| 616 | |||
| 617 |         throw new HTTPClientException('Failed to establish secure proxy connection', -150); | 
            ||
| 618 | }  | 
            ||
| 619 | |||
| 620 | /**  | 
            ||
| 621 | * Safely write data to a socket  | 
            ||
| 622 | *  | 
            ||
| 623 | * @param resource $socket An open socket handle  | 
            ||
| 624 | * @param string $data The data to write  | 
            ||
| 625 | * @param string $message Description of what is being read  | 
            ||
| 626 | * @throws HTTPClientException  | 
            ||
| 627 | *  | 
            ||
| 628 | * @author Tom N Harris <[email protected]>  | 
            ||
| 629 | */  | 
            ||
| 630 |     function _sendData($socket, $data, $message) { | 
            ||
| 659 | |||
| 660 | /**  | 
            ||
| 661 | * Safely read data from a socket  | 
            ||
| 662 | *  | 
            ||
| 663 | * Reads up to a given number of bytes or throws an exception if the  | 
            ||
| 664 | * response times out or ends prematurely.  | 
            ||
| 665 | *  | 
            ||
| 666 | * @param resource $socket An open socket handle in non-blocking mode  | 
            ||
| 667 | * @param int $nbytes Number of bytes to read  | 
            ||
| 668 | * @param string $message Description of what is being read  | 
            ||
| 669 | * @param bool $ignore_eof End-of-file is not an error if this is set  | 
            ||
| 670 | * @throws HTTPClientException  | 
            ||
| 671 | * @return string  | 
            ||
| 672 | *  | 
            ||
| 673 | * @author Tom N Harris <[email protected]>  | 
            ||
| 674 | */  | 
            ||
| 675 |     function _readData($socket, $nbytes, $message, $ignore_eof = false) { | 
            ||
| 712 | |||
| 713 | /**  | 
            ||
| 714 | * Safely read a \n-terminated line from a socket  | 
            ||
| 715 | *  | 
            ||
| 716 | * Always returns a complete line, including the terminating \n.  | 
            ||
| 717 | *  | 
            ||
| 718 | * @param resource $socket An open socket handle in non-blocking mode  | 
            ||
| 719 | * @param string $message Description of what is being read  | 
            ||
| 720 | * @throws HTTPClientException  | 
            ||
| 721 | * @return string  | 
            ||
| 722 | *  | 
            ||
| 723 | * @author Tom N Harris <[email protected]>  | 
            ||
| 724 | */  | 
            ||
| 725 |     function _readLine($socket, $message) { | 
            ||
| 750 | |||
| 751 | /**  | 
            ||
| 752 | * print debug info  | 
            ||
| 753 | *  | 
            ||
| 754 | * Uses _debug_text or _debug_html depending on the SAPI name  | 
            ||
| 755 | *  | 
            ||
| 756 | * @author Andreas Gohr <[email protected]>  | 
            ||
| 757 | *  | 
            ||
| 758 | * @param string $info  | 
            ||
| 759 | * @param mixed $var  | 
            ||
| 760 | */  | 
            ||
| 761 |     function _debug($info,$var=null){ | 
            ||
| 769 | |||
| 770 | /**  | 
            ||
| 771 | * print debug info as HTML  | 
            ||
| 772 | *  | 
            ||
| 773 | * @param string $info  | 
            ||
| 774 | * @param mixed $var  | 
            ||
| 775 | */  | 
            ||
| 776 |     function _debug_html($info, $var=null){ | 
            ||
| 786 | |||
| 787 | /**  | 
            ||
| 788 | * prints debug info as plain text  | 
            ||
| 789 | *  | 
            ||
| 790 | * @param string $info  | 
            ||
| 791 | * @param mixed $var  | 
            ||
| 792 | */  | 
            ||
| 793 |     function _debug_text($info, $var=null){ | 
            ||
| 798 | |||
| 799 | /**  | 
            ||
| 800 | * Return current timestamp in microsecond resolution  | 
            ||
| 801 | *  | 
            ||
| 802 | * @return float  | 
            ||
| 803 | */  | 
            ||
| 804 |     static function _time(){ | 
            ||
| 808 | |||
| 809 | /**  | 
            ||
| 810 | * convert given header string to Header array  | 
            ||
| 811 | *  | 
            ||
| 812 | * All Keys are lowercased.  | 
            ||
| 813 | *  | 
            ||
| 814 | * @author Andreas Gohr <[email protected]>  | 
            ||
| 815 | *  | 
            ||
| 816 | * @param string $string  | 
            ||
| 817 | * @return array  | 
            ||
| 818 | */  | 
            ||
| 819 |     function _parseHeaders($string){ | 
            ||
| 841 | |||
| 842 | /**  | 
            ||
| 843 | * convert given header array to header string  | 
            ||
| 844 | *  | 
            ||
| 845 | * @author Andreas Gohr <[email protected]>  | 
            ||
| 846 | *  | 
            ||
| 847 | * @param array $headers  | 
            ||
| 848 | * @return string  | 
            ||
| 849 | */  | 
            ||
| 850 |     function _buildHeaders($headers){ | 
            ||
| 858 | |||
| 859 | /**  | 
            ||
| 860 | * get cookies as http header string  | 
            ||
| 861 | *  | 
            ||
| 862 | * @author Andreas Goetz <[email protected]>  | 
            ||
| 863 | *  | 
            ||
| 864 | * @return string  | 
            ||
| 865 | */  | 
            ||
| 866 |     function _getCookies(){ | 
            ||
| 875 | |||
| 876 | /**  | 
            ||
| 877 | * Encode data for posting  | 
            ||
| 878 | *  | 
            ||
| 879 | * @author Andreas Gohr <[email protected]>  | 
            ||
| 880 | *  | 
            ||
| 881 | * @param array $data  | 
            ||
| 882 | * @return string  | 
            ||
| 883 | */  | 
            ||
| 884 |     function _postEncode($data){ | 
            ||
| 887 | |||
| 888 | /**  | 
            ||
| 889 | * Encode data for posting using multipart encoding  | 
            ||
| 890 | *  | 
            ||
| 891 | * @fixme use of urlencode might be wrong here  | 
            ||
| 892 | * @author Andreas Gohr <[email protected]>  | 
            ||
| 893 | *  | 
            ||
| 894 | * @param array $data  | 
            ||
| 895 | * @return string  | 
            ||
| 896 | */  | 
            ||
| 897 |     function _postMultipartEncode($data){ | 
            ||
| 920 | |||
| 921 | /**  | 
            ||
| 922 | * Generates a unique identifier for a connection.  | 
            ||
| 923 | *  | 
            ||
| 924 | * @param string $server  | 
            ||
| 925 | * @param string $port  | 
            ||
| 926 | * @return string unique identifier  | 
            ||
| 927 | */  | 
            ||
| 928 |     function _uniqueConnectionId($server, $port) { | 
            ||
| 931 | }  | 
            ||
| 932 | |||
| 934 | 
Adding explicit visibility (
private,protected, orpublic) is generally recommend to communicate to other developers how, and from where this method is intended to be used.