|
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 |
|
|
|
|
|
|
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 = '') |
|
287
|
|
|
{ |
|
288
|
|
|
if (!empty($domain) && !isset(self::$domain_cookies[$domain])) |
|
289
|
|
|
{ |
|
290
|
|
|
return false; |
|
|
|
|
|
|
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; |
|
|
|
|
|
|
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) |
|
333
|
|
|
{ |
|
334
|
|
|
self::$client_ips = is_array($ip) ? $ip : array($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) |
|
622
|
|
|
{ |
|
623
|
|
|
self::init (); |
|
624
|
|
|
return self::request($url, 'OPTIONS', $fields, $allow_redirects, $cert); |
|
|
|
|
|
|
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) |
|
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); |
|
|
|
|
|
|
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); |
|
|
|
|
|
|
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
|
|
|
|
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