arnapou/appcfg

库 - 应用配置系统。

v1.9 2024-08-29 11:50 UTC

This package is auto-updated.

Last update: 2024-09-08 14:01:22 UTC


README

pipeline coverage

应用配置系统。

安装

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 转换为字符串,您将得到原始的原始字符串。

Parser schema

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/20241.x,主要×