配置加载
Config 对象默认不是通过组件中 Autoloader::beans() 方法加载的,而是通过类注解的方式。
Config 中有init 方法,这个方法在对象实例化的时候,会自动执行,这个代码我们在 BeanHandler 中见到过,也就是 bean 的实例化阶段。通过跟踪 init 方法,可以看到,Config 对象支持读取两种类的配置文件,php/yaml 类型,默认使用的是 PHP 类型的配置文件。
PHP 配置文件解析器
解析器会找到主配置文件 base.php
,其他配置文件(非 base.php 的所有文件),并获取内部的配置信息。
解析器在加载 php 类型配置的时候,只要是php后缀的文件,且不是 base.php 都会将其读为配置,配置项主键为配置文件的名字,内容为配置文件中返回的关联数组。最后,会将所有其他配置文件获得的数据,先合并为一个其他配置项的关联数组,然后再将此数组和 base.php 文件的主配置进行合并(其他配置文件名的配置,会覆盖 base.php 中键名一致的主配置)。
详细代码,见 src/Parser/PhpParser.php
文件中的获取配置信息函数:
php
protected function getConfig(string $baseFileName, string $path): array
{
// 生成指定目录的迭代器对象
$iterator = DirectoryHelper::iterator($path);
$baseConfig = [];
$otherConfig = [];
/* @var SplFileInfo $splFileInfo */
// 遍历目录中的每个项目(可能是目录也可能是文件)
foreach ($iterator as $splFileInfo) {
// Ingore other extension file
$ext = $splFileInfo->getExtension();
$ext = strtolower($ext);
// 不是 php 后缀直接跳过
if ($ext != Config::TYPE_PHP) {
continue;
}
$fileName = $splFileInfo->getFilename();
$fileName = strtolower($fileName);
$filePath = $splFileInfo->getPathname();
// Exclude dir
// 如果是目录也跳过
if (is_dir($filePath)) {
continue;
}
// Base config
// 如果是 base.php 则获取其中内容作为主配置
if ($fileName == $baseFileName) {
$baseConfig = require $filePath;
continue;
}
// Other config
// 如果文件名不是 base.php,则以文件名为键名,文件内容为键值
[$key] = explode('.', $fileName);
$data = require $filePath;
// 将所有其他配置项合并为一个关联数组
ArrayHelper::set($otherConfig, $key, $data);
}
// 最后将其他配置项 merge 到主配置项上,注意 merge 覆盖原则为键名相同后边覆盖前面
return ArrayHelper::merge($baseConfig, $otherConfig);
}
Config 对象继承了 Collection 集合类,有一系列的公共操作接口,可以方便的检查、获取、写入、删除集合中的数据。具体可以参见 Collection 类。stdlib 组件中的 src/Collection.php
类。
Yaml 文件解析器
解析器会找到主配置文件 base.yaml
和其他配置文件(非 base.yaml
的所有文件),然后获取其内部配置。
Yaml 配置文件的解析流程和之前 php 文件的解析过程(配置的加载和覆盖顺序)一致,只是对文件的具体配置解析的有差异,最终都会形成配置的关联数组,放到 Config 对象之内存储到内存中。
配置的应用
config 函数调用
php
function config(string $key = null, $default = null)
{
if (!BeanFactory::hasBean('config')) {
return sprintf('${.config.%s}', $key);
}
/* @var Config $config */
$config = BeanFactory::getBean('config');
return $config->get($key, $default);
}
由以上代码可以判断出如下结论:
${.xxx}
花括号中为点开始的数据,表示引用的配置。不是以点开始的表示引用的是一个 bean 实例。
如果不是以美元符号和花括号表示的引用值,则表示这个是一个固定值,会直接注入到对应的属性或者参数中。
@Config 注解
php
@Config("data.key")