轻量级PHP yaml配置解析器

1.0.0 2019-04-17 18:08 UTC

This package is auto-updated.

Last update: 2024-09-29 04:49:50 UTC


README

零依赖的轻量级PHP配置解析器

露西 需要 PHP 版本 >=7.0 <=7.3。在 PHP 7.3.4 上创建。

内容

  1. 简介
  2. 安装
  3. 使用
  4. API参考
  5. 设置测试

1. 简介

露西 是一个类似于 Symfony 配置组件的配置解析器,但更轻量级(无依赖)。我创建它的原因是我没有看到与之竞争的工具,所以我创建了它。我认为露西并不比 Symfony 配置组件更好。我只是喜欢有一个以上的解决方案来解决问题。

露西基本上是一个自创建的链表。当你创建整个配置树时,它为数组(树)中的每个节点创建一个自身的实例,并验证树的那部分。它是按需进行的,因此下一个节点仅在需要验证树中的下一个值时才会创建。我还没有做过任何基准测试来比较 symfony 配置组件和 露西,但它们正在进行中。希望你会喜欢它。

2. 安装

composer require mario-legenda/lucy

3. 使用

我们将从一个尽可能简单的配置数组开始。

use Lucy;

$configuration = [
    'configuration' => []
];

$lucy = new Lucy('configuration', $configuration);

$lucy->isArray('configuration');

这段简单的代码将验证 configuration 条目是否为数组。如果条目不是数组,则会抛出 Lucy\Exception\ConfigurationException,因此如果您预期配置中存在无效值,请将其放在 try/catch 块中。

所以,让我们扩展我们的示例。


use Lucy;

$configuration = [
    'configuration' => [
        'database' => [
            'host' => 'localhost',
            'database_name' => 'db_name',
            'password' => 'password',
            'user' => 'user'
        ],
        'external_service' => [
            'api_key' => 'key',
            'secret' => 'secret',
        ]
    ]
]

$lucy = new Lucy('configuration', $configuration);

$lucy
    ->isArray('configuration')
    ->cannotBeEmpty('configuration')
    ->stepInto('configuration')
        ->isArray('database')
        ->cannotBeEmpty('database')
        ->stepInto('database')
            ->isString('host')->cannotBeEmpty('host')
            ->isString('database_name')->cannotBeEmpty('host')
            ->isString('password')->cannotBeEmpty('password')
            ->isString('user')->cannotBeEmpty('user')
        ->stepOut()
        ->cannotBeEmpty('external_service')
        ->isArray('external_service')
        ->stepInto('external_service')
            ->isString('api_key')->cannotBeEmpty('api_key')
            ->isString('secret')->cannotBeEmpty('secret')

这里,我们有一个更好的示例。使用 stepInto 方法可以逐层进入嵌套数组。之后,您可以验证数组条目中的值。我们还介绍了 isStringcannotBeEmpty 方法。露西的所有公共方法都是可链的,您可以使用您希望使用的任何顺序使用它们。

其他方法包括 keyHasToExistisNumericisBooleanisEnumisAssociativeStringArray

还有一个 stepOut 方法。使用此方法,您可以向上移动树。在我们的示例中,我们之前进入了 configurationdatabase 条目,因此我们可以验证它们内部的条目。在我们完成对 database 条目的验证后,我们可以通过进入该条目来 stepOut,并通过进入该条目来验证 external_service

使用 stepIntostepOut 方法以您希望的方式遍历树。也很重要地说,露西并不知道有下一个条目可以进入。在底层,它创建了自身的实例,这些实例成为创建它们的 露西 对象的子对象。在我们的示例中,验证 database 条目的 露西 对象是创建 configuration 条目的 露西 对象的子对象。

露西还定义了条件方法。例如,isNumeric 有一个方法 isNumericIfExists。此方法正是其所宣称的。只有当条目存在时,此方法才会尝试验证它。

其他方法包括

isBooleanIfExists
isStringIfExists
cannotBeEmptyIfExists
isArrayIfExists

可调用验证

如果您想在某个特定元素上使用特定的自定义验证,可以使用可调用验证器。这些验证器接受一个闭包(匿名函数)并传递节点名称和当前的 露西 对象。

$lucy->applyCallback('configuration', function($nodeName, Lucy $lucy) {
    // $nodeName in this example is 'configuration' and
    // $lucy object can validate 'configuration' entry
    
    $lucy->cannotBeEmpty('configuration')->isArray('configuration');
});

如果您想对一个给定条目的所有子元素应用回调,可以使用 applyToSubElements

$lucy
    ->stepInto('configuration')
    ->applyToSubElementsOf(['database', 'external_service'], function($nodeName, Lucy $lucy) {
        // this method will be called twice, once for once for 'database' entry
        // and once for 'external_service' entry. Every time it is called,
        // you will get a Lucy object for those entries, so you can to something
        // like this
        
        if ($nodeName === 'database') {
            // validate 'database' entry here
        } else if ($nodeName === 'external_service') {
            // validate 'external_entry' here
        }
    });

如果不知道元素是否实际存在,也可以使用 applyToSubElementsOfIfTheyExists。在这种情况下,此方法只会在存在的元素上调用回调,并跳过其余的元素。

4. API参考

Lucy::__construct(string $nodeName, array $node, Lucy $parentNode = null)

创建一个新的 Lucy 实例。 $parentNode 用于内部 Lucy 目的,不应在客户端代码中使用。

如果 $nodeName$node 中不存在,则抛出 Lucy\Exception\ConfigurationException

Lucy::getNodeName(): string

返回当前节点名称。

Lucy::stepInto(string $nodeName, string $errorMessage)

进入 $nodeName 并创建一个新的 Lucy 对象以进行验证。

接受一个可选的 $errorMessage,该消息将被原始错误消息替换,以便更容易调试。

如果 $nodeName 不存在,则抛出 Lucy\Exception\ConfigurationException

Lucy::stepIntoIfExists(string $nodeName)

stepInto 做同样的事情,但如果节点不存在,则不会抛出异常。

Lucy::stepOut()

从当前 Lucy 对象中退出并返回到父节点。

Lucy::applyCallback(string $nodeName, Closure $closure)

将用户定义的回调应用于 $nodeName。回调将接收一个字符串 $nodeName 和一个当前 Lucy 对象(如果对象是数组,则接收该对象,否则接收 $nodeName 的索引值)。

如果 $nodeName 不存在,则抛出 Lucy\Exception\ConfigurationException

Lucy::applyToSubElement(array $childNodes, Closure $closure)

将用户定义的回调应用于所有 $childNodes。它接收当前遍历节点的 $nodeName 和一个 Lucy 对象(如果其下的条目是数组,则接收该对象,否则接收任何其他值)。

如果任何子节点不存在,则抛出 Lucy\Configuration\ConfigurationException

Lucy::applyToSubElementIfTheyExist(array $childNodes, Closure $closure)

applyToSubElements 做同样的事情,但如果其中一个子节点不存在,则不会抛出异常。如果子节点不存在,则跳过它。

Lucy::keyHasToExist(string $nodeName, string $errorMessage = null)

验证 $nodeName 是否存在。

接受一个可选的 $errorMessage,该消息将被原始错误消息替换,以便更容易调试。

如果 $nodeName 不存在,则抛出 Lucy\Exception\ConfigurationException

Lucy::cannotBeEmpty(string $nodeName, string $errorMessage = null)

验证 $nodeName 下的条目不能为空。它使用简单的 empty() PHP 函数。

如果 $nodeName 不存在,则抛出 Lucy\Exception\ConfigurationException

接受一个可选的 $errorMessage,该消息将被原始错误消息替换,以便更容易调试。

Lucy::cannotBeEmptyIfExists(string $nodeName, string $errorMessage = null)

cannotBeEmpty 做同样的事情,但如果 $nodeName 不存在,则不会抛出异常。

Lucy::isString(string $nodeName, string $errorMessage = null)

验证 $nodeName 下的条目是否为字符串。即使为空 '',字符串也被视为字符串。

如果 $nodeName 不存在,则抛出 Lucy\Exception\ConfigurationException

接受一个可选的 $errorMessage,该消息将被原始错误消息替换,以便更容易调试。

Lucy::isStringIfExists(string $nodeName, string $errorMessage = null)

isString 做同样的事情,但如果 $nodeName 不存在,则不会抛出异常。

Lucy::isNumeric(string $nodeName, string $errorMessage = null)

验证 $nodeName 下的条目是否为数值表达式。'7' 和 7 都被视为数值。底层使用 is_numeric PHP 函数。

如果 $nodeName 不存在,则抛出 Lucy\Exception\ConfigurationException

接受一个可选的 $errorMessage,该消息将被原始错误消息替换,以便更容易调试。

Lucy::isNumericIfExists(string $nodeName, string $errorMessage = null)

isNumeric 做同样的事情,但如果 $nodeName 不存在,则不会抛出异常。

Lucy::isArray(string $nodeName, string $errorMessage = null)

验证 $nodeName 下的条目是否为数组。

如果 $nodeName 不存在,则抛出 Lucy\Exception\ConfigurationException

接受一个可选的 $errorMessage,该消息将被原始错误消息替换,以便更容易调试。

Lucy::isArrayIfExists(string $nodeName, string $errorMessage = null)

isArray 做同样的事情,但不抛出异常。

Lucy::isBoolean(string $nodeName, string $errorMessage = null)

验证 $nodeName 下的值是否为布尔值。只有 truefalse 值被视为有效的布尔值。

如果 $nodeName 不存在,则抛出 Lucy\Exception\ConfigurationException

接受一个可选的 $errorMessage,该消息将被原始错误消息替换,以便更容易调试。

Lucy::isBooleanIfExists(string $nodeName, string $errorMessage = null)

isBoolean 做同样的事情,但如果 $nodeName 不存在,则不会抛出异常。

Lucy::isAssociativeStringArray(string $nodeName, string $errorMessage = null)

验证哈希表中的所有键是否都是字符串。如果任何键不是字符串,则抛出 Lucy\Exception\ConfigurationException

如果 $nodeName 不存在,则抛出 Lucy\Exception\ConfigurationException

接受一个可选的 $errorMessage,该消息将被原始错误消息替换,以便更容易调试。

Lucy::isEnum(string $nodeName, array $values, string $errorMessage = null)

验证配置中的值是否至少包含 $values 中的其中一个值。

例如...

$configuration = [
    'configuration' => [
        'one' => 1,
        'two' => 2,
        'three' => 3
    ]
]

$lucy = new Lucy('configuration', $configuration);

$lucy->isEnum('configuration', ['one']

上述代码检查 configuration 下的数组是否至少包含 $values 数组中的一个值。

如果 $nodeName 不存在,则抛出 Lucy\Exception\ConfigurationException

接受一个可选的 $errorMessage,该消息将被原始错误消息替换,以便更容易调试。

6. 设置测试

没有生产依赖项,但有开发依赖项。在您使用 git@github.com:MarioLegenda/lucy.git 克隆此存储库后,运行 composer install。测试位于 /tests 目录。