arnapou / appcfg
Requires
- php: ~8.3.0
- arnapou/ensure: ^2.3
Requires (Dev)
- ext-yaml: *
- friendsofphp/php-cs-fixer: ^3.52
- phpstan/extension-installer: ^1.3
- phpstan/phpstan: ^1.10
- phpstan/phpstan-deprecation-rules: ^1.1
- phpstan/phpstan-phpunit: ^1.3
- phpstan/phpstan-strict-rules: ^1.5
- phpunit/php-code-coverage: ^11.0
- phpunit/phpunit: ^11.0
- psr/clock: ^1.0
README
应用配置系统。
安装
composer require arnapou/appcfg
packagist 👉️ arnapou/appcfg
简介
该库的全球目标是管理您的应用配置。
主要功能包括
- 允许覆盖机制:主机名 > 环境 > 通用。
- 形式为
%<处理器>(<标签>:<值>)%
的表达式解析器,以在您的配置中管理依赖值,并可以添加自定义处理器。 - 将编译后的配置转储到适当的 PHP 类型对象中,100% 兼容您的静态分析工具。
解析器
查看 Parser 类。
解析字符
%
是封装字符,如果存在冲突(例如包含%something(
的字符串),则双重使用%%
来转义,然后转义到%%something(
。()
括号用于收集表达式的部分%env(VAR)%
:
冒号用于分隔标签和值%env(VAR:value)%
示例
%<处理器>(<标签>)%
: 无值表达式%<处理器>(<标签>:<值>)%
: 主要表达式%<处理器>(<标签>:<字符串>%<处理器>(<标签>)%<字符串>)%
: 值部分中允许嵌套
简化表达式
%标签%
等同于%(标签)%
(处理器 =''
)- 仅
- 在第一级(不嵌套)
- 使用这些字符
a-zA-Z0-9_.-
不希望转义 %
的情况
字符串 | 其中 | 转义 | 说明 |
---|---|---|---|
%% | 任何地方 | %%%% | %% 是 % 的转义形式 |
%word( | 任何地方 | %%word( | 双重使用 % 避免解析器将其视为表达式 |
)% | nested value | %(:))%% | 我们使用表达式 %(:<default>)% 来隔离 ) 和 % ,其中 <default> 是 ) |
注意:如果对 %
的使用没有疑问,则解析器对 %
的处理比较宽松。例如,写作 foo%bar baz
是有效的,因为它显然不是一个表达式。但写作 foo%%bar baz
也是有效的,因为这与带有转义 %
的相同字符串。
捆绑处理器
- DefaultProcessor,名称为
''
:用于管理具有其他值路径的默认值(例如,parameter.database.name
)。 - EnvProcessor,名称为
'env'
:用于检索带有可选默认值的环境变量。
解析后的字符串是一个完整的不可变对象结构,如下所示。
注意,如果您将 Expression 转换为字符串,您将得到原始的原始字符串。
Processor
Processor 是一个接口,可以将值计算为结果。
如果由于依赖项尚未处理而无法计算值,则需要返回一个 ProcessorStatus 对象。
DefaultProcessor
默认情况下在Processors中添加,名称为''
这是主处理器,允许检索其他上下文值。
parameters:
foo: 'Hello World'
bar: '%(parameters.foo)%'
baz: '%(parameters.foo:default)%'
boo: '%parameters.baz%'
EnvProcessor
默认情况下在Processors中添加,名称为'env'
替换环境变量
parameters:
mandatory: '%env(VARIABLE)%'
with.default: '%env(VARIABLE:<default>)%'
FilterProcessor
需要显式添加,名称为:'filter'
。
应用一些过滤器
parameters:
# basic cast
cast.to.string: '%filter(string:<value>)%'
cast.to.int: '%filter(int:<value>)%'
cast.to.float: '%filter(float:<value>)%'
cast.to.bool: '%filter(bool:<value>)%'
# null allowed in casting
cast.to.nullable.string: '%filter(?string:<value>)%'
cast.to.nullable.int: '%filter(?int:<value>)%'
cast.to.nullable.float: '%filter(?float:<value>)%'
cast.to.nullable.bool: '%filter(?bool:<value>)%'
# string functions
string.md5: '%filter(md5:<value>)%'
string.sha1: '%filter(sha1:<value>)%'
string.capitalize: '%filter(capitalize:<value>)%'
string.lower: '%filter(lower:<value>)%'
string.upper: '%filter(upper:<value>)%'
# string+array functions
value.length: '%filter(length:<value>)%'
JsonProcessor
需要显式添加,名称为:'json'
。
应用一些过滤器
parameters:
json.decode: '%json(decode:<value>)%'
json.encode: '%json(encode:<value>)%'
DateProcessor
需要显式添加,名称为:'date'
。
格式化日期
parameters:
YYYY-MM-DD: '%date(Y-m-d:<value>)%'
RFC3339: '%date(Y-m-d\TH\:i\:sP:<value>)%' # escape the colons of the format
# you can use php date special values
# see https://php.ac.cn/manual/en/datetime.formats.php
special: '%date(Y-m-d:10 june next year)%'
timestamp: '%date(Y-m-d:1718990615)%'
# or DateTimeInterface constants
ATOM: '%date(ATOM:1718990615)%'
RFC3339: '%date(RFC3339:1718990615)%'
W3C: '%date(W3C:1718990615)%'
Compiler
一个Compiler接口可以将输入数组编译成另一个。
StaticCompiler
编译后的数组只包含编译后的标量。此编译器不显式管理循环,但具有最大遍历安全限制。
Dumper
一个Dumper接口可以将输入数组渲染成PHP代码。
StaticDumper
为您的配置结构中的每个关联数组生成PHP类型对象。100%与PHPStan等分析工具兼容。渲染的对象可以是可变的或不可变的(默认)。
DataSource / Appcfg
一个DataSource接口负责管理数据源,以便由Appcfg使用。
Appcfg是一个简单的具体类,基本上是一个指挥家,可以对前面所有对象执行多种经典操作。
示例
输入数据
$data = [
'db' => [
'main' => [
'host' => 'localhost',
'port' => 3306,
'name' => 'project_main',
'password' => 'project_password',
],
'data' => [
'host' => '%(db.main.host)%',
'port' => '%(db.main.port)%',
'name' => 'project_data',
'password' => '%(db.main.password)%',
],
],
'db|prod' => [
'main' => [
'password' => '%env(DB_PASSWORD)%',
],
],
];
💡 如果表达式独立存在,如
db.data.port
,则编译时保留引用类型(如上述示例中的int
)。
编译 & 渲染
use Arnapou\Appcfg\Compiler\CompileOptions;
use Arnapou\Appcfg\Compiler\StaticCompiler;
use Arnapou\Appcfg\Dumper\DumpOptions;
use Arnapou\Appcfg\Dumper\StaticDumper;
$compiler = new StaticCompiler();
$compiled = $compiler->compile($data, new CompileOptions('prod'));
$dumper = new StaticDumper();
echo $dumper->dump($compiled, new DumpOptions('MyProject\Config'));
结果
运行命令: DB_PASSWORD=123456 php example/readme.php
namespace MyProject;
final readonly class ConfigDbMain
{
public function __construct(
public string $host = 'localhost',
public int $port = 3306,
public string $name = 'project_main',
public string $password = '123456',
) {}
}
final readonly class ConfigDbData
{
public function __construct(
public string $host = 'localhost',
public int $port = 3306,
public string $name = 'project_data',
public string $password = '123456',
) {}
}
final readonly class ConfigDb
{
public function __construct(
public ConfigDbMain $main = new ConfigDbMain(),
public ConfigDbData $data = new ConfigDbData(),
) {}
}
final readonly class Config
{
public function __construct(
public ConfigDb $db = new ConfigDb(),
) {}
}
PHP版本
日期 | 参考 | 8.3 |
---|---|---|
01/01/2024 | 1.x,主要 | × |