HttpUtil.php 7.7 KB

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