HttpUtil.php 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. <?php
  2. namespace loyalsoft;
  3. /**
  4. * Http辅助类,可以发送请求/接收请求(提取参数)
  5. * @author gwang (email: mail@wanggangzero.cn)
  6. * @copyright 2016-3-12 ©SJZ LoyalSoft Corporation & gwang. All rights reserved.
  7. */
  8. class HttpUtil
  9. {
  10. public static function parseQueryParas($queryStr)
  11. {
  12. $arr = explode('&', $queryStr);
  13. $queryParas = array();
  14. foreach ($arr as $value) {
  15. $paras = explode('=', $value);
  16. $queryParas[$paras[0]] = $paras[1];
  17. }
  18. return $queryParas;
  19. }
  20. /**
  21. * 执行一个 HTTP 请求
  22. *
  23. * @param string $url 执行请求的URL
  24. * @param mixed $params 表单参数, 可以是array, 也可以是经过url编码之后的string
  25. * @param mixed $cookie cookie参数, 可以是array, 也可以是经过拼接的string, 默认array()
  26. * @param mixed $header http请求头, 可以是array, 也可以是经过拼接的string, 默认array()
  27. * @param string $method 请求方法 post / get, 默认='post'
  28. * @param string $protocol http协议类型 http / https, 默认='http'
  29. * @return array 结果数组 {"result":bool,"msg":返回值/curlErrMsg,"errno":curl错误码,"ifno":curlInfo}
  30. */
  31. public static function makeRequest($url, $params, $cookie = array(), #
  32. $header = array(), $method = 'post', $protocol = 'http')
  33. {
  34. $query_string = self::makeQueryString($params);
  35. $cookie_string = self::makeCookieString($cookie);
  36. $ch = curl_init();
  37. if ('GET' == strtoupper($method)) { # Get
  38. curl_setopt($ch, CURLOPT_URL, "$url?$query_string");
  39. } else { # POST
  40. curl_setopt($ch, CURLOPT_URL, $url);
  41. curl_setopt($ch, CURLOPT_POST, 1);
  42. curl_setopt($ch, CURLOPT_POSTFIELDS, $query_string); # postdata
  43. }
  44. curl_setopt($ch, CURLOPT_HEADER, false); # 控制是否返回响应头信息
  45. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  46. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3); # 超时时间
  47. if (is_array($header)) { # http header是个数组,
  48. $header[] = 'Expect:'; # 补充一个'Expect:', 避免出现 100-continue.
  49. } else if (is_string($header)) { # 如果header传过来了一个字符串
  50. $header = array($header, 'Expect:'); # 拼接一个数组
  51. } else { # 其他情况,直接忽略, 覆盖掉
  52. $header = array('Expect:');
  53. }
  54. curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
  55. if (!empty($cookie_string)) {
  56. curl_setopt($ch, CURLOPT_COOKIE, $cookie_string);
  57. }
  58. if ('https' == $protocol or substr($url, 0, 5) == 'https') { # 若为https协议
  59. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); # 若是出错,检查php.ini中curl.cainfo配置
  60. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
  61. }
  62. // curl_setopt($ch, CURLOPT_PROXYPORT, 8888); # 代理,调试用的
  63. // curl_setopt($ch, CURLOPT_PROXY, '127.0.0.1');
  64. $ret = curl_exec($ch);
  65. $err = curl_error($ch);
  66. if (false === $ret || !empty($err)) {
  67. $errno = curl_errno($ch);
  68. $info = curl_getinfo($ch);
  69. curl_close($ch);
  70. return array(
  71. 'result' => false,
  72. 'errno' => $errno,
  73. 'msg' => $err,
  74. 'info' => $info,
  75. );
  76. }
  77. curl_close($ch);
  78. return array(
  79. 'result' => true,
  80. 'msg' => $ret,
  81. );
  82. }
  83. /**
  84. * 从参数构造请求串
  85. * @param type $params 如果是字符串直接返回,(关联)数组或者object(仅取public字段)
  86. * @return string 编码规范-RFC3986
  87. */
  88. public static function makeQueryString($params)
  89. {
  90. if (is_string($params)) {
  91. return $params;
  92. }
  93. return http_build_query($params, "", '&', PHP_QUERY_RFC3986); # 3986
  94. }
  95. /**
  96. * 从参数构造Cookie字符串
  97. * @param type $params 如果是字符串直接返回,(关联)数组或者object(仅取public字段)
  98. * @return string 编码规范-RFC3986
  99. */
  100. public static function makeCookieString($params)
  101. {
  102. if (is_string($params)) {
  103. return $params;
  104. }
  105. return http_build_query($params, "", "; ", PHP_QUERY_RFC3986); # 3986
  106. }
  107. /**
  108. * 取Request过来的Data转为关联数组
  109. * @return array
  110. */
  111. public static function getQueryParas()
  112. {
  113. $param = $_REQUEST;
  114. switch ($_SERVER['REQUEST_METHOD']) {
  115. case 'GET':
  116. $param = $_REQUEST;
  117. break;
  118. case 'POST':
  119. $str = file_get_contents('php://input');
  120. $param = array_merge($param, ( strlen($str) > 0 ? self::parseQueryParas($str) : array()));
  121. break;
  122. default:
  123. }
  124. return $param;
  125. }
  126. /**
  127. * 取Request过来的数据流转为字符串
  128. * @return string
  129. */
  130. public static function getQueryString()
  131. {
  132. $queryStr = null;
  133. switch ($_SERVER['REQUEST_METHOD']) {
  134. case 'GET':
  135. $queryStr = $_SERVER['QUERY_STRING'];
  136. break;
  137. case 'POST':
  138. $queryStr = file_get_contents('php://input');
  139. break;
  140. default:
  141. }
  142. return $queryStr;
  143. }
  144. /**
  145. * 用于确保服务器只响应POST方法.
  146. */
  147. public static function PostOnly()
  148. {
  149. if ($_SERVER['REQUEST_METHOD'] != 'POST') {
  150. header('Allow: POST ', false, 405);
  151. exit();
  152. }
  153. }
  154. /**
  155. * 获取客户端ip地址及端口
  156. * @return ip:port
  157. */
  158. public static function getClientEP()
  159. {
  160. return $_SERVER['REMOTE_ADDR'] . ":" . $_SERVER['REMOTE_PORT'];
  161. }
  162. /**
  163. * 获取客户端IP地址(摘自discuz)
  164. * @return string
  165. */
  166. public static function clientIP()
  167. {
  168. $ip = '未知IP';
  169. if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
  170. return self::is_ip($_SERVER['HTTP_CLIENT_IP']) ? $_SERVER['HTTP_CLIENT_IP'] : $ip;
  171. } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
  172. return self::is_ip($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $ip;
  173. } elseif (!empty($_SERVER['REMOTE_ADDR'])) {
  174. return self::is_ip($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : $ip;
  175. } else {
  176. return $ip;
  177. }
  178. }
  179. private static function is_ip($str)
  180. {
  181. $ip = explode('.', $str);
  182. for ($i = 0; $i < count($ip); $i++) {
  183. if ($ip[$i] > 255) {
  184. return false;
  185. }
  186. }
  187. return preg_match('/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/', $str);
  188. }
  189. }
  190. /**
  191. * 取Request过来的Data转为关联数组
  192. * @return array
  193. */
  194. function query_paras()
  195. {
  196. return HttpUtil::getQueryParas();
  197. }
  198. /**
  199. * 取Request过来的数据流转为字符串
  200. * @return string
  201. */
  202. function query_string()
  203. {
  204. return HttpUtil::getQueryString();
  205. }