requests::set_hosts()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 2
nc 2
nop 2
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
// +----------------------------------------------------------------------
3
// | PHPSpider [ A PHP Framework For Crawler ]
4
// +----------------------------------------------------------------------
5
// | Copyright (c) 2006-2014 https://doc.phpspider.org All rights reserved.
6
// +----------------------------------------------------------------------
7
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
8
// +----------------------------------------------------------------------
9
// | Author: Seatle Yang <[email protected]>
10
// +----------------------------------------------------------------------
11
12
// +----------------------------------------------------------------------
13
// | GET请求
14
// | requests::get('http://www.test.com');
15
// | SERVER
16
// | $_GET
17
// +----------------------------------------------------------------------
18
// | POST请求
19
// | $data = array('name'=>'request');
20
// | requests::post('http://www.test.com', $data);
21
// | SERVER
22
// | $_POST
23
// +----------------------------------------------------------------------
24
// | POST RESTful请求
25
// | $data = array('name'=>'request');
26
// | $data_string = json_encode($data);
27
// | requests::set_header("Content-Type", "application/json");
28
// | requests::post('http://www.test.com', $data_string);
29
// | SERVER
30
// | file_get_contents('php://input')
31
// +----------------------------------------------------------------------
32
// | POST 文件上传
33
// | $data = array('file1'=>''./data/phpspider.log'');
34
// | requests::post('http://www.test.com', null, $data);
35
// | SERVER
36
// | $_FILES
37
// +----------------------------------------------------------------------
38
// | 代理
39
// | requests::set_proxy(array('223.153.69.150:42354'));
40
// | $html = requests::get('https://www.test.com');
41
// +----------------------------------------------------------------------
42
43
//----------------------------------
44
// PHPSpider请求类文件
45
//----------------------------------
46
47
namespace phpspider\core;
48
49
if (!function_exists('curl_file_create')) 
50
{
51
    function curl_file_create($filename, $mimetype = '', $postname = '') 
52
    {
53
        return "@$filename;filename="
54
            . ($postname ?: basename($filename))
55
            . ($mimetype ? ";type=$mimetype" : '');
56
    }
57
}
58
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
0 ignored issues
show
Bug introduced by
The type phpspider\core\or was not found. Maybe you did not declare it correctly or list all dependencies?

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:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
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;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type void.
Loading history...
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;
0 ignored issues
show
Bug Best Practice introduced by
The expression return true returns the type true which is incompatible with the documented return type void.
Loading history...
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;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type void.
Loading history...
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;
0 ignored issues
show
Bug Best Practice introduced by
The expression return true returns the type true which is incompatible with the documented return type void.
Loading history...
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 '';
0 ignored issues
show
Bug Best Practice introduced by
The expression return '' returns the type string which is incompatible with the documented return type void.
Loading history...
219
        }
220
        $cookies = empty($domain) ? self::$cookies : self::$domain_cookies[$domain];
221
        return isset($cookies[$name]) ? $cookies[$name] : '';
0 ignored issues
show
Bug Best Practice introduced by
The expression return IssetNode ? $cookies[$name] : '' also could return the type string which is incompatible with the documented return type void.
Loading history...
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();
0 ignored issues
show
Bug Best Practice introduced by
The expression return array() returns the type array which is incompatible with the documented return type void.
Loading history...
237
        }
238
        return empty($domain) ? self::$cookies : self::$domain_cookies[$domain];
0 ignored issues
show
Bug Best Practice introduced by
The expression return empty($domain) ? ...domain_cookies[$domain] also could return the type array which is incompatible with the documented return type void.
Loading history...
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;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type void.
Loading history...
254
        }
255
256
        if (!empty($domain) && !isset(self::$domain_cookies[$domain])) 
257
        {
258
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type void.
Loading history...
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;
0 ignored issues
show
Bug Best Practice introduced by
The expression return true returns the type true which is incompatible with the documented return type void.
Loading history...
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 = '')
287
    {
288
        if (!empty($domain) && !isset(self::$domain_cookies[$domain])) 
289
        {
290
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type void.
Loading history...
291
        }
292
        if ( empty($domain) ) 
293
        {
294
            self::$cookies = array();
295
        }
296
        else 
297
        {
298
            if (isset(self::$domain_cookies[$domain])) 
299
            {
300
                unset(self::$domain_cookies[$domain]);
301
            }
302
        }
303
        return true;
0 ignored issues
show
Bug Best Practice introduced by
The expression return true returns the type true which is incompatible with the documented return type void.
Loading history...
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);
0 ignored issues
show
introduced by
The condition is_array($useragent) is always false.
Loading history...
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)
333
    {
334
        self::$client_ips = is_array($ip) ? $ip : array($ip);
0 ignored issues
show
introduced by
The condition is_array($ip) is always false.
Loading history...
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 = '';
0 ignored issues
show
Unused Code introduced by
The assignment to $head is dead and can be removed.
Loading history...
Unused Code introduced by
The assignment to $body is dead and can be removed.
Loading history...
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);
0 ignored issues
show
Bug Best Practice introduced by
The expression return array($head, $body) returns the type array<integer,string> which is incompatible with the documented return type void.
Loading history...
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;
0 ignored issues
show
Bug Best Practice introduced by
The expression return self::headers returns the type array which is incompatible with the documented return type void.
Loading history...
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)
0 ignored issues
show
Unused Code introduced by
The method _remove_head() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
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 );
0 ignored issues
show
Bug introduced by
It seems like self::ch can also be of type false; however, parameter $ch of curl_setopt() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

547
            curl_setopt( /** @scrutinizer ignore-type */ self::$ch, CURLOPT_RETURNTRANSFER, true );
Loading history...
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)) 
0 ignored issues
show
introduced by
The condition is_array(self::timeout) is always false.
Loading history...
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);
0 ignored issues
show
Bug introduced by
Are you sure the usage of self::request($url, 'get...allow_redirects, $cert) targeting phpspider\core\requests::request() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
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);
0 ignored issues
show
Bug introduced by
Are you sure the usage of self::request($url, 'POS...allow_redirects, $cert) targeting phpspider\core\requests::request() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
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);
0 ignored issues
show
Bug introduced by
Are you sure the usage of self::request($url, 'PUT...allow_redirects, $cert) targeting phpspider\core\requests::request() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
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);
0 ignored issues
show
Bug introduced by
Are you sure the usage of self::request($url, 'DEL...allow_redirects, $cert) targeting phpspider\core\requests::request() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
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)
622
    {
623
        self::init ();
624
        return self::request($url, 'OPTIONS', $fields, $allow_redirects, $cert);
0 ignored issues
show
Bug introduced by
Are you sure the usage of self::request($url, 'OPT...allow_redirects, $cert) targeting phpspider\core\requests::request() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
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);
0 ignored issues
show
Bug introduced by
Are you sure the usage of self::request($url, 'PAT...allow_redirects, $cert) targeting phpspider\core\requests::request() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
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)
0 ignored issues
show
Unused Code introduced by
The parameter $cert is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

645
    public static function request($url, $method = 'GET', $fields = array(), $files = array(), $allow_redirects = true, /** @scrutinizer ignore-unused */ $cert = NULL)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
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;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type void.
Loading history...
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;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type void.
Loading history...
665
        }
666
        $scheme = $parse_url['scheme'];
667
        $domain = $parse_url['host'];
668
669
        // 随机绑定 hosts,做负载均衡
670
        if (self::$hosts) 
0 ignored issues
show
Bug Best Practice introduced by
The expression self::hosts of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
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();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $cookies is correct as self::get_cookies() targeting phpspider\core\requests::get_cookies() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
761
        $domain_cookies = self::get_cookies($domain);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $domain_cookies is correct as self::get_cookies($domain) targeting phpspider\core\requests::get_cookies() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
762
        $cookies =  array_merge($cookies, $domain_cookies);
0 ignored issues
show
Bug introduced by
$cookies of type void is incompatible with the type array expected by parameter $array1 of array_merge(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

762
        $cookies =  array_merge(/** @scrutinizer ignore-type */ $cookies, $domain_cookies);
Loading history...
Bug introduced by
$domain_cookies of type void is incompatible with the type array|null expected by parameter $array2 of array_merge(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

762
        $cookies =  array_merge($cookies, /** @scrutinizer ignore-type */ $domain_cookies);
Loading history...
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);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $cookie_arr seems to be defined by a foreach iteration on line 766. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
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)
0 ignored issues
show
Bug Best Practice introduced by
The expression self::rawheaders of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
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)
0 ignored issues
show
Bug Best Practice introduced by
The expression self::proxies of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
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();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to list($header, $text) is correct as self::split_header_body() targeting phpspider\core\requests::split_header_body() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
838
        self::$history = self::get_history($header);
839
        self::$headers = self::get_response_headers($header);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to self::headers is correct as self::get_response_headers($header) targeting phpspider\core\requests::get_response_headers() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
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)
863
    {
864
        $fp  = finfo_open(FILEINFO_MIME);
865
        $mime = finfo_file($fp, $filepath);
866
        finfo_close($fp);
867
        $arr  = explode(';', $mime);
868
        $type = empty($arr[0]) ? '' : $arr[0];
869
        return $type;
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)
883
    {
884
        // 构造post数据
885
        $data = '';
886
        $delimiter = '-------------' . uniqid();
887
        // 表单数据
888
        foreach ($post_fields as $name => $content) 
889
        {
890
            $data .= '--'.$delimiter."\r\n";
891
            $data .= 'Content-Disposition: form-data; name = "'.$name.'"';
892
            $data .= "\r\n\r\n";
893
            $data .= $content;
894
            $data .= "\r\n";
895
        }
896
897
        foreach ($file_fields as $input_name => $file) 
898
        {
899
            $data .= '--'.$delimiter."\r\n";
900
            $data .= 'Content-Disposition: form-data; name = "'.$input_name.'";'.
901
                ' filename="'.$file['filename'].'"'."\r\n";
902
            $data .= "Content-Type: {$file['type']}\r\n";
903
            $data .= "\r\n";
904
            $data .= $file['content'];
905
            $data .= "\r\n";
906
        }
907
908
        // 结束符
909
        $data .= '--'.$delimiter."--\r\n";
910
911
        //return array(
912
            //CURLOPT_HTTPHEADER => array(
913
                //'Content-Type:multipart/form-data;boundary=' . $delimiter,
914
                //'Content-Length:' . strlen($data)
915
            //),
916
            //CURLOPT_POST => true,
917
            //CURLOPT_POSTFIELDS => $data,
918
        //);
919
        return array($delimiter, $data);
0 ignored issues
show
Bug Best Practice introduced by
The expression return array($delimiter, $data) returns the type array<integer,string> which is incompatible with the documented return type void.
Loading history...
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')
934
    {
935
        $valid = array(
936
            'auto',
937
            'iconv',
938
            'mb_convert_encoding',
939
        );
940
        if (isset(self::$output_encoding))
941
        {
942
            $out = self::$output_encoding;
943
        }
944
        if ( ! isset($out))
945
        {
946
            $out = 'UTF-8';
947
        }
948
        if ( ! in_array($mode, $valid))
949
        {
950
            throw new Exception('invalid mode, mode='.$mode);
0 ignored issues
show
Bug introduced by
The type phpspider\core\Exception was not found. Did you mean Exception? If so, make sure to prefix the type with \.
Loading history...
951
        }
952
        $if = function_exists('mb_convert_encoding');
953
        $if = $if && ($mode == 'auto' || $mode == 'mb_convert_encoding');
954
        if (function_exists('iconv') && ($mode == 'auto' || $mode == 'iconv'))
955
        {
956
            $func = 'iconv';
957
        }
958
        elseif ($if)
959
        {
960
            $func = 'mb_convert_encoding';
961
        }
962
        else
963
        {
964
            throw new Exception('charsetTrans failed, no function');
965
        }
966
967
        $pattern = '/(<meta[^>]*?charset=([\"\']?))([a-z\d_\-]*)(\2[^>]*?>)/is';
968
        if ( ! isset($in))
969
        {
970
            $n = preg_match($pattern, $html, $in);
971
            if ($n > 0)
972
            {
973
                $in = $in[3];
974
            }
975
            else
976
            {
977
                $in = null;
978
            }
979
            if (empty($in) and function_exists('mb_detect_encoding'))
980
            {
981
                $in = mb_detect_encoding($html, array('UTF-8', 'GBK', 'GB2312', 'LATIN1', 'ASCII', 'BIG5', 'ISO-8859-1'));
982
            }
983
        }
984
985
        if (isset($in))
986
        {
987
            if ($in == 'ISO-8859-1')
988
            {
989
                $in = 'UTF-8';
990
            }
991
            $old  = error_reporting(error_reporting() & ~E_NOTICE);
992
            $html = call_user_func($func, $in, $out.'//IGNORE', $html);
993
            error_reporting($old);
994
            $html = preg_replace($pattern, "\\1$out\\4", $html, 1);
995
        }
996
        return $html;
997
    }
998
}
999