`
mengdejun
  • 浏览: 400803 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

php socket GET POST提交方法(HttpClient) 框架

    博客分类:
  • Php
阅读更多
<?php

/* Version 0.9, 6th April 2003 - Simon Willison ( http://simon.incutio.com/ )
   Manual: http://scripts.incutio.com/httpclient/
*/

class HttpClient {
    // Request vars
    var $host;
    var $port;
    var $path;
    var $method;
    var $postdata = '';
    var $cookies = array();
    var $referer;
    var $accept = 'text/xml,application/xml,application/xhtml+xml,text/html,text/plain,image/png,image/jpeg,image/gif,*/*';
    var $accept_encoding = 'gzip';
    var $accept_language = 'en-us';
    var $user_agent = 'Incutio HttpClient v0.9';
    // Options
    var $timeout = 20;
    var $use_gzip = true;
    var $persist_cookies = true;  // If true, received cookies are placed in the $this->cookies array ready for the next request
                                  // Note: This currently ignores the cookie path (and time) completely. Time is not important, 
                                  //       but path could possibly lead to security problems.
    var $persist_referers = true; // For each request, sends path of last request as referer
    var $debug = false;
    var $handle_redirects = true; // Auaomtically redirect if Location or URI header is found
    var $max_redirects = 5;
    var $headers_only = false;    // If true, stops receiving once headers have been read.
    // Basic authorization variables
    var $username;
    var $password;
    // Response vars
    var $status;
    var $headers = array();
    var $content = '';
    var $errormsg;
    // Tracker variables
    var $redirect_count = 0;
    var $cookie_host = '';
    function HttpClient($host, $port=80) {
        $this->host = $host;
        $this->port = $port;
    }
    function get($path, $data = false) {
        $this->path = $path;
        $this->method = 'GET';
        if ($data) {
            $this->path .= '?'.$this->buildQueryString($data);
        }
        return $this->doRequest();
    }
    function post($path, $data) {
        $this->path = $path;
        $this->method = 'POST';
        $this->postdata = $this->buildQueryString($data);
    	return $this->doRequest();
    }
    function buildQueryString($data) {
        $querystring = '';
        if (is_array($data)) {
            // Change data in to postable data
    		foreach ($data as $key => $val) {
    			if (is_array($val)) {
    				foreach ($val as $val2) {
    					$querystring .= urlencode($key).'='.urlencode($val2).'&';
    				}
    			} else {
    				$querystring .= urlencode($key).'='.urlencode($val).'&';
    			}
    		}
    		$querystring = substr($querystring, 0, -1); // Eliminate unnecessary &
    	} else {
    	    $querystring = $data;
    	}
    	return $querystring;
    }
    function doRequest() {
        // Performs the actual HTTP request, returning true or false depending on outcome
		if (!$fp = @fsockopen($this->host, $this->port, $errno, $errstr, $this->timeout)) {
		    // Set error message
            switch($errno) {
				case -3:
					$this->errormsg = 'Socket creation failed (-3)';
				case -4:
					$this->errormsg = 'DNS lookup failure (-4)';
				case -5:
					$this->errormsg = 'Connection refused or timed out (-5)';
				default:
					$this->errormsg = 'Connection failed ('.$errno.')';
			    $this->errormsg .= ' '.$errstr;
			    $this->debug($this->errormsg);
			}
			return false;
        }
        socket_set_timeout($fp, $this->timeout);
        $request = $this->buildRequest();
        $this->debug('Request', $request);
        fwrite($fp, $request);
    	// Reset all the variables that should not persist between requests
    	$this->headers = array();
    	$this->content = '';
    	$this->errormsg = '';
    	// Set a couple of flags
    	$inHeaders = true;
    	$atStart = true;
    	// Now start reading back the response
    	while (!feof($fp)) {
    	    $line = fgets($fp, 4096);
    	    if ($atStart) {
    	        // Deal with first line of returned data
    	        $atStart = false;
    	        if (!preg_match('/HTTP\/(\\d\\.\\d)\\s*(\\d+)\\s*(.*)/', $line, $m)) {
    	            $this->errormsg = "Status code line invalid: ".htmlentities($line);
    	            $this->debug($this->errormsg);
    	            return false;
    	        }
    	        $http_version = $m[1]; // not used
    	        $this->status = $m[2];
    	        $status_string = $m[3]; // not used
    	        $this->debug(trim($line));
    	        continue;
    	    }
    	    if ($inHeaders) {
    	        if (trim($line) == '') {
    	            $inHeaders = false;
    	            $this->debug('Received Headers', $this->headers);
    	            if ($this->headers_only) {
    	                break; // Skip the rest of the input
    	            }
    	            continue;
    	        }
    	        if (!preg_match('/([^:]+):\\s*(.*)/', $line, $m)) {
    	            // Skip to the next header
    	            continue;
    	        }
    	        $key = strtolower(trim($m[1]));
    	        $val = trim($m[2]);
    	        // Deal with the possibility of multiple headers of same name
    	        if (isset($this->headers[$key])) {
    	            if (is_array($this->headers[$key])) {
    	                $this->headers[$key][] = $val;
    	            } else {
    	                $this->headers[$key] = array($this->headers[$key], $val);
    	            }
    	        } else {
    	            $this->headers[$key] = $val;
    	        }
    	        continue;
    	    }
    	    // We're not in the headers, so append the line to the contents
    	    $this->content .= $line;
        }
        fclose($fp);
        // If data is compressed, uncompress it
        if (isset($this->headers['content-encoding']) && $this->headers['content-encoding'] == 'gzip') {
            $this->debug('Content is gzip encoded, unzipping it');
            $this->content = substr($this->content, 10); // See http://www.php.net/manual/en/function.gzencode.php
            $this->content = gzinflate($this->content);
        }
        // If $persist_cookies, deal with any cookies
        if ($this->persist_cookies && isset($this->headers['set-cookie']) && $this->host == $this->cookie_host) {
            $cookies = $this->headers['set-cookie'];
            if (!is_array($cookies)) {
                $cookies = array($cookies);
            }
            foreach ($cookies as $cookie) {
                if (preg_match('/([^=]+)=([^;]+);/', $cookie, $m)) {
                    $this->cookies[$m[1]] = $m[2];
                }
            }
            // Record domain of cookies for security reasons
            $this->cookie_host = $this->host;
        }
        // If $persist_referers, set the referer ready for the next request
        if ($this->persist_referers) {
            $this->debug('Persisting referer: '.$this->getRequestURL());
            $this->referer = $this->getRequestURL();
        }
        // Finally, if handle_redirects and a redirect is sent, do that
        if ($this->handle_redirects) {
            if (++$this->redirect_count >= $this->max_redirects) {
                $this->errormsg = 'Number of redirects exceeded maximum ('.$this->max_redirects.')';
                $this->debug($this->errormsg);
                $this->redirect_count = 0;
                return false;
            }
            $location = isset($this->headers['location']) ? $this->headers['location'] : '';
            $uri = isset($this->headers['uri']) ? $this->headers['uri'] : '';
            if ($location || $uri) {
                $url = parse_url($location.$uri);
                // This will FAIL if redirect is to a different site
                return $this->get($url['path']);
            }
        }
        return true;
    }
    function buildRequest() {
        $headers = array();
        $headers[] = "{$this->method} {$this->path} HTTP/1.0"; // Using 1.1 leads to all manner of problems, such as "chunked" encoding
        $headers[] = "Host: {$this->host}";
        $headers[] = "User-Agent: {$this->user_agent}";
        $headers[] = "Accept: {$this->accept}";
        if ($this->use_gzip) {
            $headers[] = "Accept-encoding: {$this->accept_encoding}";
        }
        $headers[] = "Accept-language: {$this->accept_language}";
        if ($this->referer) {
            $headers[] = "Referer: {$this->referer}";
        }
    	// Cookies
    	if ($this->cookies) {
    	    $cookie = 'Cookie: ';
    	    foreach ($this->cookies as $key => $value) {
    	        $cookie .= "$key=$value; ";
    	    }
    	    $headers[] = $cookie;
    	}
    	// Basic authentication
    	if ($this->username && $this->password) {
    	    $headers[] = 'Authorization: BASIC '.base64_encode($this->username.':'.$this->password);
    	}
    	// If this is a POST, set the content type and length
    	if ($this->postdata) {
    	    $headers[] = 'Content-Type: application/x-www-form-urlencoded';
    	    $headers[] = 'Content-Length: '.strlen($this->postdata);
    	}
    	$request = implode("\r\n", $headers)."\r\n\r\n".$this->postdata;
    	return $request;
    }
    function getStatus() {
        return $this->status;
    }
    function getContent() {
        return $this->content;
    }
    function getHeaders() {
        return $this->headers;
    }
    function getHeader($header) {
        $header = strtolower($header);
        if (isset($this->headers[$header])) {
            return $this->headers[$header];
        } else {
            return false;
        }
    }
    function getError() {
        return $this->errormsg;
    }
    function getCookies() {
        return $this->cookies;
    }
    function getRequestURL() {
        $url = 'http://'.$this->host;
        if ($this->port != 80) {
            $url .= ':'.$this->port;
        }            
        $url .= $this->path;
        return $url;
    }
    // Setter methods
    function setUserAgent($string) {
        $this->user_agent = $string;
    }
    function setAuthorization($username, $password) {
        $this->username = $username;
        $this->password = $password;
    }
    function setCookies($array) {
        $this->cookies = $array;
    }
    // Option setting methods
    function useGzip($boolean) {
        $this->use_gzip = $boolean;
    }
    function setPersistCookies($boolean) {
        $this->persist_cookies = $boolean;
    }
    function setPersistReferers($boolean) {
        $this->persist_referers = $boolean;
    }
    function setHandleRedirects($boolean) {
        $this->handle_redirects = $boolean;
    }
    function setMaxRedirects($num) {
        $this->max_redirects = $num;
    }
    function setHeadersOnly($boolean) {
        $this->headers_only = $boolean;
    }
    function setDebug($boolean) {
        $this->debug = $boolean;
    }
    // "Quick" static methods
    function quickGet($url) {
        $bits = parse_url($url);
        $host = $bits['host'];
        $port = isset($bits['port']) ? $bits['port'] : 80;
        $path = isset($bits['path']) ? $bits['path'] : '/';
        if (isset($bits['query'])) {
            $path .= '?'.$bits['query'];
        }
        $client = new HttpClient($host, $port);
        if (!$client->get($path)) {
            return false;
        } else {
            return $client->getContent();
        }
    }
    function quickPost($url, $data) {
        $bits = parse_url($url);
        $host = $bits['host'];
        $port = isset($bits['port']) ? $bits['port'] : 80;
        $path = isset($bits['path']) ? $bits['path'] : '/';
        $client = new HttpClient($host, $port);
        if (!$client->post($path, $data)) {
            return false;
        } else {
            return $client->getContent();
        }
    }
    function debug($msg, $object = false) {
        if ($this->debug) {
            print '<div style="border: 1px solid red; padding: 0.5em; margin: 0.5em;"><strong>HttpClient Debug:</strong> '.$msg;
            if ($object) {
                ob_start();
        	    print_r($object);
        	    $content = htmlentities(ob_get_contents());
        	    ob_end_clean();
        	    print '<pre>'.$content.'</pre>';
        	}
        	print '</div>';
        }
    }   
}

?>

 

HttpClient Manual

HttpClient Home | Download HttpClient (tar.gz) | HttpClient Examples | HttpClient Demo

Only methods that are intended to be called from outside the script are described. For details of internal methods, Use The Source :)

HttpClient($host, $port = 80)
Constructor. Takes the web server host (for example, 'scripts.incutio.com') and an optional port.
bool get($path, $data = false)
Executes a GET request for the specified path. If $data is specified, appends it to a query string as part of the get request. $data can be an array of key value pairs, in which case a matching query string will be constructed. Returns true on success and false on failure. If false, an error message describing the problem encountered can be accessed using the getError() method.
bool post($path, $data)
Executes a POST request to the specified path, sending the information from specified in $data. $data can be an array of key value pairs, in which case a matching post request will be constructed. Returns true on success and false on failure. If false, an error message describing the problem encountered can be accessed using the getError() method.
string getContent()
Returns the content of the HTTP response. This is usually an HTML document.
string getStatus()
Returns the status code of the response - 200 means OK, 404 means file not found, etc.
array getHeaders()
Returns the HTTP headers returned by the server as an associative array.
string getHeader($header)
Returns the specified response header, or false if it does not exist.
string getError()
Returns a string describing the most recent error.
string getRequestURL()
Returns the full URL that has been requested.
array getCookies()
Returns an array of cookies set by the server.
string quickGet($url)
Static method designed for running simple GET requests. Usage is:
$pageContent = HttpClient::quickGet($url);
Returns the empty string on failure.
string quickPost($url, $data)
Static method designed for running simple POST requests. Usage is:
$pageContent = HttpClient::quickPost($url, $data);
Returns the empty string on failure. See also post().
void setUserAgent($string)
Sets the user agent string to be used in the request. Default is "Incutio HttpClient v$version".
void setAuthorization($username, $password)
Sets the HTTP authorization username and password to be used in requests. Don't forget to unset this in subsequent requests to different servers.
void setCookies($array)
Sets the cookies to be sent in the request. Takes a 2D array of name value pairs.
void setUseGzip($boolean)
Specify if the client should request gzip encoded content from the server (saves bandwidth but can increase processor time). Default behaviour is TRUE.
void setPersistCookies($boolean)
Specify if the client should persist cookies between requests. Default behaviour is TRUE.
void setPersistReferers($boolean)
Specify if the client should use the URL of the previous request as the referral of a subsequent request. Default behaviour is TRUE.
void setHandleRedirects($boolean)
Specify if the client should automatically follow redirected requests. Default behaviour is TRUE.
void setMaxRedirects($int)
Set the maximum number of redirects allowed before the client quits (mainly to prevent infinite loops) Default is 5.
void setHeadersOnly($boolean)
If TRUE, the client only retrieves the headers from a page. This could be useful for implementing things like link checkers. Defaults to FALSE.
void setDebug($boolean)
Should the client run in debug mode? Default behaviour is FALSE.
void debug($message, $object = false)
This method is not intended to be called from outside the class; it is the method the class calls whenever there is debugging information available. $msg is a debugging message and $object is an optional object to be displayed (usually an array). Default behaviour is to display the message and the object in a red bordered div. If you wish debugging information to be handled in a different way you can do so by creating a new class that extends HttpClient and over-riding the debug() method in that class.

Grabbing an HTML page (static method)

$pageContents = HttpClient::quickGet('http://example.com/');

Posting a form and grabbing the response (static method)

$pageContents = HttpClient::quickPost('http://example.com/someForm', array(
    'name' => 'Some Name',
    'email' => 'email@example.com'
));

The static methods are easy to use, but seriously limit the functionality of the class as you cannot access returned headers or use facilities such as cookies or authentication.

A simple GET request using the class

$client = new HttpClient('example.com');
if (!$client->get('/')) {
    die('An error occurred: '.$client->getError());
}
$pageContents = $client->getContent();

A GET request with debugging turned on

$client = new HttpClient('example.com');
$client->setDebug(true);
if (!$client->get('/')) {
    die('An error occurred: '.$client->getError());
}
$pageContents = $client->getContent();

A GET request demonstrating automatic redirection

$client = new HttpClient('www.amazon.com');
$client->setDebug(true);
if (!$client->get('/')) {
    die('An error occurred: '.$client->getError());
}
$pageContents = $client->getContent();

Check to see if a page exists

$client = new HttpClient('example.com');
$client->setDebug(true);
if (!$client->get('/thispagedoesnotexist')) {
    die('An error occurred: '.$client->getError());
}
if ($client->getStatus() == '404') {
    echo 'Page does not exist!';
}
$pageContents = $client->getContent();

Fake the User Agent string

$client = new HttpClient('example.com');
$client->setDebug(true);
$client->setUserAgent('Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.3a) Gecko/20021207');
if (!$client->get('/')) {
    die('An error occurred: '.$client->getError());
}
$pageContents = $client->getContent();

Log in to a site via a login form, then request a page

In this example, it is assumed that correctly logging in will result in the server sending a sesssion cookie of some sort. This cookie is resent by the HttpClient class automatically, so a request to a page that requires users to be logged in will now work.

$client = new HttpClient('example.com');
$client->post('/login.php', array(
    'username' => 'Simon',
    'password' => 'ducks'
));
if (!$client->get('/private.php')) {
    die('An error occurred: '.$client->getError());
}
$pageContents = $client->getContent();

Using HTTP authorisation

Note that the class uses the American spelling 'authorization' to fit with the HTTP specification.

$client = new HttpClient('example.com');
$client->setAuthorization('Username', 'Password');
if (!$client->get('/')) {
    die('An error occurred: '.$client->getError());
}
$pageContents = $client->getContent();

Print out the headers from a response

$client = new HttpClient('example.com');
if (!$client->get('/')) {
    die('An error occurred: '.$client->getError());
}
print_r($client->getHeaders());

Setting the maximum number of redirects

 $client = new HttpClient('www.amazon.com');
  $client->setDebug(true);
  $client->setMaxRedirects(3);
  $client->get('/');

 

 

官网:http://scripts.incutio.com/httpclient/

服我网:http://www.freework.me

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics