ComponentApi::_get()   C
last analyzed

Complexity

Conditions 9
Paths 49

Size

Total Lines 62
Code Lines 40

Duplication

Lines 62
Ratio 100 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 62
loc 62
rs 6.6867
cc 9
eloc 40
nc 49
nop 5

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
namespace Wechat;
3
4
use Wechat\API\BaseApi;
5
use Wechat\CacheDriver\BaseDriver;
6
use Wechat\Api;
7
8
/**
9
 * 微信第三方平台接口 客户端基类.
10
 *
11
 * @author Tian.
12
 */
13
class ComponentApi
14
{
15
    public static  $instantiation   = false;
16
    private static $selfInstanceMap = []; // 实例列表;
17
    private static $postQueryStr    = []; // post数据时 需要携带的查询字符串
18
    private static $CACHE_DRIVER    = ''; // 接口缓存驱动类名
19
    private static $error           = ''; // 错误信息;
20
    private static $errorCode       = ''; // 错误码;
21
    private static $apiData; // 信息;
22
    private static $APP_ID; // 服务号app_id;
23
    private static $COMPONENT_APPID; // 第三方COMPONENT_APPID
24
    private static $COMPONENT_APPSECRET; // 第三方COMPONENT_APPSECRET
25
    private static $COMPONENT_TOKEN; // 第三方COMPONENT_TOKEN
26
    private static $COMPONENT_ENCODING_AES_KEY; // 第三方COMPONENT_ENCODING_AES_KEY
27
    private static $AUTHORIZER_ACCESS_TOKEN; // 第三方给授权服务号的授权token
28
    private static $API_URL; // 微信接口地址
29
30
    /**
31
     * 第三方平台初始化
32
     *
33
     * @param        $appid
34
     * @param        $component_appid
35
     * @param        $component_appsecret
36
     * @param        $component_token
37
     * @param        $encoding_aes_key
38
     * @param        $authorizer_access_token
39
     * @param string $apiurl
40
     * @param string $cacheDriver
41
     */
42 View Code Duplication
    public static function init($appid, $component_appid, $component_appsecret, $component_token, $encoding_aes_key, $authorizer_access_token, $apiurl = 'https://api.weixin.qq.com/', $cacheDriver = 'File')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
43
    {
44
        self::$APP_ID                     = $appid;
45
        self::$COMPONENT_APPID            = $component_appid;
46
        self::$COMPONENT_APPSECRET        = $component_appsecret;
47
        self::$COMPONENT_TOKEN            = $component_token;
48
        self::$COMPONENT_ENCODING_AES_KEY = $encoding_aes_key;
49
        self::$AUTHORIZER_ACCESS_TOKEN    = $authorizer_access_token;
50
        self::$CACHE_DRIVER               = $cacheDriver;
51
        self::$API_URL                    = $apiurl;
52
    }
53
54
    /**
55
     * 获取授权服务号的token
56
     *
57
     * @author YangYang <[email protected]>
58
     *
59
     * @date   2017-01-09
60
     *
61
     * @return mixed
62
     */
63
    public static function getAccessToken()
64
    {
65
66
        return self::$AUTHORIZER_ACCESS_TOKEN;
67
    }
68
69
    /**
70
     * 工厂+多例模式 获取接口实例.
71
     *
72
     * @author Tian
73
     *
74
     * @date   2015-12-08
75
     *
76
     * @param string $className 接口类名.
77
     *
78
     * @return object
79
     */
80
    public static function factory($className)
81
    {
82
        if (!$className || !is_string($className)) {
83
            exit('类名参数不正确');
0 ignored issues
show
Coding Style Compatibility introduced by
The method factory() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
84
        }
85
86
        $className = __NAMESPACE__ . '\\API\\' . $className . 'Api';
87
88 View Code Duplication
        if (!array_key_exists($className, self::$selfInstanceMap)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
89
            $api = new $className();
90
            if (!$api instanceof BaseApi) {
91
                exit($className . ' 必须继承 BaseApi');
0 ignored issues
show
Coding Style Compatibility introduced by
The method factory() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
92
            }
93
            self::$selfInstanceMap[$className] = $api;
94
        }
95
        self::$instantiation = true;
96
        Api::$instantiation  = false;
97
98
        return self::$selfInstanceMap[$className];
99
    }
100
101
    /**
102
     * 设置错误信息.
103
     *
104
     * @author Tian
105
     *
106
     * @date   2015-12-08
107
     *
108
     * @param string $errorText 错误信息
109
     */
110
    public static function setError($errorText)
111
    {
112
        self::$error = $errorText;
113
    }
114
115
    /**
116
     * 获取错误信息.
117
     *
118
     * @author Tian
119
     *
120
     * @date   2015-12-08
121
     *
122
     * @return string
123
     */
124
    public static function getError()
125
    {
126
        return self::$error;
127
    }
128
129
    /**
130
     * 设置api原始返回值
131
     *
132
     * @param $apiData
133
     */
134
    public static function setApiData($apiData)
135
    {
136
        self::$apiData = $apiData;
137
    }
138
139
    /**
140
     * 设置post操作的get参数.
141
     *
142
     * @author Tian
143
     *
144
     * @date   2015-08-03
145
     *
146
     * @param string $name  参数名
147
     * @param string $value 值
148
     */
149
    public static function setPostQueryStr($name, $value)
150
    {
151
        self::$postQueryStr[$name] = $value;
152
    }
153
154
    /**
155
     * 获取api原始返回值
156
     *
157
     */
158
    public static function getApiData()
159
    {
160
        return self::$apiData;
161
    }
162
163
    /**
164
     * 设置错误码.
165
     *
166
     * @author Cui
167
     *
168
     * @date   2015-07-27
169
     *
170
     * @param string $errorCode 错误Code
171
     */
172
    public static function setErrorCode($errorCode)
173
    {
174
        self::$errorCode = $errorCode;
175
    }
176
177
    /**
178
     * 获取微信服务器ip.
179
     *
180
     * @author Tian
181
     *
182
     * @date   2015-12-08
183
     *
184
     * @return array
185
     */
186
187 View Code Duplication
    public static function getWxIpList()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
188
    {
189
        $module   = 'getcallbackip';
190
        $queryStr = [];
191
        $res      = self::_get($module, '', $queryStr);
192
        if (!$res) {
193
            exit(self::getError());
0 ignored issues
show
Coding Style Compatibility introduced by
The method getWxIpList() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
194
        }
195
196
        return $res;
197
    }
198
199
    /**
200
     * 获取AppId
201
     *
202
     * @return string AppId
203
     */
204
    public static function getAppId()
205
    {
206
        return self::$APP_ID;
207
    }
208
209
    public static function getComponentAppId()
210
    {
211
        return self::$COMPONENT_APPID;
212
    }
213
214
    /**
215
     * 获取ENCODING_AES_KEY
216
     *
217
     * @return string ENCODING_AES_KEY
218
     */
219
    public static function getEncoding_Aes_Key()
220
    {
221
        return self::$COMPONENT_ENCODING_AES_KEY;
222
    }
223
224
    /**
225
     * 获取TOKEN
226
     *
227
     * @return string TOKEN
228
     */
229
    public static function getToken()
230
    {
231
        return self::$COMPONENT_TOKEN;
232
    }
233
234
    /**
235
     * 获取AppSecret
236
     *
237
     * @return string AppSecret
238
     */
239
    public static function getAppSecret()
240
    {
241
        return self::$COMPONENT_APPSECRET;
242
    }
243
244
    /**
245
     * 用get的方式访问接口.
246
     *
247
     * @author Tian
248
     *
249
     * @date   2015-12-08
250
     *
251
     * @param string $module   指定接口模块
252
     * @param string $node     指定接口模块的节点
253
     * @param array  $queryStr 查询字符串
254
     * @param bool   $arsort   是否排序
255
     * @param string $apitype  api类型
256
     *
257
     * @return array|bool 错误时返回false
258
     */
259 View Code Duplication
    public static function _get($module, $node, $queryStr = [], $arsort = true, $apitype = 'cgi-bin')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
260
    {
261
        //不需要 token 参数
262
        $no_module = ['token', 'showqrcode'];
263
264
        $no_apitye = ['sns'];
265
266
        if (in_array($apitype, $no_apitye) || in_array($module, $no_module)) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
267
            //$queryStr = $queryStr;
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
268
        } elseif ($module != 'token') {
269
            $info = self::getAccessToken();
270
271
            if (false == $info) {
272
                return false;
273
            }
274
            $queryStr['access_token'] = $info;
275
        }
276
277
        if ($arsort) {
278
            arsort($queryStr);
279
        }
280
281
        $queryStr = http_build_query($queryStr);
282
283
        if (!empty($node)) {
284
            $node = '/' . $node;
285
        }
286
287
        $apiUrl = rtrim(self::$API_URL . $apitype . '/' . $module . $node, '/');
288
        $apiUrl .= '?' . $queryStr;
289
290
        $apiUrl = urldecode($apiUrl);
291
        $ch     = curl_init($apiUrl);
292
        curl_setopt($ch, CURLOPT_URL, $apiUrl);
293
        curl_setopt($ch, CURLOPT_TIMEOUT, 60);
294
        curl_setopt($ch, CURLOPT_HEADER, true);
295
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
296
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
297
298
        $res      = curl_exec($ch);
299
        $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
300
        curl_close($ch);
301
302
        $header = '';
303
        $body   = $res;
304
        if ($httpcode == 200) {
305
            list($header, $body) = explode("\r\n\r\n", $res, 2);
306
            $header = self::http_parse_headers($header);
307
        }
308
309
        $result           = [];
310
        $result['info']   = $body;
311
        $result['header'] = $header;
312
        $result['status'] = $httpcode;
313
314
        $rest = self::packData($result);
315
        if ($rest == 'retry') {
316
            return self::get_retry($apiUrl);
317
        } else {
318
            return $rest;
319
        }
320
    }
321
322
    /**
323
     * 用post的方式访问接口.
324
     *
325
     * @author Tian
326
     *
327
     * @date   2015-12-08
328
     *
329
     * @param string $module     指定接口模块
330
     * @param string $node       指定接口模块的节点
331
     * @param array  $data       要发送的数据
332
     * @param bool   $jsonEncode 是否转换为jsons数据
333
     * @param string $apitype    Api类型
334
     *
335
     * @return array|bool 错误时返回false;
336
     */
337
    public static function _post($module, $node, $data, $jsonEncode = true, $apitype = 'cgi-bin')
338
    {
339
        //$postQueryStr = self::$postQueryStr;
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
340
341
        $postQueryStr['access_token'] = self::getAccessToken();
0 ignored issues
show
Coding Style Comprehensibility introduced by
$postQueryStr was never initialized. Although not strictly required by PHP, it is generally a good practice to add $postQueryStr = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
342
343
        if (false == $postQueryStr) {
344
            return false;
345
        }
346
347
        if (!empty($node)) {
348
            $node = '/' . $node;
349
        }
350
351
        $apiUrl = rtrim(self::$API_URL . $apitype . '/' . $module . $node, '/');
352
353
        asort($postQueryStr);
354
355
        $postQueryStr = http_build_query($postQueryStr);
356
357
        $apiUrl .= '?' . $postQueryStr;
358
359 View Code Duplication
        if ($jsonEncode) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
360
            if (is_array($data)) {
361
                if (!defined('JSON_UNESCAPED_UNICODE')) {
362
                    // 解决php 5.3版本 json转码时 中文编码问题.
363
                    $data = json_encode($data);
364
                    $data = preg_replace("#\\\u([0-9a-f]{4})#ie", "iconv('UCS-2BE', 'UTF-8', pack('H4', '\\1'))", $data);
365
                } else {
366
                    $data = json_encode($data, JSON_UNESCAPED_UNICODE);
367
                }
368
            }
369
        }
370
371
        $apiUrl = urldecode($apiUrl);
372
        $ch     = curl_init();
373
374
        // CURLOPT_SAFE_UPLOAD php 5.5 中添加,默认值为false,5.6中默认值为true,7.0+ 没有该设置项
375
        if (version_compare(PHP_VERSION, '5.5', '>=') && version_compare(PHP_VERSION, '7', '<')) {
376
            curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false);
377
        }
378
379
        curl_setopt($ch, CURLOPT_URL, $apiUrl);
380
        curl_setopt($ch, CURLOPT_TIMEOUT, 60);
381
        curl_setopt($ch, CURLOPT_HEADER, true);
382
        curl_setopt($ch, CURLOPT_NOBODY, false);
383
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
384
        curl_setopt($ch, CURLOPT_POST, 1);
385
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
386
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
387
388
        $res      = trim(curl_exec($ch));
389
        $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
390
        curl_close($ch);
391
392
        $header = '';
393
        $body   = $res;
394
        if ($httpcode == 200) {
395
            list($header, $body) = explode("\r\n\r\n", $res, 2);
396
            //list($header, $body) = explode("keep-alive", $res, 2);
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
397
            $header = self::http_parse_headers($header);
398
        }
399
400
        $result           = [];
401
        $result['info']   = $body;
402
        $result['header'] = $header;
403
        $result['status'] = $httpcode;
404
405
        $rest = self::packData($result);
406
407
        if ($rest === 'retry') {
408
            return self::post_retry($apiUrl, $data);
409
        } else {
410
            return $rest;
411
        }
412
    }
413
414
    /**
415
     * 对接口返回的数据进行验证和组装.
416
     *
417
     * @author Tian
418
     *
419
     * @date   2015-12-08
420
     *
421
     * @param array $apiReturnData 由_post|| _get方法返回的数据.
422
     *
423
     * @return array|bool
424
     */
425 View Code Duplication
    public static function packData($apiReturnData)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
426
    {
427
        $status     = $apiReturnData['status'];
428
        $header     = $apiReturnData['header'];
429
        $returnData = $apiReturnData['info'];
430
431
        if ($status != 200 && empty($returnData)) {
432
            self::setError('接口服务器连接失败.');
433
434
            return false;
435
        }
436
        $apiReturnData     = json_decode($returnData, true);
437
        $apiData           = [];
438
        $apiData['status'] = $status;
439
        $apiData['header'] = $header;
440
        $apiData['info']   = $apiReturnData;
441
442
        self::setApiData($apiData);
443
444
        if (!$apiReturnData && substr($header['Content-Type'], 0, 16) != 'application/json') {
445
            $apiReturnData            = [];
446
            $apiReturnData['content'] = $returnData;
447
            $apiReturnData['type']    = $header['Content-Type'];
448
            $apiReturnData['size']    = $header['Content-Length'];
449
450
            return $apiReturnData;
451
        }
452
453
        if ($status != 200 && !$apiReturnData) {
454
            self::setError($returnData);
455
456
            return false;
457
        }
458
459
        if (isset($apiReturnData['errcode']) && ($apiReturnData['errcode'] == 42001 || $apiReturnData['errcode'] == 40001)) {
460
            $error = '错误码:' . $apiReturnData['errcode'] . ', 错误信息:' . $apiReturnData['errmsg'] . '-已重新刷新access_token';
461
462
            //强制刷新 AccessToken
463
            self::getAccessToken();
0 ignored issues
show
Unused Code introduced by
The call to the method Wechat\ComponentApi::getAccessToken() seems un-needed as the method has no side-effects.

PHP Analyzer performs a side-effects analysis of your code. A side-effect is basically anything that might be visible after the scope of the method is left.

Let’s take a look at an example:

class User
{
    private $email;

    public function getEmail()
    {
        return $this->email;
    }

    public function setEmail($email)
    {
        $this->email = $email;
    }
}

If we look at the getEmail() method, we can see that it has no side-effect. Whether you call this method or not, no future calls to other methods are affected by this. As such code as the following is useless:

$user = new User();
$user->getEmail(); // This line could safely be removed as it has no effect.

On the hand, if we look at the setEmail(), this method _has_ side-effects. In the following case, we could not remove the method call:

$user = new User();
$user->setEmail('email@domain'); // This line has a side-effect (it changes an
                                 // instance variable).
Loading history...
464
465
            self::setError($error);
466
467
            $rest = 'retry';
468
469
            return $rest;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $rest; (string) is incompatible with the return type documented by Wechat\ComponentApi::packData of type array|boolean.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
470
        }
471
472
        if (isset($apiReturnData['errcode']) && $apiReturnData['errcode'] != 0) {
473
            $error = '错误码:' . $apiReturnData['errcode'] . ', 错误信息:' . $apiReturnData['errmsg'];
474
475
            self::setError($error);
476
477
            return false;
478
        }
479
480
        if (isset($apiReturnData['errcode'])) {
481
            unset($apiReturnData['errcode']);
482
        }
483
484
        if (count($apiReturnData) > 1 && isset($apiReturnData['errmsg'])) {
485
            unset($apiReturnData['errmsg']);
486
        }
487
488
        if (count($apiReturnData) == 1) {
489
            $apiReturnData = reset($apiReturnData);
490
        }
491
492
        return $apiReturnData;
493
    }
494
495
    /**
496
     * 接口加密方法.
497
     *
498
     * @param string $data   要加密的字符串
499
     * @param string $key    加密密钥
500
     * @param int    $expire 过期时间 单位 秒
501
     *
502
     * @return string
503
     */
504 View Code Duplication
    public static function encrypt($data, $key, $expire = 0)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
505
    {
506
        $data = base64_encode($data);
507
        $x    = 0;
508
        $len  = strlen($data);
509
        $l    = strlen($key);
510
        $char = '';
511
512
        for ($i = 0; $i < $len; $i++) {
513
            if ($x == $l) {
514
                $x = 0;
515
            }
516
            $char .= substr($key, $x, 1);
517
            $x++;
518
        }
519
520
        $str = sprintf('%010d', $expire ? $expire + time() : 0);
521
522
        for ($i = 0; $i < $len; $i++) {
523
            $str .= chr(ord(substr($data, $i, 1)) + (ord(substr($char, $i, 1))) % 256);
524
        }
525
526
        return rawurlencode(str_replace('=', '', base64_encode($str)));
527
    }
528
529
    /**
530
     * 解析头信息
531
     *
532
     * @param $raw_headers
533
     *
534
     * @return array
535
     */
536 View Code Duplication
    public static function http_parse_headers($raw_headers)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
537
    {
538
        $headers = [];
539
        $key     = ''; // [+]
540
541
        foreach (explode("\n", $raw_headers) as $i => $h) {
542
            $h = explode(':', $h, 2);
543
544
            if (isset($h[1])) {
545
                if (!isset($headers[$h[0]])) {
546
                    $headers[$h[0]] = trim($h[1]);
547
                } elseif (is_array($headers[$h[0]])) {
548
                    // $tmp = array_merge($headers[$h[0]], array(trim($h[1]))); // [-]
0 ignored issues
show
Unused Code Comprehensibility introduced by
73% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
549
                    // $headers[$h[0]] = $tmp; // [-]
0 ignored issues
show
Unused Code Comprehensibility introduced by
65% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
550
                    $headers[$h[0]] = array_merge($headers[$h[0]], [trim($h[1])]); // [+]
551
                } else {
552
                    // $tmp = array_merge(array($headers[$h[0]]), array(trim($h[1]))); // [-]
0 ignored issues
show
Unused Code Comprehensibility introduced by
75% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
553
                    // $headers[$h[0]] = $tmp; // [-]
0 ignored issues
show
Unused Code Comprehensibility introduced by
65% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
554
                    $headers[$h[0]] = array_merge([$headers[$h[0]]], [trim($h[1])]); // [+]
555
                }
556
557
                $key = $h[0]; // [+]
558
            } else {
559
                // [+]
560
                // [+]
561
                if (substr($h[0], 0, 1) == "\t") {
562
                    // [+]
563
                    $headers[$key] .= "\r\n\t" . trim($h[0]);
564
                } // [+]
565
                elseif (!$key) {
566
                    // [+]
567
                    $headers[0] = trim($h[0]);
568
                }
569
                trim($h[0]); // [+]
570
            } // [+]
571
        }
572
573
        return $headers;
574
    }
575
576
    /**
577
     * 缓存方法
578
     *
579
     * @param string $name    缓存名
580
     * @param string $value   缓存值 如果不输入值 则根据缓存名返回缓存值.
581
     * @param int    $expires 缓存过期时间 默认0 即永不超时. 单位秒
582
     *
583
     * @return bool|null|string
584
     */
585 View Code Duplication
    public static function cache($name, $value = '', $expires = 0)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
586
    {
587
        if (!$name || !is_string($name)) {
588
            self::setError('参数错误!');
589
590
            return false;
591
        }
592
593
        /** @var BaseDriver $cacheDriver */
594
        static $cacheDriver;
595
596
        if (!isset($cacheDriver)) {
597
            $cacheDriver = __NAMESPACE__ . '\\CacheDriver\\' . self::$CACHE_DRIVER . 'Driver';
598
            $cacheDriver = new $cacheDriver(__DIR__ . '/Cache/');
599
        }
600
601
        if (!$value && $value !== 0) {
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison !== seems to always evaluate to true as the types of $value (string) and 0 (integer) can never be identical. Maybe you want to use a loose comparison != instead?
Loading history...
602
            $value = $cacheDriver->_get($name);
603
            if (false == $value) {
604
                $value = null;
605
            }
606
607
            return $value;
608
        }
609
610
        $res = $cacheDriver->_set($name, $value, $expires);
611
612
        return $res ? true : false;
613
    }
614
615
    //token 刷新后重试 post
616 View Code Duplication
    public static function post_retry($apiUrl, $data)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
617
    {
618
        $urlarr = parse_url($apiUrl);
619
        parse_str($urlarr['query'], $parr);
620
621
        usleep(500000);
622
623
        $parr['access_token'] = self::getAccessToken();
624
625
        $apiUrl = $urlarr['scheme'] . '://' . $urlarr['host'] . $urlarr['path'];
626
        $apiUrl .= '?' . http_build_query($parr);
627
628
        $ch = curl_init();
629
        curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false);
630
        curl_setopt($ch, CURLOPT_URL, $apiUrl);
631
        curl_setopt($ch, CURLOPT_TIMEOUT, 60);
632
        curl_setopt($ch, CURLOPT_HEADER, true);
633
        curl_setopt($ch, CURLOPT_NOBODY, false);
634
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
635
        curl_setopt($ch, CURLOPT_POST, 1);
636
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
637
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
638
639
        $res      = trim(curl_exec($ch));
640
        $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
641
        curl_close($ch);
642
643
        $header = '';
644
        $body   = $res;
645
        if ($httpcode == 200) {
646
            list($header, $body) = explode("\r\n\r\n", $res, 2);
647
            //list($header, $body) = explode("keep-alive", $res, 2);
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
648
            $header = self::http_parse_headers($header);
649
        }
650
651
        $result           = [];
652
        $result['info']   = $body;
653
        $result['header'] = $header;
654
        $result['status'] = $httpcode;
655
656
        $rest_retry = self::packData($result);
657
        if ($rest_retry === 'retry') {
658
            return false;
659
        }
660
661
        return $rest_retry;
662
    }
663
664
    //token 刷新后重试 get
665 View Code Duplication
    public static function get_retry($apiUrl)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
666
    {
667
        $urlarr = parse_url($apiUrl);
668
        parse_str($urlarr['query'], $parr);
669
670
        usleep(500000);
671
672
        $parr['access_token'] = self::getAccessToken();
673
674
        $apiUrl = $urlarr['scheme'] . '://' . $urlarr['host'] . $urlarr['path'];
675
        $apiUrl .= '?' . http_build_query($parr);
676
677
        $apiUrl = urldecode($apiUrl);
678
        $ch     = curl_init($apiUrl);
679
        curl_setopt($ch, CURLOPT_URL, $apiUrl);
680
        curl_setopt($ch, CURLOPT_TIMEOUT, 60);
681
        curl_setopt($ch, CURLOPT_HEADER, true);
682
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
683
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
684
685
        $res      = curl_exec($ch);
686
        $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
687
        curl_close($ch);
688
689
        $header = '';
690
        $body   = $res;
691
        if ($httpcode == 200) {
692
            list($header, $body) = explode("\r\n\r\n", $res, 2);
693
            $header = self::http_parse_headers($header);
694
        }
695
696
        $result           = [];
697
        $result['info']   = $body;
698
        $result['header'] = $header;
699
        $result['status'] = $httpcode;
700
701
        $rest_retry = self::packData($result);
702
703
        if ($rest_retry === 'retry') {
704
            return false;
705
        }
706
707
        return $rest_retry;
708
    }
709
}
710