|
/*
* Filename:httpclient.php
* Created on 2012-12-21
* Created by Robintang
* To change the template for this generated file go to
* Window-preferences-phpeclipse-php-code Templates
*/
Class Sincookie {
Public $name; Cookie Name
Public $value; Cookie value
The following three properties are not implemented now
Public $expires; Expiry time
public $path; Path
Public $domain; Domain
Create a cookie object from a cookie string
function __construct ($s = false) {
if ($s) {
$i 1 = strpos ($s, ' = ');
$i 2 = Strpos ($s, '; ');
$this->name = Trim (substr ($s, 0, $i 1));
$this->value = Trim (substr ($s, $i 1 +1, $i 2-$i 1-1));
}
}
Gets the cookie key value pair
function Getkeyvalue () {
Return "$this->name= $this->value";
}
}
Session context
Class Sinhttpcontext {
Public $cookies; Session cookies
Public $referer; Previous page address
function __construct () {
$this->cookies = Array ();
$this->refrer = "";
}
Set cookies
function Cookie ($key, $val) {
$ck = new Sincookie ();
$ck->name = $key;
$ck->value = $val;
$this->addcookie ($CK);
}
Add a cookie
function Addcookie ($ck) {
$this->cookies[$ck->name] = $ck;
}
Get a cookie string and use it when requested
function cookiesstring () {
$res = ";
foreach ($this->cookies as $ck) {
$res. = $ck->getkeyvalue (). ';';
}
return $res;
}
}
HTTP Request Object
Class Sinhttprequest {
public $url; Request Address
Public $method = ' GET '; Request method
Public $host; Host
public $path; Path
Public $scheme; Protocol, HTTP
Public $port; Port
Public $header; Request Header
Public $body; Request Body
Set Header
function SetHeader ($k, $v) {
if (!isset ($this->header)) {
$this->header = Array ();
}
$this->header[$k] = $v;
}
Get request string
Include header and request body
Write the socket directly after you get it.
function reqstring () {
$matches = Parse_url ($this->url);
!isset ($matches [' Host ']) && $matches [' host '] = ';
!isset ($matches [' path ']) && $matches [' path '] = ';
!isset ($matches [' query ']) && $matches [' query '] = ';
!isset ($matches [' Port ']) && $matches [' port '] = ';
$host = $matches [' Host '];
$path = $matches [' Path ']? $matches [' Path ']. ($matches [' query ']? '?' . $matches [' query ']: '): '/';
$port =!empty ($matches [' Port '])? $matches [' Port ']: 80;
$scheme = $matches [' scheme ']? $matches [' scheme ']: ' http ';
$this->host = $host;
$this->path = $path;
$this->scheme = $scheme;
$this->port = $port;
$method = Strtoupper ($this->method);
$res = "$method $path http/1.1\r\n";
$res. = "Host: $host \ r \ n";
if ($this->header) {
Reset ($this->header);
while (list ($k, $v) = each ($this->header)) {
if (Isset ($v) && strlen ($v) > 0)
$res. = "$k: $v \ r \ n";
}
}
$res. = "\ r \ n";
if ($this->body) {
$res. = $this->body;
$res. = "\r\n\r\n";
}
return $res;
}
}
HTTP response
Class Sinhttpresponse {
Public $scheme; Agreement
Public $stasus; State, when success is OK
Public $code; Status code, 200 when it's successful.
Public $header; Response header
Public $body; Response body
function __construct () {
$this->header = Array ();
$this->body = null;
}
function SetHeader ($key, $val) {
$this->header[$key] = $val;
}
}
HttpClient
Class Sinhttpclient {
Public $keepcontext = true; Whether to maintain the session
Public $context; Context
Public $request; Request
Public $response; Response
Public $debug = false;
Whether in debug mode,
True to print out the requested content and the same header
function __construct () {
$this->request = new Sinhttprequest ();
$this->response = new Sinhttpresponse ();
$this->context = new Sinhttpcontext ();
$this->timeout = 15; The default timeout is 15s
}
Clears the last Request content
function Clearrequest () {
$this->request->body = ";
$this->request->setheader (' Content-length ', false);
$this->request->setheader (' Content-type ', false);
}
Post method
Data for the request
Simulate form submission for key-value pairs
Other times for data submission, submitted in the form of XML
If you have other needs, please expand your own
Function post ($url, $data = False) {
$this->clearrequest ();
if ($data) {
if (Is_array ($data)) {
$con = Http_build_query ($data);
$this->request->setheader (' Content-type ', ' application/x-www-form-urlencoded ');
} else {
$con = $data;
$this->request->setheader (' Content-type ', ' text/xml; Charset=utf-8 ');
}
$this->request->body = $con;
$this->request->method = "POST";
$this->request->setheader (' Content-length ', strlen ($con));
}
$this->startrequest ($url);
}
Get method
function Get ($url) {
$this->clearrequest ();
$this->request->method = "GET";
$this->startrequest ($url);
}
The method is called internally, without calling directly
function Startrequest ($url) {
$this->request->url = $url;
if ($this->keepcontext) {
If you save the context, set the relevant information
$this->request->setheader (' Referer ', $this->context->refrer);
$cks = $this->context->cookiesstring ();
if (strlen ($cks) > 0)
$this->request->setheader (' Cookie ', $cks);
}
Get Request Content
$reqstring = $this->request->reqstring ();
if ($this->debug)
echo "request:\n$reqstring\n";
try {
$fp = Fsockopen ($this->request->host, $this->request->port, $errno, $errstr, $this->timeout);
} catch (Exception $ex) {
echo $ex->getmessage ();
Exit (0);
}
if ($fp) {
Stream_set_blocking ($fp, true);
Stream_set_timeout ($fp, $this->timeout);
Write Data
Fwrite ($fp, $reqstring);
$status = Stream_get_meta_data ($FP);
if (! $status [' timed_out ']) {//Not timed out
The following loop is used to read the response header
while (!feof ($fp)) {
$h = fgets ($FP);
if ($this->debug)
Echo $h;
if ($h && ($h = = "\ n" | | $h = = "\ n"))
Break
$pos = Strpos ($h, ': ');
if ($pos) {
$k = Strtolower (Trim (substr ($h, 0, $pos));
$v = Trim (substr ($h, $pos + 1));
if ($k = = ' Set-cookie ') {
Update cookies
if ($this->keepcontext) {
$this->context->addcookie (New Sincookie ($v));
}
} else {
Add to the head inside
$this->response->setheader ($k, $v);
}
} else {
First row of data
Parsing the response status
$preg = '/^ (\s*) (\s*) (. *) $/';
Preg_match_all ($preg, $h, $arr);
Isset ($arr [1][0]) & $this->response->scheme = Trim ($arr [1][0]);
Isset ($arr [2][0]) & $this->response->stasus = Trim ($arr [2][0]);
Isset ($arr [3][0]) & $this->response->code = Trim ($arr [3][0]);
}
}
Get Response Body length
$len = (int) $this->response->header[' content-length '];
$res = ";
The following loop reads the body
while (!feof ($fp) && $len > 0) {
$c = Fread ($fp, $len);
$res. = $c;
$len-= strlen ($c);
}
$this->response->body = $res;
}
Close socket
Fclose ($FP);
Save the return to the context maintenance
$this->context->refrer = $url;
}
}
}
Demo
Now let begin test it
$client = new Sinhttpclient (); Create a client
$client->get (' http://www.baidu.com/'); Get
Echo $client->response->body; Echo
?>
|