Http.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // |
  4. // +----------------------------------------------------------------------
  5. // |
  6. // +----------------------------------------------------------------------
  7. // |
  8. // +----------------------------------------------------------------------
  9. // |
  10. // +----------------------------------------------------------------------
  11. // | Original reference: https://gitee.com/karson/fastadmin
  12. // +----------------------------------------------------------------------
  13. // +----------------------------------------------------------------------
  14. // | 字符串类
  15. // +----------------------------------------------------------------------
  16. namespace util;
  17. class Http
  18. {
  19. /**
  20. * 发送一个POST请求
  21. * @param string $url 请求URL
  22. * @param array $params 请求参数
  23. * @param array $options 扩展参数
  24. * @return mixed|string
  25. */
  26. public static function post(string $url, $params = [], $options = [])
  27. {
  28. $req = self::sendRequest($url, $params, 'POST', $options);
  29. return $req['ret'] ? $req['msg'] : '';
  30. }
  31. /**
  32. * 发送一个GET请求
  33. * @param string $url 请求URL
  34. * @param array $params 请求参数
  35. * @param array $options 扩展参数
  36. * @return mixed|string
  37. */
  38. public static function get(string $url, $params = [], $options = [])
  39. {
  40. $req = self::sendRequest($url, $params, 'GET', $options);
  41. return $req['ret'] ? $req['msg'] : '';
  42. }
  43. /**
  44. * CURL发送Request请求,含POST和REQUEST
  45. * @param string $url 请求的链接
  46. * @param mixed $params 传递的参数
  47. * @param string $method 请求的方法
  48. * @param mixed $options CURL的参数
  49. * @return array
  50. */
  51. public static function sendRequest(string $url, $params = [], string $method = 'POST', $options = [])
  52. {
  53. $method = strtoupper($method);
  54. $protocol = substr($url, 0, 5);
  55. $query_string = is_array($params) ? http_build_query($params) : $params;
  56. $ch = curl_init();
  57. $defaults = [];
  58. if ('GET' == $method) {
  59. $geturl = $query_string ? $url . (stripos($url, "?") !== false ? "&" : "?") . $query_string : $url;
  60. $defaults[CURLOPT_URL] = $geturl;
  61. } else {
  62. $defaults[CURLOPT_URL] = $url;
  63. if ($method == 'POST') {
  64. $defaults[CURLOPT_POST] = 1;
  65. } else {
  66. $defaults[CURLOPT_CUSTOMREQUEST] = $method;
  67. }
  68. $defaults[CURLOPT_POSTFIELDS] = is_array($params) && count(array_filter($params, 'is_array')) > 0 ? $query_string : $params;
  69. }
  70. $defaults[CURLOPT_HEADER] = false;
  71. $defaults[CURLOPT_USERAGENT] = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.98 Safari/537.36";
  72. $defaults[CURLOPT_FOLLOWLOCATION] = true;
  73. $defaults[CURLOPT_RETURNTRANSFER] = true;
  74. $defaults[CURLOPT_CONNECTTIMEOUT] = 10;
  75. $defaults[CURLOPT_TIMEOUT] = 10;
  76. // disable 100-continue
  77. curl_setopt($ch, CURLOPT_HTTPHEADER, ['Expect:']);
  78. if ('https' == $protocol) {
  79. $defaults[CURLOPT_SSL_VERIFYPEER] = false;
  80. $defaults[CURLOPT_SSL_VERIFYHOST] = false;
  81. }
  82. curl_setopt_array($ch, (array) $options + $defaults);
  83. $ret = curl_exec($ch);
  84. $err = curl_error($ch);
  85. if (false === $ret || !empty($err)) {
  86. $errno = curl_errno($ch);
  87. $info = curl_getinfo($ch);
  88. curl_close($ch);
  89. return [
  90. 'ret' => false,
  91. 'errno' => $errno,
  92. 'msg' => $err,
  93. 'info' => $info,
  94. ];
  95. }
  96. curl_close($ch);
  97. return [
  98. 'ret' => true,
  99. 'msg' => $ret,
  100. ];
  101. }
  102. /**
  103. * 异步发送一个请求
  104. * @param string $url 请求的链接
  105. * @param mixed $params 请求的参数
  106. * @param string $method 请求的方法
  107. * @return boolean TRUE
  108. */
  109. public static function sendAsyncRequest(string $url, $params = [], $method = 'POST')
  110. {
  111. $method = strtoupper($method);
  112. $method = $method == 'POST' ? 'POST' : 'GET';
  113. //构造传递的参数
  114. if (is_array($params)) {
  115. $post_params = [];
  116. foreach ($params as $k => &$v) {
  117. if (is_array($v)) {
  118. $v = implode(',', $v);
  119. }
  120. $post_params[] = $k . '=' . urlencode($v);
  121. }
  122. $post_string = implode('&', $post_params);
  123. } else {
  124. $post_string = $params;
  125. }
  126. $parts = parse_url($url);
  127. //构造查询的参数
  128. if ($method == 'GET' && $post_string) {
  129. $parts['query'] = isset($parts['query']) ? $parts['query'] . '&' . $post_string : $post_string;
  130. $post_string = '';
  131. }
  132. $parts['query'] = isset($parts['query']) && $parts['query'] ? '?' . $parts['query'] : '';
  133. //发送socket请求,获得连接句柄
  134. $fp = fsockopen($parts['host'], $parts['port'] ?? 80, $errno, $errstr, 10);
  135. if (!$fp) {
  136. return false;
  137. }
  138. //设置超时时间
  139. stream_set_timeout($fp, 10);
  140. $out = "{$method} {$parts['path']}{$parts['query']} HTTP/1.1\r\n";
  141. $out .= "Host: {$parts['host']}\r\n";
  142. $out .= "Content-Type: application/x-www-form-urlencoded\r\n";
  143. $out .= "Content-Length: " . strlen($post_string) . "\r\n";
  144. $out .= "Connection: Close\r\n\r\n";
  145. if ($post_string !== '') {
  146. $out .= $post_string;
  147. }
  148. fwrite($fp, $out);
  149. //不用关心服务器返回结果
  150. //echo fread($fp, 1024);
  151. fclose($fp);
  152. return true;
  153. }
  154. /**
  155. * 发送文件到客户端
  156. * @param string $file
  157. * @param bool $delaftersend
  158. * @param bool $exitaftersend
  159. */
  160. public static function sendToBrowser(string $file, bool $delaftersend = true, bool $exitaftersend = true): void
  161. {
  162. if (file_exists($file) && is_readable($file)) {
  163. header('Content-Description: File Transfer');
  164. header('Content-Type: application/octet-stream');
  165. header('Content-Disposition: attachment;filename = ' . basename($file));
  166. header('Content-Transfer-Encoding: binary');
  167. header('Expires: 0');
  168. header('Cache-Control: must-revalidate, post-check = 0, pre-check = 0');
  169. header('Pragma: public');
  170. header('Content-Length: ' . filesize($file));
  171. ob_clean();
  172. flush();
  173. readfile($file);
  174. if ($delaftersend) {
  175. unlink($file);
  176. }
  177. if ($exitaftersend) {
  178. exit;
  179. }
  180. }
  181. }
  182. }