thamtech/yii2-yaml

Yii2 的 Yaml 辅助工具

资助包维护!
Liberapay

安装数: 6,061

依赖: 2

建议者: 0

安全性: 0

星标: 1

关注者: 2

分支: 1

公开问题: 0

类型:yii2-extension

v1.0.0 2021-06-13 23:48 UTC

This package is auto-updated.

Last update: 2024-09-14 07:17:46 UTC


README

Yii2 Yaml 提供了一个 Yaml 辅助工具和一个 Yaml 解析/导出扩展。

Yaml 辅助工具提供了 encode()decode()errorSummary() 方法,类似于 yii\helpers\Json

Yii2 Yaml 还包括了对 symfony/yaml 库的扩展,支持自定义 Yaml 标签表示 UnsetArrayValueReplaceArrayValue,并允许您将事件附加到处理任何其他自定义 Yaml 标签。

有关许可证信息,请检查 LICENSE 文件。

安装

安装此扩展的首选方式是通过 composer

php composer.phar require --prefer-dist thamtech/yii2-yaml

或者添加

"thamtech/yii2-yaml": "*"

到您的 composer.json 文件的 require 部分。

背景

此 Yii2 Yaml 扩展的目标是在 Yii2 中支持 Yaml,就像内置对 JSON 的支持一样。引入了一个 Yaml 辅助工具,以匹配 Yii2 内置 Json 辅助工具的 API。

此外,我们还扩展了 symfony/yaml 库,以支持对 ReplaceArrayValueUnsetArrayValue 对象的解码和编码,以用于 Yii 的 ArrayHelper::merge() 方法。您可以使用 Yii2 事件处理器在解析/解码时处理自定义标签,并在导出/编码前预处理对象。

Yii2 在 Json 辅助工具中使用 encode/decode 术语,而 symfony/yaml 使用 dump/parse 术语。我们的辅助工具在使用 encode/decode 术语方面与 Json 辅助工具保持一致。

使用方法

解码/解析

示例 Yaml

people:
    john:
        id: 1
        name: John
    # A value must be associated with a tag: either a block value (indented
    # section under the key) or an inline value.
    # Here, we demsonstrate a block value following the !yii/helpers/ReplaceArrayValue/tag:
    bob: !yii/helpers/ReplaceArrayValue
        id: 1001
        name: Bob
    # The `unsetArrayValue` handler requires that the associated value be
    # empty, so use an inline `{}`, `[]`, `false`, or `null` value.
    jane: !yii/helpers/UnsetArrayValue null
    susan: !lookupIdFromEmployeeNumber
        employee_number: 1234
        name: Susan

使用 Yaml 辅助工具的解码示例

<?php
use thamtech\yaml\helpers\Yaml;

$data = Yaml::decode($yaml);
print_r($data);

# Array
# (
#     [people] => Array
#         (
#           [john] => Array
#               (
#                   [id] => 1
#                   [name] => John
#               )
#           [bob] => yii\helpers\ReplaceArrayValue Object
#               (
#                   [value] => Array
#                       (
#                           [id] => 1001
#                           [name] => Bob
#                       )
#               )
#           [jane] => yii\helpers\UnsetArrayValue Object
#               (
#               )
#           [susan] => Symfony\Component\Yaml\Tag\TaggedValue Object
#               (
#                   [tag:Symfony\Component\Yaml\Tag\TaggedValue:private] => lookupIdFromEmployeeNumber
#                   [value:Symfony\Component\Yaml\Tag\TaggedValue:private] => Array
#                       (
#                           [employee_number] => 1234
#                           [name] => Susan
#                       )
#               )
#         )
# )

在上面的示例中,您可以看到带有 !yii/helpers/ReplaceArrayValue!yii/helpers/UnsetArrayValue 标签的键被自动替换为准备与 ArrayHelper::merge() 方法一起使用的辅助对象。

为了添加对 !lookupIdFromEmployeeNumber 标签等类似标签的自定义处理器,您可以在将配置数组传递给 Yaml::decode() 方法时指定它们。

<?php
use thamtech\yaml\helpers\Yaml;

$data = Yaml::decode($yaml, [
    'on lookupIdFromEmployeeNumber' => function ($event) {
        // get the value associated with the `!lookupIdFromEmployeeNumber` tag
        $value = $event->value;
        
        // find the person's id and add it to the value
        $value['id'] = Employee::find()
            ->select(['id'])
            ->where(['employee_number' => $value['employee_number']])
            ->scalar();
        
        // set the updated value in the event; the value set in `value` will
        // replace the `TaggedValue` object in the parsed yaml data as long as we
        // mark that the event was handled
        $event->value = $value;
        $event->handled = true;
        
        // as a shortcut, the following is equivalent to the previous two lines:
        $event->handleValue($value);
    },
]);

print_r($data);
# Array
# (
#     [people] => Array
#         (
#           [john] => Array
#               (
#                   [id] => 1
#                   [name] => John
#               )
#           [bob] => yii\helpers\ReplaceArrayValue Object
#               (
#                   [value] => Array
#                       (
#                           [id] => 1001
#                           [name] => Bob
#                       )
#               )
#           [jane] => yii\helpers\UnsetArrayValue Object
#               (
#               )
#           [susan] => Array
#               (
#                   [employee_number] => 1234
#                   [name] => Susan
#                   [id] => 1004
#               )
#         )
# )

编码/导出

要编码的数据示例

<?php
print_r($data);
# Array
# (
#     [people] => Array
#         (
#           [john] => Array
#               (
#                   [id] => 1
#                   [name] => John
#               )
#           [bob] => yii\helpers\ReplaceArrayValue Object
#               (
#                   [value] => Array
#                       (
#                           [id] => 1001
#                           [name] => Bob
#                       )
#               )
#           [jane] => yii\helpers\UnsetArrayValue Object
#               (
#               )
#           [susan] => Some\Package\EmployeeWithoutId Object
#               (
#                   [employee_number:Some\Package\EmployeeWithoutId:private] => 1234
#                   [name:Some\Package\EmployeeWithoutId:private] => Susan
#               )
#         )
# )

使用标准 symfony/yaml 库进行导出

<?php
use Symfony\Component\Yaml\Yaml;

$yaml = Yaml::dump($data);
echo $yaml;
# people:
#     john:
#         id: 1
#         name: John
#     bob: null
#     jane: null
#     susan: null

使用我们的默认 Yaml 辅助工具进行导出

<?php
use Symfony\Component\Yaml\Yaml;

$yaml = Yaml::dump($data);
echo $yaml;
# people:
#     john:
#         id: 1
#         name: John
#     bob: !yii/helpers/ReplaceArrayValue
#         id: 1001
#         name: Bob
#     jane: !yii/helpers/UnsetArrayValue null
#     susan: null

在上面的示例中,您可以看到带有 !yii/helpers/ReplaceArrayValue!yii/helpers/UnsetArrayValue 标签的键被自动从 ReplaceArrayValueUnsetArrayValue 对象编码。

为了添加对 EmployeeWithoutId 对象等类似值的自定义处理器,您可以在将配置数组传递给 Yaml::decode() 方法时指定它们。

<?php
use thamtech\yaml\helpers\Yaml;
use Symfony\Component\Yaml\Tag\TaggedValue;

$yaml = Yaml::encode($data, [
    'on Some\Package\EmployeeWithoutId' => function ($event) {
        // get the EmployeeWithoutId object
        $value = $event->value;
        
        // decode the object into a TaggedValue object
        $event->value = new TaggedValue('lookupIdFromEmployeeNumber', [
            'employee_number' => $value->getEmployeeNumber(),
            'name' => $value->getName(),
        ]);
        $event->handled = true;
        
        // as a shortcut, the following is equivalent to setting `$event->value`
        // and setting `$event->handled = true`.
        $event->handleValue(
            new TaggedValue('lookupIdFromEmployeeNumber', [
                'employee_number' => $value->getEmployeeNumber(),
                'name' => $value->getName(),
            ])
        );
    },
]);

echo $yaml;
# people:
#     john:
#         id: 1
#         name: John
#     bob: !yii/helpers/ReplaceArrayValue/
#         id: 1001
#         name: Bob
#     jane: !yii/helpers/UnsetArrayValue null
#     susan: !lookupIdFromEmployeeNumber
#         employee_number: 1234
#         name: Susan

配置默认处理器

您可能不想每次调用 Yaml::encode()Yaml::decode() 时都发送一个包含一个或多个自定义处理器的配置数组。Yaml 组件将其默认的 ParserDumper 定义设置到 Yii::$container 中。您可以在那里设置自己的默认 ParserDumper 定义,并使用您自己的处理器。

默认不使用任何处理器(甚至不包括 Yaml 组件的默认处理器)

<?php
use Yii;

Yii::$container->set('thamtech\yaml\Parser');
Yii::$container->set('thamtech\yaml\Dumper');

// alternatively, in your application configuration:
[
    'container' => [
        'definitions' => [
            'thamtech\yaml\Parser' => [],
            'thamtech\yaml\Dumper' => [],
        ],
    ],
];

然而,您更有可能希望从 Yaml 组件的默认处理器开始,并覆盖它们或添加您自己的。使用 Yaml::getDumperDefinition()Yaml::getParserDefinition() 方法是方便地获取准备设置到 Yii::$container 中的 Parser 和 Dumper 定义的方式。

use Yii;
use thamtech\yaml\helpers\Yaml;

Yii::$container->setDefinitions([
    'thamtech\yaml\Parser' => Yaml::getParserDefinition([
        // example: we are calling getParserDefinition() to use `Yaml`'s default
        // definitions as a base, but these lines shows how we can alter those
        // default definitions. In this case, we remove the 'ReplaceArrayValue'
        // and 'UnsetArrayValue' handlers by unsetting their array keys:
        'on yii/helpers/ReplaceArrayValue' => new \yii\helpers\UnsetArrayValue(),
        'on yii/helpers/UnsetArrayValue' => new \yii\helpers\UnsetArrayValue(),
        
        // example: adding your own handler
        'on lookupIdFromEmployeeNumber' => function ($event) {
            // get the value associated with the `!lookupIdFromEmployeeNumber` tag
            $value = $event->value;
            
            // find the person's id and add it to the value
            $value['id'] = Employee::find()
                ->select(['id'])
                ->where(['employee_number' => $value['employee_number']])
                ->scalar();
            
            // set the updated value in the event; the value set in `value` will
            // replace the `TaggedValue` object in the parsed yaml data as long as we
            // mark that the event was handled
            $event->value = $value;
            $event->handled = true;
            
            // as a shortcut, the following is equivalent to the previous two lines:
            $event->handleValue($value);
        },
    ]),
    'thamtech\yaml\Dumper' => Yaml::getDumperDefinition([
        // example: we are calling getDumperDefinition() to use `Yaml`'s default
        // definitions as a base, but these lines shows how we can alter those
        // default definitions. In this case, we remove the 'ReplaceArrayValue'
        // and 'UnsetArrayValue' handlers by unsetting their array keys:
        'on yii/helpers/ReplaceArrayValue' => new \yii\helpers\UnsetArrayValue(),
        'on yii/helpers/UnsetArrayValue' => new \yii\helpers\UnsetArrayValue(),
        
        // example: adding your own handler
        'on Some\Package\EmployeeWithoutId' => function ($event) {
            // get the EmployeeWithoutId object
            $value = $event->value;
            
            // decode the object into a TaggedValue object
            $event->value = new TaggedValue('lookupIdFromEmployeeNumber', [
                'employee_number' => $value->getEmployeeNumber(),
                'name' => $value->getName(),
            ]);
            $event->handled = true;
            
            // as a shortcut, the following is equivalent to setting `$event->value`
            // and setting `$event->handled = true`.
            $event->handleValue(
                new TaggedValue('lookupIdFromEmployeeNumber', [
                    'employee_number' => $value->getEmployeeNumber(),
                    'name' => $value->getName(),
                ])
            );
        },
    ]),
]);


// alternatively, in your application configuration:
[
    'container' => [
        'definitions' => [
            'thamtech\yaml\Parser' => Yaml::getParserDefinition([
                // ...
            ]),
            'thamtech\yaml\Dumper' => Yaml::getDumperDefinition([
                // ...
            ]),
        ],
    ],
];

Yaml 响应格式化器

您可以将 YamlResponseFormatter 添加为 yii\web\Response 组件的 yaml 格式化器,以支持返回 yaml 响应。

<?php
// ... config ...
return [
    'response' => [
        'formatters' => [
            'yaml' => [
                'class' => 'thamtech\yaml\web\YamlResponseFormatter',
                
                // you can define your own dumper config like the earlier
                // examples:
                'dumper' => [
                    // `'class' => 'thamtech\yaml\Dumper'` is assumed, but can
                    // be overridden if you extend 'thamtech\yaml\Dumper'
                    
                    'on Some\Package\EmployeeWithoutId' => function ($event) {
                        // ... handle event, see earlier example ...
                    },
                ],
            ],
        ],
    ],
];

另请参阅