PHP封装的HttpClient类用法实例

这篇文章主要介绍了PHP封装的HttpClient类,可实现简单的GET、POST、Cookie、Session等功能,需要的朋友可以参考下。

本文实例讲述了PHP封装的HttpClient类,分享给大家供大家参考,具体分析如下:

这是一段php封装的HttpClient类,可实现GET POST Cookie Session等简单的功能,原来做过,这两天重新修改了一下。

  1. <?php
  2. /*
  3. * Filename: httpclient.php
  4. * Created on 2012-12-21
  5. * Created by RobinTang
  6. * To change the template for this generated file go to
  7. * Window - Preferences - PHPeclipse - PHP - Code Templates
  8. */
  9. class SinCookie {
  10. public $name; // Cookie名称
  11. public $value; // Cookie值
  12. // 下面三个属性现在未实现
  13. public $expires; // 过期时间
  14. public $path; // 路径
  15. public $domain; // 域
  16. // 从Cookie字符串创建一个Cookie对象
  17. function __construct($s = false) {
  18. if ($s) {
  19. $i1 = strpos($s, '=');
  20. $i2 = strpos($s, ';');
  21. $this->name = trim(substr($s, 0, $i1));
  22. $this->value = trim(substr($s, $i1 +1, $i2 - $i1 -1));
  23. }
  24. }
  25. // 获取Cookie键值对
  26. function getKeyValue() {
  27. return "$this->name=$this->value";
  28. }
  29. }
  30. // 会话上下文
  31. class SinHttpContext {
  32. public $cookies; // 会话Cookies
  33. public $referer; // 前一个页面地址
  34. function __construct() {
  35. $this->cookies = array ();
  36. $this->refrer = "";
  37. }
  38. // 设置Cookie
  39. function cookie($key, $val) {
  40. $ck = new SinCookie();
  41. $ck->name = $key;
  42. $ck->value = $val;
  43. $this->addCookie($ck);
  44. }
  45. // 添加Cookie
  46. function addCookie($ck) {
  47. $this->cookies[$ck->name] = $ck;
  48. }
  49. // 获取Cookies字串,请求时用到
  50. function cookiesString() {
  51. $res = '';
  52. foreach ($this->cookies as $ck) {
  53. $res .= $ck->getKeyValue() . ';';
  54. }
  55. return $res;
  56. }
  57. }
  58. // Http请求对象
  59. class SinHttpRequest {
  60. public $url; // 请求地址
  61. public $method = 'GET'; // 请求方法
  62. public $host; // 主机
  63. public $path; // 路径
  64. public $scheme; // 协议,http
  65. public $port; // 端口
  66. public $header; // 请求头
  67. public $body; // 请求正文
  68. // 设置头
  69. function setHeader($k, $v) {
  70. if (!isset ($this->header)) {
  71. $this->header = array ();
  72. }
  73. $this->header[$k] = $v;
  74. }
  75. // 获取请求字符串
  76. // 包含头和请求正文
  77. // 获取之后直接写socket就行
  78. function reqString() {
  79. $matches = parse_url($this->url);
  80. !isset ($matches['host']) && $matches['host'] = '';
  81. !isset ($matches['path']) && $matches['path'] = '';
  82. !isset ($matches['query']) && $matches['query'] = '';
  83. !isset ($matches['port']) && $matches['port'] = '';
  84. $host = $matches['host'];
  85. $path = $matches['path'] ? $matches['path'] . ($matches['query'] ? '?' . $matches['query'] : '') : '/';
  86. $port = !emptyempty ($matches['port']) ? $matches['port'] : 80;
  87. $scheme = $matches['scheme'] ? $matches['scheme'] : 'http';
  88. $this->host = $host;
  89. $this->path = $path;
  90. $this->scheme = $scheme;
  91. $this->port = $port;
  92. $method = strtoupper($this->method);
  93. $res = "$method $path HTTP/1.1\r\n";
  94. $res .= "Host: $host\r\n";
  95. if ($this->header) {
  96. reset($this->header);
  97. while (list ($k, $v) = each($this->header)) {
  98. if (isset ($v) && strlen($v) > 0)
  99. $res .= "$k: $v\r\n";
  100. }
  101. }
  102. $res .= "\r\n";
  103. if ($this->body) {
  104. $res .= $this->body;
  105. $res .= "\r\n\r\n";
  106. }
  107. return $res;
  108. }
  109. }
  110. // Http响应
  111. class SinHttpResponse {
  112. public $scheme; // 协议
  113. public $stasus; // 状态,成功的时候是ok
  114. public $code; // 状态码,成功的时候是200
  115. public $header; // 响应头
  116. public $body; // 响应正文
  117. function __construct() {
  118. $this->header = array ();
  119. $this->body = null;
  120. }
  121. function setHeader($key, $val) {
  122. $this->header[$key] = $val;
  123. }
  124. }
  125. // HttpClient
  126. class SinHttpClient {
  127. public $keepcontext = true; // 是否维持会话
  128. public $context; // 上下文
  129. public $request; // 请求
  130. public $response; // 响应
  131. public $debug = false;
  132. // 是否在Debug模式,
  133. //为true的时候会打印出请求内容和相同的头部
  134. function __construct() {
  135. $this->request = new SinHttpRequest();
  136. $this->response = new SinHttpResponse();
  137. $this->context = new SinHttpContext();
  138. $this->timeout = 15; // 默认的超时为15s
  139. }
  140. // 清除上一次的请求内容
  141. function clearRequest() {
  142. $this->request->body = '';
  143. $this->request->setHeader('Content-Length', false);
  144. $this->request->setHeader('Content-Type', false);
  145. }
  146. // post方法
  147. // data为请求的数据
  148. // 为键值对的时候模拟表单提交
  149. // 其他时候为数据提交,提交的形式为xml
  150. // 如有其他需求,请自行扩展
  151. function post($url, $data = false) {
  152. $this->clearRequest();
  153. if ($data) {
  154. if (is_array($data)) {
  155. $con = http_build_query($data);
  156. $this->request->setHeader('Content-Type', 'application/x-www-form-urlencoded');
  157. } else {
  158. $con = $data;
  159. $this->request->setHeader('Content-Type', 'text/xml; charset=utf-8');
  160. }
  161. $this->request->body = $con;
  162. $this->request->method = "POST";
  163. $this->request->setHeader('Content-Length', strlen($con));
  164. }
  165. $this->startRequest($url);
  166. }
  167. // get方法
  168. function get($url) {
  169. $this->clearRequest();
  170. $this->request->method = "GET";
  171. $this->startRequest($url);
  172. }
  173. // 该方法为内部调用方法,不用直接调用
  174. function startRequest($url) {
  175. $this->request->url = $url;
  176. if ($this->keepcontext) {
  177. // 如果保存上下文的话设置相关信息
  178. $this->request->setHeader('Referer', $this->context->refrer);
  179. $cks = $this->context->cookiesString();
  180. if (strlen($cks) > 0)
  181. $this->request->setHeader('Cookie', $cks);
  182. }
  183. // 获取请求内容
  184. $reqstring = $this->request->reqString();
  185. if ($this->debug)
  186. echo "Request:\n$reqstring\n";
  187. try {
  188. $fp = fsockopen($this->request->host, $this->request->port, $errno, $errstr, $this->timeout);
  189. } catch (Exception $ex) {
  190. echo $ex->getMessage();
  191. exit (0);
  192. }
  193. if ($fp) {
  194. stream_set_blocking($fp, true);
  195. stream_set_timeout($fp, $this->timeout);
  196. // 写数据
  197. fwrite($fp, $reqstring);
  198. $status = stream_get_meta_data($fp);
  199. if (!$status['timed_out']) { //未超时
  200. // 下面的循环用来读取响应头部
  201. while (!feof($fp)) {
  202. $h = fgets($fp);
  203. if ($this->debug)
  204. echo $h;
  205. if ($h && ($h == "\r\n" || $h == "\n"))
  206. break;
  207. $pos = strpos($h, ':');
  208. if ($pos) {
  209. $k = strtolower(trim(substr($h, 0, $pos)));
  210. $v = trim(substr($h, $pos +1));
  211. if ($k == 'set-cookie') {
  212. // 更新Cookie
  213. if ($this->keepcontext) {
  214. $this->context->addCookie(new SinCookie($v));
  215. }
  216. } else {
  217. // 添加到头里面去
  218. $this->response->setHeader($k, $v);
  219. }
  220. } else {
  221. // 第一行数据
  222. // 解析响应状态
  223. $preg = '/^(\S*) (\S*) (.*)$/';
  224. preg_match_all($preg, $h, $arr);
  225. isset ($arr[1][0]) & $this->response->scheme = trim($arr[1][0]);
  226. isset ($arr[2][0]) & $this->response->stasus = trim($arr[2][0]);
  227. isset ($arr[3][0]) & $this->response->code = trim($arr[3][0]);
  228. }
  229. }
  230. // 获取响应正文长度
  231. $len = (int) $this->response->header['content-length'];
  232. $res = '';
  233. // 下面的循环读取正文
  234. while (!feof($fp) && $len > 0) {
  235. $c = fread($fp, $len);
  236. $res .= $c;
  237. $len -= strlen($c);
  238. }
  239. $this->response->body = $res;
  240. }
  241. // 关闭Socket
  242. fclose($fp);
  243. // 把返回保存到上下文维持中
  244. $this->context->refrer = $url;
  245. }
  246. }
  247. }
  248. // demo
  249. // now let begin test it
  250. $client = new SinHttpClient(); // create a client
  251. $client->get('http://www.baidu.com/'); // get
  252. echo $client->response->body; // echo
  253. ?>