Passed
Push — 8.0 ( fadba0...bf6144 )
by liu
02:42
created

Config::get()   B

Complexity

Conditions 7
Paths 8

Size

Total Lines 31
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 7.2694

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 17
c 1
b 0
f 0
nc 8
nop 2
dl 0
loc 31
ccs 14
cts 17
cp 0.8235
crap 7.2694
rs 8.8333
1
<?php
2
// +----------------------------------------------------------------------
3
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
4
// +----------------------------------------------------------------------
5
// | Copyright (c) 2006~2023 http://thinkphp.cn All rights reserved.
6
// +----------------------------------------------------------------------
7
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
8
// +----------------------------------------------------------------------
9
// | Author: liu21st <[email protected]>
10
// +----------------------------------------------------------------------
11
declare (strict_types = 1);
12
13
namespace think;
14
15
use Closure;
16
17
/**
18
 * 配置管理类
19
 * @package think
20
 */
21
class Config
22
{
23
    /**
24
     * 配置参数
25
     * @var array
26
     */
27
    protected $config = [];
28
29
    /**
30
     * 注册配置获取器
31
     * @var Closure
32
     */
33
    protected $hook;
34
35
    /**
36
     * 构造方法
37
     * @access public
38
     */
39 42
    public function __construct(protected string $path = '', protected string $ext = '.php')
40
    {
41 42
    }
42
43 36
    public static function __make(App $app)
44
    {
45 36
        $path = $app->getConfigPath();
46 36
        $ext  = $app->getConfigExt();
47
48 36
        return new static($path, $ext);
49
    }
50
51
    /**
52
     * 加载配置文件(多种格式)
53
     * @access public
54
     * @param  string $file 配置文件名
55
     * @param  string $name 一级配置名
56
     * @return array
57
     */
58 3
    public function load(string $file, string $name = ''): array
59
    {
60 3
        if (is_file($file)) {
61 3
            $filename = $file;
62
        } elseif (is_file($this->path . $file . $this->ext)) {
63
            $filename = $this->path . $file . $this->ext;
64
        }
65
66 3
        if (isset($filename)) {
67 3
            return $this->parse($filename, $name);
68
        }
69
70
        return $this->config;
71
    }
72
73
    /**
74
     * 解析配置文件
75
     * @access public
76
     * @param  string $file 配置文件名
77
     * @param  string $name 一级配置名
78
     * @return array
79
     */
80 3
    protected function parse(string $file, string $name): array
81
    {
82 3
        $type   = pathinfo($file, PATHINFO_EXTENSION);
83 3
        $config = [];
84 3
        $config = match ($type) {
85 3
            'php' => include $file,
86 3
            'yml', 'yaml' => function_exists('yaml_parse_file') ? yaml_parse_file($file) : [],
87 3
            'ini'         => parse_ini_file($file, true, INI_SCANNER_TYPED) ?: [],
88 3
            'json'        => json_decode(file_get_contents($file), true),
89 3
            default       => [],
90 3
        };
91
92 3
        return is_array($config) ? $this->set($config, strtolower($name)) : [];
0 ignored issues
show
introduced by
The condition is_array($config) is always true.
Loading history...
93
    }
94
95
    /**
96
     * 检测配置是否存在
97
     * @access public
98
     * @param  string $name 配置参数名(支持多级配置 .号分割)
99
     * @return bool
100
     */
101 3
    public function has(string $name): bool
102
    {
103 3
        if (!str_contains($name, '.') && !isset($this->config[strtolower($name)])) {
104
            return false;
105
        }
106
107 3
        return !is_null($this->get($name));
108
    }
109
110
    /**
111
     * 获取一级配置
112
     * @access protected
113
     * @param  string $name 一级配置名
114
     * @return array
115
     */
116 57
    protected function pull(string $name): array
117
    {
118 57
        $name = strtolower($name);
119
120 57
        return $this->config[$name] ?? [];
121
    }
122
123
    /**
124
     * 注册配置获取器
125
     * @access public
126
     * @param  Closure $callback
127
     * @return void
128
     */
129
    public function hook(Closure $callback)
130
    {
131
        $this->hook = $callback;
132
    }
133
134
    /**
135
     * 获取配置参数 为空则获取所有配置
136
     * @access public
137
     * @param  string $name    配置参数名(支持多级配置 .号分割)
138
     * @param  mixed  $default 默认值
139
     * @return mixed
140
     */
141 84
    public function get(?string $name = null, $default = null)
142
    {
143
        // 无参数时获取所有
144 84
        if (empty($name)) {
145
            return $this->config;
146
        }
147
148 84
        if (!str_contains($name, '.')) {
149 57
            return $this->pull($name);
150
        }
151
152 78
        $item    = explode('.', $name);
153 78
        $item[0] = strtolower($item[0]);
154 78
        $config  = $this->config;
155
156
        // 按.拆分成多维数组进行判断
157 78
        foreach ($item as $val) {
158 78
            if (isset($config[$val])) {
159 6
                $config = $config[$val];
160 75
            } elseif ($this->hook) {
161
                return $this->lazy($name, null, $default);
162
            } else {
163 75
                return $default;
164
            }
165
        }
166
167 6
        if ($this->hook) {
168
            return $this->lazy($name, $config, $default);
169
        }
170
171 6
        return $config;
172
    }
173
174
    /**
175
     * 通过获取器加载配置
176
     * @access public
177
     * @param  string  $name 配置参数
178
     * @param  mixed   $value 配置值
179
     * @param  mixed   $default 默认值
180
     * @return mixed
181
     */
182
    protected function lazy(?string $name, $value = null, $default = null)
183
    {
184
        // 通过获取器返回
185
        $result = call_user_func_array($this->hook, [$name, $value]);
186
        if (is_null($result)) {
187
            return $default;
188
        }
189
        return $result;
190
    }
191
192
    /**
193
     * 设置配置参数 name为数组则为批量设置
194
     * @access public
195
     * @param  array  $config 配置参数
196
     * @param  string $name 配置名
197
     * @return array
198
     */
199 6
    public function set(array $config, ?string $name = null): array
200
    {
201 6
        if (empty($name)) {
202
            $this->config = array_merge($this->config, array_change_key_case($config));
203
            return $this->config;
204
        }
205
206 6
        if (isset($this->config[$name])) {
207
            $result = array_merge($this->config[$name], $config);
208
        } else {
209 6
            $result = $config;
210
        }
211
212 6
        $this->config[$name] = $result;
213
214 6
        return $result;
215
    }
216
}
217