You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

213 lines
6.6 KiB

  1. <?php
  2. namespace Kuxin\Helper;
  3. use Kuxin\Config;
  4. use Kuxin\Log;
  5. /**
  6. * Class Http
  7. *
  8. * @package Kuxin\Helper
  9. * @author Pakey <pakey@qq.com>
  10. */
  11. class Http
  12. {
  13. /**
  14. * @param $url
  15. * @param array $params
  16. * @param string $method
  17. * @param array $header
  18. * @param array $option
  19. * @return bool|mixed
  20. */
  21. public static function curl($url, $params = [], $method = 'GET', $header = [], $option = [])
  22. {
  23. $opts = [
  24. CURLOPT_TIMEOUT => Config::get('http.timeout', 15),
  25. CURLOPT_CONNECTTIMEOUT => Config::get('http.timeout', 15),
  26. CURLOPT_RETURNTRANSFER => 1,
  27. CURLOPT_FOLLOWLOCATION => 1,
  28. CURLOPT_HEADER => 0,
  29. //CURLOPT_FILETIME => true,
  30. //CURLOPT_FRESH_CONNECT => false,
  31. //CURLOPT_MAXREDIRS => 5,
  32. CURLOPT_USERAGENT => Config::get('http.user_agent', 'PTCMS Framework Http Client'),
  33. CURLOPT_REFERER => isset($header['referer']) ? $header['referer'] : $url,
  34. CURLOPT_NOSIGNAL => 1,
  35. CURLOPT_ENCODING => 'gzip, deflate',
  36. CURLOPT_SSL_VERIFYPEER => false,
  37. CURLOPT_SSL_VERIFYHOST => false,
  38. ];
  39. if (Config::get('http.proxy.power')) {
  40. $opts[CURLOPT_PROXY] = Config::get('http.proxy.host');
  41. $opts[CURLOPT_PROXYPORT] = Config::get('http.proxy.port');
  42. $opts[CURLOPT_PROXYTYPE] = Config::get('http.proxy.type');
  43. if (!empty($user = Config::get('http.proxy.username')) && !empty($pwd = Config::get('http.proxy.password'))) {
  44. $opts[CURLOPT_PROXYUSERPWD] = "{$user}:{$pwd}";
  45. }
  46. }
  47. if (isset($header['cookie'])) {
  48. $opts[CURLOPT_COOKIE] = $header['cookie'];
  49. unset($header['cookie']);
  50. }
  51. if (isset($header['useragent'])) {
  52. $opts[CURLOPT_USERAGENT] = $header['useragent'];
  53. unset($header['useragent']);
  54. }
  55. if (isset($header['showheader'])) {
  56. $opts[CURLOPT_HEADER] = true;
  57. unset($header['showheader']);
  58. }
  59. if (!empty($header)) {
  60. foreach ($header as $key => $item) {
  61. $opts[CURLOPT_HTTPHEADER][] = $key . ': ' . $item;
  62. }
  63. }
  64. //补充配置
  65. foreach ($option as $k => $v) {
  66. $opts[$k] = $v;
  67. }
  68. $opts[CURLOPT_URL] = $url;
  69. /* 根据请求类型设置特定参数 */
  70. switch (strtoupper($method)) {
  71. case 'GET':
  72. if ($params) {
  73. if (is_array($params)) {
  74. $params = http_build_query($params);
  75. }
  76. if (strpos($url, '?')) {
  77. $url .= '&' . $params;
  78. } else {
  79. $url .= '?' . $params;
  80. }
  81. $opts[CURLOPT_URL] = $url;
  82. }
  83. break;
  84. case 'POST':
  85. //判断是否传输文件
  86. $opts[CURLOPT_POST] = 1;
  87. $opts[CURLOPT_POSTFIELDS] = $params;
  88. break;
  89. case 'PUT':
  90. $opts[CURLOPT_CUSTOMREQUEST] = 'PUT';
  91. $opts[CURLOPT_POSTFIELDS] = $params;
  92. break;
  93. case 'HEAD':
  94. $opts[CURLOPT_CUSTOMREQUEST] = 'HEAD';
  95. $opts[CURLOPT_NOBODY] = 1;
  96. break;
  97. case 'DELETE':
  98. $opts[CURLOPT_CUSTOMREQUEST] = 'DELETE';
  99. $opts[CURLOPT_POSTFIELDS] = $params;
  100. break;
  101. default:
  102. exit('不支持的请求方式!');
  103. }
  104. /* 初始化并执行curl请求 */
  105. $ch = curl_init();
  106. curl_setopt_array($ch, $opts);
  107. $data = curl_exec($ch);
  108. $error = curl_error($ch);
  109. $errno = curl_errno($ch);
  110. curl_close($ch);
  111. if ($error && $errno !== 28) {
  112. if (Config::get('app.debug')) {
  113. trigger_error('Curl获取远程内容错误!原因:' . $error . ' 地址:' . $url);
  114. } else {
  115. Log::record('Curl获取远程内容错误!原因:' . $error . ' 地址:' . $url);
  116. }
  117. return false;
  118. }
  119. return $data;
  120. }
  121. public static function get($url, $data = [], $header = [], $option = [])
  122. {
  123. return self::curl($url, $data, 'GET', $header, $option);
  124. }
  125. public static function post($url, $data = [], $header = [], $option = [])
  126. {
  127. return self::curl($url, $data, 'POST', $header, $option);
  128. }
  129. public static function getJson($url, $data = [])
  130. {
  131. return Json::decode(trim(self::curl($url, $data, 'GET')));
  132. }
  133. public static function postJson($url, $data = [], $header = [])
  134. {
  135. return Json::decode(trim(self::curl($url, $data, 'POST', $header)));
  136. }
  137. /**
  138. * 触发url
  139. *
  140. * @param $url
  141. */
  142. public static function trigger($url)
  143. {
  144. if (stripos($url, 'http') === 0) {
  145. if (defined('CURLOPT_TIMEOUT_MS')) {
  146. self::curl($url, [], 'GET', [], [
  147. CURLOPT_TIMEOUT_MS => 300,
  148. CURLOPT_CONNECTTIMEOUT_MS => 300,
  149. ]);
  150. } elseif (function_exists('file_get_contents')) {
  151. $context = [
  152. 'http' => [
  153. 'timeout' => 0,
  154. ],
  155. ];
  156. $stream_context = stream_context_create($context);
  157. file_get_contents($url, false, $stream_context);
  158. } else {
  159. stream_context_set_default(
  160. [
  161. 'http' => [
  162. 'method' => 'HEAD',
  163. ],
  164. ]
  165. );
  166. get_headers($url);
  167. }
  168. }
  169. }
  170. /**
  171. * 解析头部内容
  172. * @param $response
  173. * @return array
  174. */
  175. public static function parse_headers($response)
  176. {
  177. $result = [];
  178. $headers = explode("\r\n\r\n", $response, 2)[0];
  179. $headers = explode("\n", $headers);
  180. array_shift($headers);
  181. foreach ($headers as $header) {
  182. list($key, $value) = explode(':', $header, 2);
  183. $result[strtolower($key)] = trim($value);
  184. }
  185. return $result;
  186. }
  187. /**
  188. * 解析内容
  189. * @param $response
  190. * @return array
  191. */
  192. public static function parse_content($response)
  193. {
  194. return explode("\r\n\r\n", $response, 2)[1];
  195. }
  196. }