Total Complexity | 130 |
Total Lines | 938 |
Duplicated Lines | 0 % |
Changes | 0 |
Complex classes like requests often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use requests, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
59 | class requests |
||
60 | { |
||
61 | const VERSION = '2.0.1'; |
||
62 | |||
63 | protected static $ch = null; |
||
64 | |||
65 | /**** Public variables ****/ |
||
66 | |||
67 | /* user definable vars */ |
||
68 | |||
69 | public static $timeout = 15; |
||
70 | public static $encoding = null; |
||
71 | public static $input_encoding = null; |
||
72 | public static $output_encoding = null; |
||
73 | public static $cookies = array(); // array of cookies to pass |
||
74 | // $cookies['username'] = "seatle"; |
||
75 | public static $rawheaders = array(); // array of raw headers to send |
||
76 | public static $domain_cookies = array(); // array of cookies for domain to pass |
||
77 | public static $hosts = array(); // random host binding for make request faster |
||
78 | public static $headers = array(); // headers returned from server sent here |
||
79 | public static $useragents = array("requests/2.0.0"); // random agent we masquerade as |
||
80 | public static $client_ips = array(); // random ip we masquerade as |
||
81 | public static $proxies = array(); // random proxy ip |
||
82 | public static $raw = ""; // head + body content returned from server sent here |
||
83 | public static $head = ""; // head content |
||
84 | public static $content = ""; // The body before encoding |
||
85 | public static $text = ""; // The body after encoding |
||
86 | public static $info = array(); // curl info |
||
87 | public static $history = 302; // http request status before redirect. ex:30x |
||
88 | public static $status_code = 0; // http request status |
||
89 | public static $error = ""; // error messages sent here |
||
90 | |||
91 | /** |
||
92 | * set timeout |
||
93 | * $timeout 为数组时会分别设置connect和read |
||
94 | * |
||
95 | * @param init or array $timeout |
||
|
|||
96 | * @return |
||
97 | */ |
||
98 | public static function set_timeout($timeout) |
||
99 | { |
||
100 | self::$timeout = $timeout; |
||
101 | } |
||
102 | |||
103 | /** |
||
104 | * 设置代理 |
||
105 | * 如果代理有多个,请求时会随机使用 |
||
106 | * |
||
107 | * @param mixed $proxies |
||
108 | * array ( |
||
109 | * 'socks5://user1:pass2@host:port', |
||
110 | * 'socks5://user2:pass2@host:port' |
||
111 | *) |
||
112 | * @return void |
||
113 | * @author seatle <[email protected]> |
||
114 | * @created time :2016-09-18 10:17 |
||
115 | */ |
||
116 | public static function set_proxy($proxy) |
||
117 | { |
||
118 | self::$proxies = is_array($proxy) ? $proxy : array($proxy); |
||
119 | } |
||
120 | |||
121 | /** |
||
122 | * 删除代理 |
||
123 | * 因为每个链接信息里面都有代理信息,有的链接需要,有的不需要,所以必须提供一个删除功能 |
||
124 | * |
||
125 | * @return void |
||
126 | * @author seatle <[email protected]> |
||
127 | * @created time :2018-07-16 17:59 |
||
128 | */ |
||
129 | public static function del_proxy() |
||
130 | { |
||
131 | self::$proxies = array(); |
||
132 | } |
||
133 | |||
134 | /** |
||
135 | * 自定义请求头部 |
||
136 | * 请求头内容可以用 requests::$rawheaders 来获取 |
||
137 | * 比如获取Content-Type:requests::$rawheaders['Content-Type'] |
||
138 | * |
||
139 | * @param string $headers |
||
140 | * @return void |
||
141 | */ |
||
142 | public static function set_header($key, $value) |
||
143 | { |
||
144 | self::$rawheaders[$key] = $value; |
||
145 | } |
||
146 | |||
147 | /** |
||
148 | * 设置全局COOKIE |
||
149 | * |
||
150 | * @param string $cookie |
||
151 | * @return void |
||
152 | */ |
||
153 | public static function set_cookie($key, $value, $domain = '') |
||
154 | { |
||
155 | if (empty($key)) |
||
156 | { |
||
157 | return false; |
||
158 | } |
||
159 | if (!empty($domain)) |
||
160 | { |
||
161 | self::$domain_cookies[$domain][$key] = $value; |
||
162 | } |
||
163 | else |
||
164 | { |
||
165 | self::$cookies[$key] = $value; |
||
166 | } |
||
167 | return true; |
||
168 | } |
||
169 | |||
170 | /** |
||
171 | * 批量设置全局cookie |
||
172 | * |
||
173 | * @param mixed $cookies |
||
174 | * @param string $domain |
||
175 | * @return void |
||
176 | * @author seatle <[email protected]> |
||
177 | * @created time :2017-08-03 18:06 |
||
178 | */ |
||
179 | public static function set_cookies($cookies, $domain = '') |
||
180 | { |
||
181 | $cookies_arr = explode(';', $cookies); |
||
182 | if (empty($cookies_arr)) |
||
183 | { |
||
184 | return false; |
||
185 | } |
||
186 | |||
187 | foreach ($cookies_arr as $cookie) |
||
188 | { |
||
189 | $cookie_arr = explode('=', $cookie, 2); |
||
190 | $key = $cookie_arr[0]; |
||
191 | $value = empty($cookie_arr[1]) ? '' : $cookie_arr[1]; |
||
192 | |||
193 | if (!empty($domain)) |
||
194 | { |
||
195 | self::$domain_cookies[$domain][$key] = $value; |
||
196 | } |
||
197 | else |
||
198 | { |
||
199 | self::$cookies[$key] = $value; |
||
200 | } |
||
201 | } |
||
202 | return true; |
||
203 | } |
||
204 | |||
205 | /** |
||
206 | * 获取单一Cookie |
||
207 | * |
||
208 | * @param mixed $name cookie名称 |
||
209 | * @param string $domain 不传则取全局cookie,就是手动set_cookie的cookie |
||
210 | * @return void |
||
211 | * @author seatle <[email protected]> |
||
212 | * @created time :2017-08-03 18:06 |
||
213 | */ |
||
214 | public static function get_cookie($name, $domain = '') |
||
215 | { |
||
216 | if (!empty($domain) && !isset(self::$domain_cookies[$domain])) |
||
217 | { |
||
218 | return ''; |
||
219 | } |
||
220 | $cookies = empty($domain) ? self::$cookies : self::$domain_cookies[$domain]; |
||
221 | return isset($cookies[$name]) ? $cookies[$name] : ''; |
||
222 | } |
||
223 | |||
224 | /** |
||
225 | * 获取Cookie数组 |
||
226 | * |
||
227 | * @param string $domain 不传则取全局cookie,就是手动set_cookie的cookie |
||
228 | * @return void |
||
229 | * @author seatle <[email protected]> |
||
230 | * @created time :2017-08-03 18:06 |
||
231 | */ |
||
232 | public static function get_cookies($domain = '') |
||
233 | { |
||
234 | if (!empty($domain) && !isset(self::$domain_cookies[$domain])) |
||
235 | { |
||
236 | return array(); |
||
237 | } |
||
238 | return empty($domain) ? self::$cookies : self::$domain_cookies[$domain]; |
||
239 | } |
||
240 | |||
241 | /** |
||
242 | * 删除Cookie |
||
243 | * |
||
244 | * @param string $domain 不传则删除全局Cookie |
||
245 | * @return void |
||
246 | * @author seatle <[email protected]> |
||
247 | * @created time :2017-08-03 18:06 |
||
248 | */ |
||
249 | public static function del_cookie($key, $domain = '') |
||
250 | { |
||
251 | if (empty($key)) |
||
252 | { |
||
253 | return false; |
||
254 | } |
||
255 | |||
256 | if (!empty($domain) && !isset(self::$domain_cookies[$domain])) |
||
257 | { |
||
258 | return false; |
||
259 | } |
||
260 | |||
261 | if (!empty($domain)) |
||
262 | { |
||
263 | if (isset(self::$domain_cookies[$domain][$key])) |
||
264 | { |
||
265 | unset(self::$domain_cookies[$domain][$key]); |
||
266 | } |
||
267 | } |
||
268 | else |
||
269 | { |
||
270 | if (isset(self::$cookies[$key])) |
||
271 | { |
||
272 | unset(self::$cookies[$key]); |
||
273 | } |
||
274 | } |
||
275 | return true; |
||
276 | } |
||
277 | |||
278 | /** |
||
279 | * 删除Cookie |
||
280 | * |
||
281 | * @param string $domain 不传则删除全局Cookie |
||
282 | * @return void |
||
283 | * @author seatle <[email protected]> |
||
284 | * @created time :2017-08-03 18:06 |
||
285 | */ |
||
286 | public static function del_cookies($domain = '') |
||
304 | } |
||
305 | |||
306 | /** |
||
307 | * 设置随机的user_agent |
||
308 | * |
||
309 | * @param string $useragent |
||
310 | * @return void |
||
311 | */ |
||
312 | public static function set_useragent($useragent) |
||
313 | { |
||
314 | self::$useragents = is_array($useragent) ? $useragent : array($useragent); |
||
315 | } |
||
316 | |||
317 | /** |
||
318 | * set referer |
||
319 | * |
||
320 | */ |
||
321 | public static function set_referer($referer) |
||
322 | { |
||
323 | self::$rawheaders['Referer'] = $referer; |
||
324 | } |
||
325 | |||
326 | /** |
||
327 | * 设置伪造IP |
||
328 | * 传入数组则为随机IP |
||
329 | * @param string $ip |
||
330 | * @return void |
||
331 | */ |
||
332 | public static function set_client_ip($ip) |
||
335 | } |
||
336 | |||
337 | /** |
||
338 | * 删除伪造IP |
||
339 | * |
||
340 | * @return void |
||
341 | * @author seatle <[email protected]> |
||
342 | * @created time :2018-07-16 17:59 |
||
343 | */ |
||
344 | public static function del_client_ip() |
||
345 | { |
||
346 | self::$client_ips = array(); |
||
347 | } |
||
348 | |||
349 | /** |
||
350 | * 设置中文请求 |
||
351 | * |
||
352 | * @param string $lang |
||
353 | * @return void |
||
354 | */ |
||
355 | public static function set_accept_language($lang = 'zh-CN') |
||
356 | { |
||
357 | self::$rawheaders['Accept-Language'] = $lang; |
||
358 | } |
||
359 | |||
360 | /** |
||
361 | * 设置Hosts |
||
362 | * 负载均衡到不同的服务器,如果对方使用CDN,采用这个是最好的了 |
||
363 | * |
||
364 | * @param string $hosts |
||
365 | * @return void |
||
366 | */ |
||
367 | public static function set_hosts($host, $ips = array()) |
||
368 | { |
||
369 | $ips = is_array($ips) ? $ips : array($ips); |
||
370 | self::$hosts[$host] = $ips; |
||
371 | } |
||
372 | |||
373 | /** |
||
374 | * 分割返回的header和body |
||
375 | * header用来判断编码和获取Cookie |
||
376 | * body用来判断编码,得到编码前和编码后的内容 |
||
377 | * |
||
378 | * @return void |
||
379 | * @author seatle <[email protected]> |
||
380 | * @created time :2017-08-03 18:06 |
||
381 | */ |
||
382 | public static function split_header_body() |
||
383 | { |
||
384 | $head = $body = ''; |
||
385 | $head = substr(self::$raw, 0, self::$info['header_size']); |
||
386 | $body = substr(self::$raw, self::$info['header_size']); |
||
387 | // http header |
||
388 | self::$head = $head; |
||
389 | // The body before encoding |
||
390 | self::$content = $body; |
||
391 | |||
392 | //$http_headers = array(); |
||
393 | //// 解析HTTP数据流 |
||
394 | //if (!empty(self::$raw)) |
||
395 | //{ |
||
396 | //self::get_response_cookies($domain); |
||
397 | //// body里面可能有 \r\n\r\n,但是第一个一定是HTTP Header,去掉后剩下的就是body |
||
398 | //$array = explode("\r\n\r\n", self::$raw); |
||
399 | //foreach ($array as $k=>$v) |
||
400 | //{ |
||
401 | //// post 方法会有两个http header:HTTP/1.1 100 Continue、HTTP/1.1 200 OK |
||
402 | //if (preg_match("#^HTTP/.*? 100 Continue#", $v)) |
||
403 | //{ |
||
404 | //unset($array[$k]); |
||
405 | //continue; |
||
406 | //} |
||
407 | //if (preg_match("#^HTTP/.*? \d+ #", $v)) |
||
408 | //{ |
||
409 | //$header = $v; |
||
410 | //unset($array[$k]); |
||
411 | //$http_headers = self::get_response_headers($v); |
||
412 | //} |
||
413 | //} |
||
414 | //$body = implode("\r\n\r\n", $array); |
||
415 | //} |
||
416 | |||
417 | // 设置了输出编码的转码,注意: xpath只支持utf-8,iso-8859-1 不要转,他本身就是utf-8 |
||
418 | $body = self::encoding($body); //自动转码 |
||
419 | // 转码后 |
||
420 | self::$encoding = self::$output_encoding; |
||
421 | |||
422 | // The body after encoding |
||
423 | self::$text = $body; |
||
424 | return array($head, $body); |
||
425 | } |
||
426 | |||
427 | /** |
||
428 | * 获得域名相对应的Cookie |
||
429 | * |
||
430 | * @param mixed $header |
||
431 | * @param mixed $domain |
||
432 | * @return void |
||
433 | * @author seatle <[email protected]> |
||
434 | * @created time :2017-08-03 18:06 |
||
435 | */ |
||
436 | public static function get_response_cookies($header, $domain) |
||
437 | { |
||
438 | // 解析Cookie并存入 self::$cookies 方便调用 |
||
439 | preg_match_all("/.*?Set\-Cookie: ([^\r\n]*)/i", $header, $matches); |
||
440 | $cookies = empty($matches[1]) ? array() : $matches[1]; |
||
441 | |||
442 | // 解析到Cookie |
||
443 | if (!empty($cookies)) |
||
444 | { |
||
445 | $cookies = implode(';', $cookies); |
||
446 | $cookies = explode(';', $cookies); |
||
447 | foreach ($cookies as $cookie) |
||
448 | { |
||
449 | $cookie_arr = explode('=', $cookie, 2); |
||
450 | // 过滤 httponly、secure |
||
451 | if (count($cookie_arr) < 2) |
||
452 | { |
||
453 | continue; |
||
454 | } |
||
455 | $cookie_name = !empty($cookie_arr[0]) ? trim($cookie_arr[0]) : ''; |
||
456 | if (empty($cookie_name)) |
||
457 | { |
||
458 | continue; |
||
459 | } |
||
460 | // 过滤掉domain路径 |
||
461 | if (in_array(strtolower($cookie_name), array('path', 'domain', 'expires', 'max-age'))) |
||
462 | { |
||
463 | continue; |
||
464 | } |
||
465 | self::$domain_cookies[$domain][trim($cookie_arr[0])] = trim($cookie_arr[1]); |
||
466 | } |
||
467 | } |
||
468 | } |
||
469 | |||
470 | /** |
||
471 | * 获得response header |
||
472 | * 此方法占时没有用到 |
||
473 | * |
||
474 | * @param mixed $header |
||
475 | * @return void |
||
476 | * @author seatle <[email protected]> |
||
477 | * @created time :2017-08-03 18:06 |
||
478 | */ |
||
479 | public static function get_response_headers($header) |
||
480 | { |
||
481 | $headers = array(); |
||
482 | $header_lines = explode("\n", $header); |
||
483 | if (!empty($header_lines)) |
||
484 | { |
||
485 | foreach ($header_lines as $line) |
||
486 | { |
||
487 | $header_arr = explode(':', $line, 2); |
||
488 | $key = empty($header_arr[0]) ? '' : trim($header_arr[0]); |
||
489 | $val = empty($header_arr[1]) ? '' : trim($header_arr[1]); |
||
490 | if (empty($key) || empty($val)) |
||
491 | { |
||
492 | continue; |
||
493 | } |
||
494 | $headers[$key] = $val; |
||
495 | } |
||
496 | } |
||
497 | self::$headers = $headers; |
||
498 | return self::$headers; |
||
499 | } |
||
500 | |||
501 | /** |
||
502 | * 获取编码 |
||
503 | * @param $string |
||
504 | * @return string |
||
505 | */ |
||
506 | public static function get_encoding($string) |
||
507 | { |
||
508 | $encoding = mb_detect_encoding($string, array('UTF-8', 'GBK', 'GB2312', 'LATIN1', 'ASCII', 'BIG5', 'ISO-8859-1')); |
||
509 | return strtolower($encoding); |
||
510 | } |
||
511 | |||
512 | /** |
||
513 | * 移除页面head区域代码 |
||
514 | * @param $html |
||
515 | * @return mixed |
||
516 | */ |
||
517 | private static function _remove_head($html) |
||
518 | { |
||
519 | return preg_replace('/<head.+?>.+<\/head>/is', '<head></head>', $html); |
||
520 | } |
||
521 | |||
522 | /** |
||
523 | * 简单的判断一下参数是否为一个URL链接 |
||
524 | * @param string $str |
||
525 | * @return boolean |
||
526 | */ |
||
527 | private static function _is_url($url) |
||
528 | { |
||
529 | //$pattern = '/^http(s)?:\\/\\/.+/'; |
||
530 | $pattern = "/\b(([\w-]+:\/\/?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|\/)))/"; |
||
531 | if (preg_match($pattern, $url)) |
||
532 | { |
||
533 | return true; |
||
534 | } |
||
535 | return false; |
||
536 | } |
||
537 | |||
538 | /** |
||
539 | * 初始化 CURL |
||
540 | * |
||
541 | */ |
||
542 | public static function init() |
||
543 | { |
||
544 | if (!is_resource ( self::$ch )) |
||
545 | { |
||
546 | self::$ch = curl_init (); |
||
547 | curl_setopt( self::$ch, CURLOPT_RETURNTRANSFER, true ); |
||
548 | curl_setopt( self::$ch, CURLOPT_HEADER, false ); |
||
549 | curl_setopt( self::$ch, CURLOPT_USERAGENT, "phpspider-requests/".self::VERSION ); |
||
550 | // 如果设置了两个时间,就分开设置 |
||
551 | if (is_array(self::$timeout)) |
||
552 | { |
||
553 | curl_setopt( self::$ch, CURLOPT_CONNECTTIMEOUT, self::$timeout[0] ); |
||
554 | curl_setopt( self::$ch, CURLOPT_TIMEOUT, self::$timeout[1]); |
||
555 | } |
||
556 | else |
||
557 | { |
||
558 | curl_setopt(self::$ch, CURLOPT_CONNECTTIMEOUT, ceil(self::$timeout / 2)); |
||
559 | curl_setopt(self::$ch, CURLOPT_TIMEOUT, self::$timeout); |
||
560 | } |
||
561 | curl_setopt(self::$ch, CURLOPT_MAXREDIRS, 5); //maximum number of redirects allowed |
||
562 | // 在多线程处理场景下使用超时选项时,会忽略signals对应的处理函数,但是无耐的是还有小概率的crash情况发生 |
||
563 | curl_setopt( self::$ch, CURLOPT_NOSIGNAL, true); |
||
564 | } |
||
565 | return self::$ch; |
||
566 | } |
||
567 | |||
568 | /** |
||
569 | * get 请求 |
||
570 | */ |
||
571 | public static function get($url, $fields = array(), $allow_redirects = true, $cert = NULL) |
||
572 | { |
||
573 | self::init (); |
||
574 | return self::request($url, 'get', $fields, NULL, $allow_redirects, $cert); |
||
575 | } |
||
576 | |||
577 | /** |
||
578 | * post 请求 |
||
579 | * $fields 有三种类型:1、数组;2、http query;3、json |
||
580 | * 1、array('name'=>'yangzetao') |
||
581 | * 2、http_build_query(array('name'=>'yangzetao')) |
||
582 | * 3、json_encode(array('name'=>'yangzetao')) |
||
583 | * 前两种是普通的post,可以用$_POST方式获取 |
||
584 | * 第三种是post stream( json rpc,其实就是webservice ) |
||
585 | * 虽然是post方式,但是只能用流方式 http://input 后者 $HTTP_RAW_POST_DATA 获取 |
||
586 | * |
||
587 | * @param mixed $url |
||
588 | * @param array $fields |
||
589 | * @param mixed $proxies |
||
590 | * @static |
||
591 | * @access public |
||
592 | * @return void |
||
593 | */ |
||
594 | public static function post($url, $fields = array(), $files = array(), $allow_redirects = true, $cert = NULL) |
||
595 | { |
||
596 | self::init (); |
||
597 | return self::request($url, 'POST', $fields, $files, $allow_redirects, $cert); |
||
598 | } |
||
599 | |||
600 | public static function put($url, $fields = array(), $allow_redirects = true, $cert = NULL) |
||
601 | { |
||
602 | self::init (); |
||
603 | return self::request($url, 'PUT', $fields, $allow_redirects, $cert); |
||
604 | } |
||
605 | |||
606 | public static function delete($url, $fields = array(), $allow_redirects = true, $cert = NULL) |
||
607 | { |
||
608 | self::init (); |
||
609 | return self::request($url, 'DELETE', $fields, $allow_redirects, $cert); |
||
610 | } |
||
611 | |||
612 | // 响应HTTP头域里的元信息 |
||
613 | // 此方法被用来获取请求实体的元信息而不需要传输实体主体(entity-body) |
||
614 | // 此方法经常被用来测试超文本链接的有效性,可访问性,和最近的改变。. |
||
615 | public static function head($url, $fields = array(), $allow_redirects = true, $cert = NULL) |
||
616 | { |
||
617 | self::init (); |
||
618 | self::request($url, 'HEAD', $fields, $allow_redirects, $cert); |
||
619 | } |
||
620 | |||
621 | public static function options($url, $fields = array(), $allow_redirects = true, $cert = NULL) |
||
625 | } |
||
626 | |||
627 | public static function patch($url, $fields = array(), $allow_redirects = true, $cert = NULL) |
||
628 | { |
||
629 | self::init (); |
||
630 | return self::request($url, 'PATCH', $fields, $allow_redirects, $cert); |
||
631 | } |
||
632 | |||
633 | /** |
||
634 | * request |
||
635 | * |
||
636 | * @param mixed $url 请求URL |
||
637 | * @param string $method 请求方法 |
||
638 | * @param array $fields 表单字段 |
||
639 | * @param array $files 上传文件 |
||
640 | * @param mixed $cert CA证书 |
||
641 | * @return void |
||
642 | * @author seatle <[email protected]> |
||
643 | * @created time :2017-08-03 18:06 |
||
644 | */ |
||
645 | public static function request($url, $method = 'GET', $fields = array(), $files = array(), $allow_redirects = true, $cert = NULL) |
||
646 | { |
||
647 | $method = strtoupper($method); |
||
648 | if(!self::_is_url($url)) |
||
649 | { |
||
650 | self::$error = "You have requested URL ({$url}) is not a valid HTTP address"; |
||
651 | return false; |
||
652 | } |
||
653 | |||
654 | // 如果是 get 方式,直接拼凑一个 url 出来 |
||
655 | if ($method == 'GET' && !empty($fields)) |
||
656 | { |
||
657 | $url = $url.(strpos($url, '?') === false ? '?' : '&').http_build_query($fields); |
||
658 | } |
||
659 | |||
660 | $parse_url = parse_url($url); |
||
661 | if (empty($parse_url) || empty($parse_url['host']) || !in_array($parse_url['scheme'], array('http', 'https'))) |
||
662 | { |
||
663 | self::$error = "No connection adapters were found for '{$url}'"; |
||
664 | return false; |
||
665 | } |
||
666 | $scheme = $parse_url['scheme']; |
||
667 | $domain = $parse_url['host']; |
||
668 | |||
669 | // 随机绑定 hosts,做负载均衡 |
||
670 | if (self::$hosts) |
||
671 | { |
||
672 | if (isset(self::$hosts[$domain])) |
||
673 | { |
||
674 | $hosts = self::$hosts[$domain]; |
||
675 | $key = rand(0, count($hosts)-1); |
||
676 | $ip = $hosts[$key]; |
||
677 | $url = str_replace($domain, $ip, $url); |
||
678 | self::$rawheaders['Host'] = $domain; |
||
679 | } |
||
680 | } |
||
681 | |||
682 | curl_setopt( self::$ch, CURLOPT_URL, $url ); |
||
683 | |||
684 | if ($method != 'GET') |
||
685 | { |
||
686 | // 如果是 post 方式 |
||
687 | if ($method == 'POST') |
||
688 | { |
||
689 | //curl_setopt( self::$ch, CURLOPT_POST, true ); |
||
690 | $tmpheaders = array_change_key_case(self::$rawheaders, CASE_LOWER); |
||
691 | // 有些RESTful服务只接受JSON形态的数据 |
||
692 | // CURLOPT_POST会把上傳的文件类型设为 multipart/form-data |
||
693 | // 把CURLOPT_POSTFIELDS的内容按multipart/form-data 的形式编码 |
||
694 | // CURLOPT_CUSTOMREQUEST可以按指定内容上传 |
||
695 | if ( isset($tmpheaders['content-type']) && $tmpheaders['content-type'] == 'application/json' ) |
||
696 | { |
||
697 | curl_setopt( self::$ch, CURLOPT_CUSTOMREQUEST, $method ); |
||
698 | } |
||
699 | else |
||
700 | { |
||
701 | curl_setopt( self::$ch, CURLOPT_POST, true ); |
||
702 | } |
||
703 | |||
704 | $file_fields = array(); |
||
705 | if (!empty($files)) |
||
706 | { |
||
707 | foreach ($files as $postname => $file) |
||
708 | { |
||
709 | $filepath = realpath($file); |
||
710 | // 如果文件不存在 |
||
711 | if (!file_exists($filepath)) |
||
712 | { |
||
713 | continue; |
||
714 | } |
||
715 | |||
716 | $filename = basename($filepath); |
||
717 | $type = self::get_mimetype($filepath); |
||
718 | $file_fields[$postname] = curl_file_create($filepath, $type, $filename); |
||
719 | // curl -F "name=seatle&file=@/absolute/path/to/image.png" htt://localhost/uploadfile.php |
||
720 | //$cfile = '@'.realpath($filename).";type=".$type.";filename=".$filename; |
||
721 | } |
||
722 | } |
||
723 | } |
||
724 | else |
||
725 | { |
||
726 | self::$rawheaders['X-HTTP-Method-Override'] = $method; |
||
727 | curl_setopt( self::$ch, CURLOPT_CUSTOMREQUEST, $method ); |
||
728 | } |
||
729 | |||
730 | if ( $method == 'POST' ) |
||
731 | { |
||
732 | // 不是上传文件的,用http_build_query, 能实现更好的兼容性,更小的请求数据包 |
||
733 | if ( empty($file_fields) ) |
||
734 | { |
||
735 | // post方式 |
||
736 | if ( is_array($fields) ) |
||
737 | { |
||
738 | $fields = http_build_query($fields); |
||
739 | } |
||
740 | } |
||
741 | else |
||
742 | { |
||
743 | // 有post数据 |
||
744 | if ( is_array($fields) && !empty($fields) ) |
||
745 | { |
||
746 | // 某些server可能会有问题 |
||
747 | $fields = array_merge($fields, $file_fields); |
||
748 | } |
||
749 | else |
||
750 | { |
||
751 | $fields = $file_fields; |
||
752 | } |
||
753 | } |
||
754 | |||
755 | // 不能直接传数组,不知道是什么Bug,会非常慢 |
||
756 | curl_setopt( self::$ch, CURLOPT_POSTFIELDS, $fields ); |
||
757 | } |
||
758 | } |
||
759 | |||
760 | $cookies = self::get_cookies(); |
||
761 | $domain_cookies = self::get_cookies($domain); |
||
762 | $cookies = array_merge($cookies, $domain_cookies); |
||
763 | // 是否设置了cookie |
||
764 | if (!empty($cookies)) |
||
765 | { |
||
766 | foreach ($cookies as $key=>$value) |
||
767 | { |
||
768 | $cookie_arr[] = $key.'='.$value; |
||
769 | } |
||
770 | $cookies = implode('; ', $cookie_arr); |
||
771 | curl_setopt(self::$ch, CURLOPT_COOKIE, $cookies); |
||
772 | } |
||
773 | |||
774 | if (!empty(self::$useragents)) |
||
775 | { |
||
776 | $key = rand(0, count(self::$useragents) - 1); |
||
777 | self::$rawheaders['User-Agent'] = self::$useragents[$key]; |
||
778 | } |
||
779 | |||
780 | if (!empty(self::$client_ips)) |
||
781 | { |
||
782 | $key = rand(0, count(self::$client_ips) - 1); |
||
783 | self::$rawheaders['CLIENT-IP'] = self::$client_ips[$key]; |
||
784 | self::$rawheaders['X-FORWARDED-FOR'] = self::$client_ips[$key]; |
||
785 | } |
||
786 | |||
787 | if (self::$rawheaders) |
||
788 | { |
||
789 | $http_headers = array(); |
||
790 | foreach (self::$rawheaders as $k=>$v) |
||
791 | { |
||
792 | $http_headers[] = $k.': '.$v; |
||
793 | } |
||
794 | curl_setopt( self::$ch, CURLOPT_HTTPHEADER, $http_headers ); |
||
795 | } |
||
796 | |||
797 | curl_setopt( self::$ch, CURLOPT_ENCODING, 'gzip' ); |
||
798 | |||
799 | // 关闭验证 |
||
800 | if ($scheme == 'https') |
||
801 | { |
||
802 | curl_setopt(self::$ch, CURLOPT_SSL_VERIFYPEER, false); |
||
803 | curl_setopt(self::$ch, CURLOPT_SSL_VERIFYHOST, false); |
||
804 | } |
||
805 | |||
806 | if (self::$proxies) |
||
807 | { |
||
808 | $key = rand(0, count(self::$proxies) - 1); |
||
809 | $proxy = self::$proxies[$key]; |
||
810 | curl_setopt( self::$ch, CURLOPT_PROXY, $proxy ); |
||
811 | } |
||
812 | |||
813 | // header + body,header 里面有 cookie |
||
814 | curl_setopt( self::$ch, CURLOPT_HEADER, true ); |
||
815 | // 请求跳转后的内容 |
||
816 | if ($allow_redirects) |
||
817 | { |
||
818 | curl_setopt( self::$ch, CURLOPT_FOLLOWLOCATION, true); |
||
819 | } |
||
820 | |||
821 | self::$raw = curl_exec ( self::$ch ); |
||
822 | // 真实url |
||
823 | //$location = curl_getinfo( self::$ch, CURLINFO_EFFECTIVE_URL); |
||
824 | self::$info = curl_getinfo( self::$ch ); |
||
825 | //print_r(self::$info); |
||
826 | self::$status_code = self::$info['http_code']; |
||
827 | if (self::$raw === false) |
||
828 | { |
||
829 | self::$error = 'Curl error: ' . curl_error( self::$ch ); |
||
830 | //trigger_error(self::$error, E_USER_WARNING); |
||
831 | } |
||
832 | |||
833 | // 关闭句柄 |
||
834 | curl_close( self::$ch ); |
||
835 | |||
836 | // 请求成功之后才把URL存起来 |
||
837 | list($header, $text) = self::split_header_body(); |
||
838 | self::$history = self::get_history($header); |
||
839 | self::$headers = self::get_response_headers($header); |
||
840 | self::get_response_cookies($header, $domain); |
||
841 | //$data = substr($data, 10); |
||
842 | //$data = gzinflate($data); |
||
843 | return $text; |
||
844 | } |
||
845 | |||
846 | public static function get_history($header) |
||
847 | { |
||
848 | $status_code = 0; |
||
849 | $lines = explode("\n", $header); |
||
850 | foreach ($lines as $line) |
||
851 | { |
||
852 | $line = trim($line); |
||
853 | if (preg_match("#^HTTP/.*? (\d+) Found#", $line, $out)) |
||
854 | { |
||
855 | $status_code = empty($out[1]) ? 0 : intval($out[1]); |
||
856 | } |
||
857 | } |
||
858 | return $status_code; |
||
859 | } |
||
860 | |||
861 | // 获取 mimetype |
||
862 | public static function get_mimetype($filepath) |
||
870 | } |
||
871 | |||
872 | /** |
||
873 | * 拼凑文件和表单 |
||
874 | * 占时没有用到 |
||
875 | * |
||
876 | * @param mixed $post_fields |
||
877 | * @param mixed $file_fields |
||
878 | * @return void |
||
879 | * @author seatle <[email protected]> |
||
880 | * @created time :2017-08-03 18:06 |
||
881 | */ |
||
882 | public static function get_postfile_form($post_fields, $file_fields) |
||
920 | } |
||
921 | |||
922 | /** |
||
923 | * html encoding transform |
||
924 | * |
||
925 | * @param string $html |
||
926 | * @param string $in |
||
927 | * @param string $out |
||
928 | * @param string $content |
||
929 | * @param string $mode |
||
930 | * auto|iconv|mb_convert_encoding |
||
931 | * @return string |
||
932 | */ |
||
933 | public static function encoding($html, $in = null, $out = null, $mode = 'auto') |
||
997 | } |
||
998 | } |
||
999 |
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"]
, you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths