HttpUtil.php 7.6 KB

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