Curl.php 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. <?php namespace Dever\Helper;
  2. use Dever;
  3. class Curl
  4. {
  5. private $handle;
  6. private $url;
  7. private $get_info = false;
  8. private $log = false;
  9. private $result_header = false;
  10. private $param = array();
  11. private $header = array();
  12. public function load($url, $param = false, $type = '', $json = false, $header = false, $agent = false, $proxy = false, $refer = false)
  13. {
  14. if ($type == 'get_info') {
  15. $this->get_info = true;
  16. $type = 'get';
  17. }
  18. $this->init();
  19. $this->param($param);
  20. $this->setRequest($type);
  21. if ($header) {
  22. $this->setHeader($header);
  23. }
  24. if (!$agent) {
  25. $agent = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36';
  26. }
  27. if ($agent) {
  28. $this->setAgent($agent);
  29. }
  30. if ($proxy) {
  31. $this->setProxy($proxy);
  32. }
  33. if ($refer) {
  34. $this->setRefer($refer);
  35. }
  36. if ($json) {
  37. $this->setJson($param);
  38. } elseif ($type == 'file') {
  39. $this->setFormData($param);
  40. } elseif ($type == 'post' || $type == 'put') {
  41. $this->setForm($param);
  42. } elseif ($param) {
  43. if (strpos($url, '?')) {
  44. $url .= '&';
  45. } else {
  46. $url .= '?';
  47. }
  48. $url .= http_build_query($param);
  49. }
  50. if (strpos($url, '??')) {
  51. $url = str_replace('??', '?', $url);
  52. }
  53. $this->setUrl($url);
  54. return $this;
  55. }
  56. public function log($log)
  57. {
  58. $this->log = $log;
  59. return $this;
  60. }
  61. private function init()
  62. {
  63. if (!$this->handle) {
  64. $this->handle = curl_init();
  65. }
  66. }
  67. private function param(&$param)
  68. {
  69. if ($param && is_array($param) && isset($param[0])) {
  70. $temp = $param;
  71. $param = array();
  72. foreach ($temp as $k => $v) {
  73. if (is_array($v)) {
  74. $param = array_merge($param, $v);
  75. } else {
  76. $param[$k] = $v;
  77. }
  78. }
  79. }
  80. }
  81. public function setStream($callback)
  82. {
  83. curl_setopt($this->handle, CURLOPT_BUFFERSIZE, 16384);
  84. // 检查是否断联,每10秒发送一次心跳
  85. curl_setopt($this->handle,CURLOPT_TCP_KEEPALIVE,1); // 开启
  86. curl_setopt($this->handle,CURLOPT_TCP_KEEPIDLE,10); // 空闲10秒问一次
  87. curl_setopt($this->handle,CURLOPT_TCP_KEEPINTVL,10); // 每10秒问一次
  88. curl_setopt($this->handle, CURLOPT_WRITEFUNCTION, function ($ch, $data) use ($callback) {
  89. call_user_func($callback, $data);
  90. return strlen($data);
  91. });
  92. return $this;
  93. }
  94. public function setRequest($type)
  95. {
  96. if ($type == 'post' || $type == 'file') {
  97. curl_setopt($this->handle, CURLOPT_POST, true);
  98. } elseif ($type == 'put' || $type == 'delete') {
  99. curl_setopt($this->handle, CURLOPT_CUSTOMREQUEST, strtoupper($type));
  100. } else {
  101. curl_setopt($this->handle, CURLOPT_HTTPGET, true);
  102. }
  103. }
  104. public function setHeader($header)
  105. {
  106. if (is_array($header)) {
  107. foreach ($header as $k => $v) {
  108. if (is_string($k)) {
  109. $this->header[] = $k . ':' . $v;
  110. } else {
  111. $this->header[] = $v;
  112. }
  113. }
  114. } else {
  115. $this->header = explode("\n", $header);
  116. }
  117. }
  118. public function setAgent($agent)
  119. {
  120. curl_setopt($this->handle, CURLOPT_USERAGENT, $agent);
  121. }
  122. public function setProxy($proxy)
  123. {
  124. curl_setopt($this->handle, CURLOPT_PROXY, $proxy[0]); //代理服务器地址
  125. curl_setopt($this->handle, CURLOPT_PROXYPORT, $proxy[1]); //代理服务器端口
  126. curl_setopt($this->handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
  127. }
  128. public function setRefer($refer)
  129. {
  130. curl_setopt($this->handle, CURLOPT_REFERER, $refer);
  131. }
  132. public function setJson($param)
  133. {
  134. if (is_array($param)) {
  135. if (isset($param['item_desc'])) {
  136. $param = json_encode($param, JSON_UNESCAPED_UNICODE);
  137. } else {
  138. $param = json_encode($param);
  139. }
  140. }
  141. $header['Content-Type'] = 'application/json';
  142. $header['Content-Length'] = strlen($param);
  143. $this->setHeader($header);
  144. $this->setParam($param);
  145. }
  146. public function setFormData($param)
  147. {
  148. $header['Content-Type'] = 'multipart/form-data';
  149. if (!is_array($param)) {
  150. $param = Dever::json_decode($param);
  151. }
  152. $this->setHeader($header);
  153. $this->setParam($param);
  154. }
  155. public function setForm($param)
  156. {
  157. $header['Content-Type'] = 'application/x-www-form-urlencoded';
  158. if (!is_array($param)) {
  159. $array = Dever::json_decode($param);
  160. if (json_last_error() === JSON_ERROR_NONE) {
  161. $param = $array;
  162. }
  163. }
  164. if (is_array($param)) {
  165. $param = http_build_query($param);
  166. }
  167. $this->setHeader($header);
  168. $this->setParam($param);
  169. }
  170. public function setUrl($url)
  171. {
  172. $this->url = $url;
  173. curl_setopt($this->handle, CURLOPT_URL, $url);
  174. curl_setopt($this->handle, CURLOPT_RETURNTRANSFER, true);
  175. }
  176. public function result($setting = false)
  177. {
  178. try {
  179. if ($setting) {
  180. $this->setting($setting);
  181. }
  182. if ($this->header) {
  183. curl_setopt($this->handle, CURLOPT_HTTPHEADER, $this->header);
  184. }
  185. curl_setopt($this->handle, CURLOPT_HEADER, false);
  186. if ($this->result_header) {
  187. $this->result_header = array();
  188. curl_setopt($this->handle, CURLOPT_HEADERFUNCTION, array($this, 'headerHandler'));
  189. }
  190. if (Dever::shell('debug')) {
  191. curl_setopt($this->handle, CURLINFO_HEADER_OUT, true);
  192. }
  193. curl_setopt($this->handle, CURLOPT_ACCEPT_ENCODING, 'gzip,deflate');
  194. $result = curl_exec($this->handle);
  195. $debug = array();
  196. if (Dever::shell('debug')) {
  197. $debug['request'] = curl_getinfo($this->handle, CURLINFO_HEADER_OUT);
  198. } elseif ($this->get_info) {
  199. $result = curl_getinfo($this->handle);
  200. }
  201. curl_close($this->handle);
  202. $data = $result;
  203. if (!Dever::shell('all') && is_array($data)) {
  204. $data = count($data) . ' records';
  205. }
  206. $debug['url'] = $this->url;
  207. $debug['param'] = $this->param;
  208. $debug['result'] = $data;
  209. if ($this->log) {
  210. Dever::log($debug, 'curl');
  211. }
  212. Dever::debug($debug, 'curl');
  213. if (isset($setting['stream'])) {
  214. exit;
  215. }
  216. return $result;
  217. } catch (\Exception $e) {
  218. curl_close($this->handle);
  219. return 'error';
  220. }
  221. }
  222. public function setting($setting = array())
  223. {
  224. if ($setting) {
  225. $this->init();
  226. foreach ($setting as $k => $v) {
  227. $method = 'set' . ucfirst($k);
  228. $this->$method($v);
  229. }
  230. }
  231. }
  232. public function setVerbose($verbose)
  233. {
  234. curl_setopt($this->handle, CURLOPT_VERBOSE, $verbose);
  235. }
  236. public function setUserPWD($userpwd)
  237. {
  238. curl_setopt($this->handle, CURLOPT_USERPWD, $userpwd);
  239. }
  240. public function setTimeOut($time)
  241. {
  242. curl_setopt($this->handle, CURLOPT_TIMEOUT, $time);
  243. }
  244. public function setCookie($cookie)
  245. {
  246. curl_setopt($this->handle, CURLOPT_COOKIE, $cookie);
  247. }
  248. public function setParam($param)
  249. {
  250. $this->param = $param;
  251. if (is_array($param)) {
  252. $param = http_build_query($param);
  253. }
  254. curl_setopt($this->handle, CURLOPT_POSTFIELDS, $param);
  255. }
  256. public function setEncode($encode)
  257. {
  258. curl_setopt($this->handle, CURLOPT_ENCODING, $encode);
  259. }
  260. public function setIp($ip)
  261. {
  262. $config['CLIENT-IP'] = $ip;
  263. $config['X-FORWARDED-FOR'] = $ip;
  264. $this->setHeader($config);
  265. }
  266. public function setResultHeader($value)
  267. {
  268. $this->result_header = $value;
  269. }
  270. public function header()
  271. {
  272. return $this->result_header;
  273. }
  274. private function headerHandler($curl, $headerLine)
  275. {
  276. $len = strlen($headerLine);
  277. $split = explode(':', $headerLine, 2);
  278. if (count($split) > 1) {
  279. $key = trim($split[0]);
  280. $value = trim($split[1]);
  281. $this->result_header[$key] = $value;
  282. }
  283. return $len;
  284. }
  285. public function resultCookie()
  286. {
  287. $result = $this->result();
  288. list($header, $body) = explode("\r\n\r\n", $result, 2);
  289. preg_match_all("/Set\-Cookie:([^;]*);/", $header, $matches);
  290. $info['cookie'] = substr($matches[1][0], 1);
  291. $info['content'] = $body;
  292. return $info;
  293. }
  294. }