[关闭]
@xxliixin1993 2015-12-09T15:08:47.000000Z 字数 4128 阅读 1951

php socket

php


socket流程图

Created with Raphaël 2.1.2fsockopen() 创建socketfwrite() 把http请求头写入socketfread() 读取响应

简单例子(模拟GET请求):

  1. <?php
  2. $url = "http://jk.campus.fang.com/GetPositionList_V1.api?returntype=2";
  3. print_r(parse_url($url));
  4. //把url拆分成数组
  5. $info = parse_url($url);
  6. //获取socket句柄
  7. $fp = fsockopen($info['host'], 80, $errno, $errstr, 10);
  8. //超时时间设置
  9. stream_set_timeout($fp, 10);
  10. $head = "GET ". $info['path'] .'?'. $info['query'] ." HTTP/1.0 \r\n";
  11. $head .= "Host: ".$info['host']."\r\n";
  12. $head .= "Content-Type: application/x-www-form-urlencoded\r\n";
  13. $head .= "\r\n";
  14. //向socket中写http请求头
  15. $write = fwrite($fp, $head);
  16. while (!feof($fp))
  17. {
  18. //读出http响应
  19. $content = fread($fp,409600);
  20. echo $content;
  21. }

封装套接字类:

  1. class HttpSocket {
  2. public $host;//主机名
  3. public $path;//请求文件
  4. public $query;//请求参数和值
  5. public $timeout; //超时时间 单位s
  6. public $port; //端口
  7. public $response;//响应内容
  8. /**
  9. * @param string $url 类似http://jk.campus.fang.com/GetPositionList_V1.api?returntype=2 必须要有http://
  10. * @param int $timeout 超时时间 单位s
  11. */
  12. public function __construct($url, $timeout, $port=80){
  13. //拆分url
  14. $info = parse_url($url);
  15. $this->host = $info['host'];
  16. $this->path = $info['path'];
  17. $this->query = $info['query'];
  18. $this->timeout = $timeout;
  19. $this->port = $port;
  20. }
  21. /**
  22. * 模拟GET请求
  23. * @param string $request http请求头
  24. * @return void
  25. */
  26. public function getMethod($request=''){
  27. $fp = fsockopen($this->host, $this->port, $errno, $errstr, 10);
  28. //超时时间设置
  29. stream_set_timeout($fp, $this->timeout);
  30. if (!empty($this->path) && !empty($this->query)) {
  31. $head = "GET ". $this->path .'?'. $this->query ." HTTP/1.0 \r\n";
  32. } else if (!empty($this->path) && empty($this->query)) {
  33. $head = "GET ". $this->path ." HTTP/1.0 \r\n";
  34. }
  35. $head .= "Host: ".$this->host."\r\n";
  36. $head .= "Content-Type: application/x-www-form-urlencoded\r\n";
  37. //$head .= "Accept-Encoding: compress\r\n";
  38. $head .= "Connection: Close\r\n";
  39. if (!empty($request)) {
  40. $head .= $request;
  41. }
  42. $head .= "\r\n";
  43. //向socket中写http请求头
  44. fwrite($fp, $head);
  45. while (!feof($fp)){
  46. $this->response .= fread($fp,409600);
  47. //从封装协议文件指针中取得报头
  48. $info = stream_get_meta_data($fp);//print_r($info);exit;
  49. if ($info['timed_out']) {
  50. echo "time out";
  51. @fclose($this->fp);
  52. return false;
  53. }
  54. }
  55. fclose($fp);
  56. print_r($this->response);exit;
  57. }
  58. /**
  59. * 处理得到响应body
  60. */
  61. public function getResponseBody($response = ''){
  62. if (!empty($response)) {
  63. $this->response = $response;
  64. }
  65. //因为在http响应头最后是\r\n\r\n,而且只有一个
  66. $tmp = split("\r\n\r\n" , $this->response); //print_r($this->response);exit;
  67. if (is_array($tmp) && count($tmp) > 1) {
  68. //当有多个\r\n时
  69. for ($i=1; $i<count($tmp); $i++) {
  70. $responseBody .= $tmp[$i] . "\r\n";
  71. }
  72. } else {
  73. $responseBody = $tmp[0];
  74. }
  75. //echo $responseBody;exit;
  76. //TODO根据响应头,检查处理Content-Type,Content-Encoding等
  77. return $responseBody;
  78. }
  79. /**
  80. * 获取响应头信息
  81. */
  82. public function getResponseHeader($response = ''){
  83. if (!empty($response)) {
  84. $this->response = $response;
  85. }
  86. //因为在http响应头最后是\r\n\r\n,而且只有一个
  87. $content = strstr($this->response, "\r\n\r\n");
  88. //取出响应头部信息
  89. $header = substr($this->response, 0, strlen($this->response)-strlen($content));
  90. //把响应头转换成数组
  91. $header = explode("\r\n", $header);
  92. return $header;
  93. }
  94. }
  95. //测试使用
  96. $url = "http://jk.campus.fang.com/GetPositionList_V1.api?returntype=2";//返回xml
  97. $url = 'http://jk.campus.fang.com/GetPositionList_V1.api';//返回json
  98. //$url ='http://jk.ask.fang.com/Interface/GetHotTagsForHome.aspx';
  99. //实例化HttpSocket类 并传入url和设置超时时常
  100. $socket = new HttpSocket($url, 10);
  101. //调用getMethod去模拟GET请求
  102. $socket->getMethod();
  103. //获取响应body
  104. $body = $socket->getResponseBody();
  105. print_r($body);exit;

输出信息

  1. {"ServerTime":"2015-11-18 09:26:00","Message":"","Content":{"Item":[{"ID":"3q8ldj32jg0g0000f8a7aff7c4834307","Name":"电商特种兵:电商营销\t\/营销支持","CreateTime":"2015-09-29 17:51:08","Classify":"1"},{"ID":"3q8ldklkqov00000e56ff68d63b74d90","Name":"产品技术类(北京):产品\/工程师\/设计师","CreateTime":"2015-09-29 17:51:26","Classify":"1"},{"ID":"3q8ldlokbqk00000ea5e817e206343c4","Name":"运营支持类:分析师\/编辑\/策划","CreateTime":"2015-09-29 17:51:38","Classify":"1"},{"ID":"3q8ldmsm42u000007720fc2f875e44c3","Name":"职能管理类:财务\/人事\/行政","CreateTime":"2015-09-29 17:51:51","Classify":"1"},{"ID":"c78hc08du6c0000fc2582111ef3457da","Name":"电商特种兵:电商营销\t\/营销支持","CreateTime":"2015-09-29 17:52:04","Classify":"2"},{"ID":"c78hc58k0b40000d5deac4ed6de469db","Name":"产品技术类(北京):产品\/工程师\/设计师","CreateTime":"2015-09-29 17:52:22","Classify":"2"},{"ID":"c78hc80n2js00004e6a3e7e64774196a","Name":"运营支持类:分析师\/编辑\/策划","CreateTime":"2015-09-29 17:52:32","Classify":"2"},{"ID":"c78hcb7v6880000aab38688a977428e9","Name":"职能管理类:财务\/人事\/行政","CreateTime":"2015-09-29 17:52:43","Classify":"2"}]}}
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注