thamtech / yii2-yaml
Yii2 的 Yaml 辅助工具
Requires
- php: >=7.2.5
- symfony/yaml: >=3.4 <=3.4.29 || ^4.4.0 || ^5.0.0
- yiisoft/yii2: >=2.0.14 <2.1
Requires (Dev)
- php: >=7.3
- phpunit/phpunit: ~9.0
README
Yii2 Yaml 提供了一个 Yaml 辅助工具和一个 Yaml 解析/导出扩展。
Yaml 辅助工具提供了 encode()
、decode()
和 errorSummary()
方法,类似于 yii\helpers\Json。
Yii2 Yaml 还包括了对 symfony/yaml 库的扩展,支持自定义 Yaml 标签表示 UnsetArrayValue 和 ReplaceArrayValue,并允许您将事件附加到处理任何其他自定义 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
库,以支持对 ReplaceArrayValue
和 UnsetArrayValue
对象的解码和编码,以用于 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
标签的键被自动从 ReplaceArrayValue
和 UnsetArrayValue
对象编码。
为了添加对 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
组件将其默认的 Parser
和 Dumper
定义设置到 Yii::$container
中。您可以在那里设置自己的默认 Parser
和 Dumper
定义,并使用您自己的处理器。
默认不使用任何处理器(甚至不包括 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 ... }, ], ], ], ], ];