GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( abd501...0949e1 )
by t
126:30 queued 61:30
created

I::get()   D

Complexity

Conditions 19
Paths 15

Size

Total Lines 43
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 0
Metric Value
cc 19
eloc 36
c 3
b 1
f 0
nc 15
nop 3
dl 0
loc 43
rs 4.5166

How to fix   Complexity   

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
/**
3
 * Class I
4
 *
5
 * @link https://www.icy2003.com/
6
 * @author icy2003 <[email protected]>
7
 * @copyright Copyright (c) 2017, icy2003
8
 */
9
namespace icy2003\php;
10
11
use Exception;
12
use icy2003\php\icomponents\file\LocalFile;
13
use icy2003\php\ihelpers\Strings;
14
use ReflectionClass;
15
16
/**
17
 * I 类
18
 */
19
class I
20
{
21
22
    /**
23
     * 获取值
24
     *
25
     * 支持类型:数组对象和 null、数字和字符串、布尔值、回调函数,依据数据类型有不同的含义(但是都很合理)
26
     *
27
     * @param mixed $mixed 混合类型
28
     *      - 当 $mixed 为**数组或对象**时,此方法用于按照层级获取值,用法如下:
29
     *          1. 对于一个多维数组 $array 来说,a.b.cd_ef 会拿 $array['a']['b']['cd_ef'] 的值
30
     *          2. 如果 $array['a'] 是对象,则先检查 getB 方法,然后检查 b 属性
31
     *          3. 如果 $array['a']['b'] 是对象,则检查 getCdEf 方法,然后检查 cd_ef 属性
32
     *      - 当 $mixed 为**布尔值**(即表达式)时,等价于三元操作符,例如 I::get(1 > 2, '真', '假')
33
     *      - 当 $mixed 为**字符串或数字**时,等价于 Strings::sub,截取字符串
34
     *      - 当 $mixed 为 **null** 时,含义可被描述为:在使用 I::get($array, 'a.b', 1),$array 意外的是 null,返回 1 是理所当然的
35
     *      - 当 $mixed 为**回调函数**,$mixed 的执行结果将作为 I::get 的返回值
36
     * @param mixed $keyString 取决于 $mixed 的类型:
37
     *      - 当 $mixed 为**数组或对象**时,$keyString 表示:点(.)分割代表层级的字符串,下划线用于对象中转化成驼峰方法,支持数组和对象嵌套
38
     *      - 当 $mixed 为**布尔值**(即表达式)时,$keyString 表示:$mixed 为 true 时返回的值
39
     *      - 当 $mixed 为**字符串或数字**时,$keyString 强制转为整型,表示:截取 $mixed 时,子串的起始位置
40
     *      - 当 $mixed 为 **null** 时,此参数无效
41
     *      - 当 $mixed 为**回调函数**,如果 $mixed 的返回值代表 true(如:1),则执行此回调
42
     * @param mixed $defaultValue 取决于 $mixed 的类型:
43
     *      - 当 $mixed 为**数组或对象**时,$defaultValue 表示:拿不到值时会直接返回该默认值
44
     *      - 当 $mixed 为**布尔值**(即表达式)时,$defaultValue 表示:$mixed 为 false 时返回的值
45
     *      - 当 $mixed 为**字符串或数字**时,$defaultValue 表示:截取 $mixed 时,子串的长度,null 时表示长度为 1
46
     *      - 当 $mixed 为 **null** 时,返回 $defaultValue
47
     *      - 当 $mixed 为**回调函数**,如果 $mixed 的返回值代表 false(如:0),则执行此回调
48
     *
49
     * @return mixed
50
     */
51
    public static function get($mixed, $keyString, $defaultValue = null)
52
    {
53
        if (true === $mixed) {
54
            return $keyString;
55
        } elseif (false === $mixed) {
56
            return $defaultValue;
57
        } elseif (is_array($mixed) || is_object($mixed)) {
58
            $keyArray = explode('.', $keyString);
59
            foreach ($keyArray as $key) {
60
                if (is_array($mixed)) {
61
                    if (array_key_exists($key, $mixed) && null !== $mixed[$key]) {
62
                        $mixed = $mixed[$key];
63
                    } else {
64
                        return $defaultValue;
65
                    }
66
                } elseif (is_object($mixed)) {
67
                    $method = 'get' . ucfirst(Strings::toCamel($key));
68
                    if (method_exists($mixed, $method)) {
69
                        $mixed = $mixed->$method();
70
                    } elseif (property_exists($mixed, $key) && null !== $mixed->$key) {
71
                        $mixed = $mixed->$key;
72
                    } else {
73
                        return $defaultValue;
74
                    }
75
                } else {
76
                    return $defaultValue;
77
                }
78
            }
79
            return $mixed;
80
        } elseif (is_string($mixed) || is_numeric($mixed)) {
81
            $pos = (int) $keyString;
82
            $length = null === $defaultValue ? 1 : (int) $defaultValue;
83
            return Strings::sub($mixed, $pos, $length);
84
        } elseif (null === $mixed) {
85
            return $defaultValue;
86
        } elseif (is_callable($mixed)) {
87
            $result = self::trigger($mixed);
88
            if ($result) {
89
                self::trigger($keyString);
90
            } else {
91
                self::trigger($defaultValue);
92
            }
93
            return $result;
94
        }
95
    }
96
97
    /**
98
     * 设置值
99
     *
100
     * @param array|object $mixed 对象或数组
101
     * @param string $key 键
102
     * @param mixed $value 值
103
     * @param boolean $overWrite 如果对应的值存在,是否用给定的值覆盖,默认 true,即:是
104
     *
105
     * @return mixed
106
     */
107
    public static function set(&$mixed, $key, $value, $overWrite = true)
108
    {
109
        $get = self::get($mixed, $key);
110
        if (null === $get || true === $overWrite) {
111
            if (is_array($mixed)) {
112
                $mixed[$key] = $value;
113
            } elseif (is_object($mixed)) {
114
                $method = 'set' . ucfirst(Strings::toCamel($key));
115
                if (method_exists($mixed, $method)) {
116
                    $mixed->$method($value);
117
                } elseif (property_exists($mixed, $key)) {
118
                    $mixed->$key = $value;
119
                } else {
120
                    throw new Exception('无法设置值');
121
                }
122
            }
123
            return $value;
124
        }
125
        return $get;
126
    }
127
128
    /**
129
     * 触发回调
130
     *
131
     * @param callback $callback 回调函数
132
     * @param array $params 回调参数
133
     * @return mixed
134
     */
135
    public static function trigger($callback, $params = [])
136
    {
137
        $result = false;
138
        is_callable($callback) && $result = call_user_func_array($callback, $params);
139
        return $result;
140
    }
141
142
    /**
143
     * 定义一个常量
144
     *
145
     * @param string $constant 常量名
146
     * @param mixed $value 值
147
     *
148
     * @return void
149
     */
150
    public static function def($constant, $value)
151
    {
152
        defined($constant) || define($constant, $value);
153
    }
154
155
    /**
156
     * 让 empty 支持函数调用
157
     *
158
     * 注意:此函数并不比 empty 好,只是为了让 empty 支持函数调用
159
     *
160
     * 例如:empty($array[0]) 就不能用此函数代替,另外,empty 是语法结构,性能明显比函数高
161
     *
162
     * @see http://php.net/manual/zh/function.empty.php
163
     *
164
     * @param mixed $data
165
     * @return boolean
166
     */
167
    public static function isEmpty($data)
168
    {
169
        return empty($data);
170
    }
171
172
    /**
173
     * 获取 php.ini 配置值
174
     *
175
     * @param string $key 配置名
176
     * @param mixed $default 默认值
177
     *
178
     * @return mixed
179
     */
180
    public static function phpini($key, $default = null)
181
    {
182
        if (false !== ($ini = ini_get($key))) {
183
            return $ini;
184
        }
185
        if (false !== ($ini = get_cfg_var($key))) {
186
            return $ini;
187
        }
188
        return $default;
189
    }
190
191
    /**
192
     * 显示 PHP 错误
193
     *
194
     * @param boolean $show 是否显示,默认是
195
     *
196
     * @return void
197
     */
198
    public static function displayErrors($show = true)
199
    {
200
        ini_set("display_errors", true === $show ? 'On' : 'Off');
201
        true === $show && error_reporting(E_ALL | E_STRICT);
202
    }
203
204
    /**
205
     * 别名列表
206
     *
207
     * @var array
208
     */
209
    public static $aliases = [];
210
211
    /**
212
     * 用别名获取真实路径
213
     *
214
     * @param string $alias 别名
215
     * @param bool $loadNew 是否加载新别名到 I 里,默认否
216
     *
217
     * @return string|boolean
218
     */
219
    public static function getAlias($alias, $loadNew = false)
220
    {
221
        if (strncmp($alias, '@', 1)) {
222
            return $alias;
223
        }
224
        $localFile = new LocalFile();
225
        $aliases = [
226
            '@vendor' => __DIR__ . '/../../../../vendor',
227
            '@icy2003/php_tests' => __DIR__ . '/../tests',
228
            '@icy2003/php_runtime' => __DIR__ . '/../runtime',
229
            '@icy2003/php' => __DIR__,
230
        ];
231
        foreach ($aliases as $k => $v) {
232
            if (false === array_key_exists($k, static::$aliases)) {
233
                static::$aliases[$k] = $localFile->getRealpath($v);
234
            }
235
        }
236
237
        $pos = 0;
238
        while (true) {
239
            $pos = strpos($alias, '/', $pos);
240
            $root = $pos === false ? $alias : substr($alias, 0, $pos);
241
            if (isset(static::$aliases[$root])) {
242
                if (is_string(static::$aliases[$root])) {
243
                    return $pos === false ? static::$aliases[$root] : static::$aliases[$root] . substr($alias, $pos);
244
                } elseif (is_array(static::$aliases[$root])) {
245
                    foreach (static::$aliases[$root] as $name => $path) {
246
                        if (strpos($alias . '/', $name . '/') === 0) {
247
                            return $path . substr($alias, strlen($name));
248
                        }
249
                    }
250
                } else {
251
                    return false;
252
                }
253
            }
254
            if ($root == $alias) {
255
                break;
256
            }
257
            $pos++;
258
        }
259
        // 对 Yii2 的支持
260
        if ($result = self::trigger(['\Yii', 'getAlias'], [$alias])) {
261
            true === $loadNew && self::setAlias($alias, $result);
262
            return $result;
263
        }
264
265
        return false;
266
    }
267
268
    /**
269
     * 是否是 Yii2 项目
270
     *
271
     * @return boolean
272
     */
273
    public static function isYii2()
274
    {
275
        return method_exists('\Yii', 'getVersion');
276
    }
277
278
    /**
279
     * 设置别名
280
     *
281
     * @param string $alias 别名
282
     * @param string|null $path 路径
283
     *
284
     * @return void
285
     */
286
    public static function setAlias($alias, $path)
287
    {
288
        // 对 Yii2 的支持
289
        self::trigger(['\Yii', 'setAlias'], [$alias, $path]);
290
        if (strncmp($alias, '@', 1)) {
291
            $alias = '@' . $alias;
292
        }
293
        $pos = strpos($alias, '/');
294
        $root = $pos === false ? $alias : substr($alias, 0, $pos);
295
        if ($path !== null) {
296
            $path = strncmp($path, '@', 1) ? rtrim($path, '\\/') : static::getAlias($path);
297
            if (!isset(static::$aliases[$root])) {
298
                if ($pos === false) {
299
                    static::$aliases[$root] = $path;
300
                } else {
301
                    static::$aliases[$root] = [$alias => $path];
302
                }
303
            } elseif (is_string(static::$aliases[$root])) {
304
                if ($pos === false) {
305
                    static::$aliases[$root] = $path;
306
                } else {
307
                    static::$aliases[$root] = [
308
                        $alias => $path,
309
                        $root => static::$aliases[$root],
310
                    ];
311
                }
312
            } else {
313
                static::$aliases[$root][$alias] = $path;
314
                krsort(static::$aliases[$root]);
315
            }
316
        } elseif (isset(static::$aliases[$root])) {
317
            if (is_array(static::$aliases[$root])) {
318
                unset(static::$aliases[$root][$alias]);
319
            } elseif ($pos === false) {
320
                unset(static::$aliases[$root]);
321
            }
322
        }
323
    }
324
325
    /**
326
     * 判断给定选项值里是否设置某选项
327
     *
328
     * @param integer $flags 选项值
329
     * @param integer $flag 待判断的选项值
330
     *
331
     * @return boolean
332
     */
333
    public static function hasFlag($flags, $flag)
334
    {
335
        return $flags === ($flag | $flags);
336
    }
337
338
    /**
339
     * 创建一个对象
340
     *
341
     * @param array $params
342
     * - class:表示类名,可使用别名
343
     * - 其他:该类的属性,初始化这些属性
344
     * @param array $config
345
     * - 构造函数传参
346
     *
347
     * @return object
348
     */
349
    public static function createObject($params, $config = [])
350
    {
351
        if (is_array($params) && isset($params['class'])) {
352
            try {
353
                $class = $params['class'];
354
                unset($params['class']);
355
                $reflection = new ReflectionClass(self::getAlias($class));
356
                $object = $reflection->newInstanceArgs($config);
357
                foreach ($params as $name => $value) {
358
                    self::set($object, $name, $value);
359
                }
360
                return $object;
361
            } catch (Exception $e) {
362
                throw new Exception('初始化 ' . $class . ' 失败', $e->getCode(), $e);
363
            }
364
        }
365
        throw new Exception('必须带 class 以指定一个类');
366
    }
367
}
368