taufik-nurrohman / y-a-m-l
显然是一个 YAML 解析器。
Requires
- php: >=7.1
README
动机
人们似乎不再寻找内容管理系统了。已经有那么多博客服务允许他们只写内容。在大数据时代,个性化和货币化似乎不再是主要关注点。或者,如果货币化是他们唯一的关注点,他们可能会将其留给使用的服务,牺牲选择符合他们个性的网页设计。
实际上,这个项目是我内容管理系统 Mecha 的一个内部功能,但我决定现在将其作为一个独立项目,以便其他人也能使用它。人们似乎更倾向于寻找 PHP YAML 解析器,而不是内容管理系统。因此,这个项目也是我试图将需要 PHP YAML 解析器的人引导到我所自豪的内容管理系统项目中的尝试(显然,这个项目并不非常受欢迎,因为人们似乎更感兴趣的是静态站点生成器)。
为什么你应该选择我的 YAML 解析器而不是其他任何类似的 YAML 解析器?
- mustangostang/spyc 由一个 PHP 文件组成,大小为 35.1 KB,包含总共 1186 行代码 自编写时起。它已经过时(只支持 YAML 1.0,并且在各种情况下存在错误 在此 此处 此处),并且与我的 YAML 解析器相比,相对较大。
- symfony/yaml 优先考虑可靠性和稳定性,用于大型应用程序。此库包含许多依赖项,如果您的目标仅仅是将 YAML 语法转换为 PHP 数据,则会导致您的应用程序过度膨胀。
- yaml 要求您的服务器允许您安装 PHP 扩展。在转换速度方面,它应该更快,因为它使用 C,但并不能保证在您租用的所有 PHP 服务器上都可以使用,考虑到这个 PHP 扩展默认并不捆绑在 PHP 中。
功能
锚点
asdf-1: &asdf 1 asdf-2: *asdf asdf-3: *asdf
asdf-1: &asdf a: asdf b: asdf c: asdf asdf-2: *asdf asdf-3: *asdf
注释
与 官方 PHP YAML 扩展 不同,此锚点功能仅复制值,并不通过将锚点值链接到它们的别名作为 引用 进行适当的内存管理,以简化 1。
数组
列表
- asdf - asdf - asdf
流
[ asdf, asdf, asdf ]
对象
块
a: asdf b: asdf c: asdf
流
{ a: asdf, b: asdf, c: asdf }
注释
# This is a comment.
标量
布尔值
# Case insensitive false
# Case insensitive true
常量
# Case insensitive .INF
# Case insensitive .NAN
日期
2023-09-25
2023-09-25 20:22:42
# Case insensitive 2023-09-25T20:22:42.025Z
# Case insensitive 2023-09-25T20:22:42+07:00
数字
浮点数
0.5
.5
指数形式的浮点数
# Case insensitive 1.2e+34
整数
12
十六进制整数
# Case insensitive 0xC
八进制整数
# Case insensitive 0o14
014
空值
# Case insensitive null
~
字符串
块
折叠
> # Clip (default) asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf
>4 # Clip and indent with 2 space(s) asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf
>+ # Keep asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf
>+4 # Keep and indent with 2 space(s) asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf
>- # Strip asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf
>-4 # Strip and indent with 2 space(s) asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf
字面量
| # Clip (default) asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf
|4 # Clip and indent with 2 space(s) asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf
|+ # Keep asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf
|+4 # Keep and indent with 2 space(s) asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf
|- # Strip asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf
|-4 # Strip and indent with 2 space(s) asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf
流
双引号
"asdf asdf \"asdf\" asdf"
单引号
'asdf asdf ''asdf'' asdf'
普通
asdf asdf 'asdf' asdf
标签
支持以下内置标签
!!binary
!!bool
!!float
!!int
!!map
!!null
!!seq
!!str
!!timestamp
想要添加自定义标签的用户可以在from()
函数的$lot
参数中定义它们,作为一个闭包。注意,这个参数是一个实时引用,因此你不能直接将其中的标签定义数组放入其中。相反,你必须将其放入一个临时变量中。
// <https://symfony.com.cn/doc/7.0/reference/formats/yaml.html#symfony-specific-features> $lot = [ '!php/const' => static function ($value) { if (is_string($value) && defined($value)) { return constant($value); } return null; }, '!php/enum' => static function ($value) { if (!is_string($value)) { return null; } [$a, $b] = explode('::', $value, 2); if ('->value' === substr($b, -7)) { return (new ReflectionEnumBackedCase($a, substr($b, 0, -7)))->getBackingValue(); } return (new ReflectionEnumBackedCase($a, $b))->getValue(); }, '!php/object' => static function ($value) { return is_string($value) ? unserialize($value) : null; } ]; $value = from_yaml($value, false, $lot); // Here, the `$lot` variable will probably contain anchors as well. Anchor data will have a key started with ‘&’. var_dump($lot, $value);
用法
此转换器可以使用Composer进行安装,但它不需要其他依赖项,只是使用Composer自动包含文件的能力。如果您不使用Composer,应该能够直接将from.php
和to.php
文件包含到您的应用程序中而不会出现任何问题。
使用Composer
从命令行界面,导航到您的项目文件夹,然后运行此命令
composer require taufik-nurrohman/y-a-m-l
在您的应用程序中引入生成的自动加载文件
<?php use function x\y_a_m_l\from as from_yaml; use function x\y_a_m_l\to as to_yaml; require 'vendor/autoload.php'; var_export(from_yaml('asdf: asdf')); // Returns `(object) ['asdf' => 'asdf']`
使用文件
在您的应用程序中引入from.php
和to.php
文件
<?php use function x\y_a_m_l\from as from_yaml; use function x\y_a_m_l\to as to_yaml; require 'from.php'; require 'to.php'; var_export(from_yaml('asdf: asdf')); // Returns `(object) ['asdf' => 'asdf']`
选项
/** * Convert YAML string to PHP data. * * @param null|string $value Your YAML string. * @param bool $array If this option is set to `true`, PHP object will becomes associative array. * @param array $lot Currently used to store anchor(s) and custom tag(s) * @return mixed */ from(?string $value, bool $array = false, array &$lot = []): mixed;
/** * Convert PHP data to YAML string. * * @param mixed $value Your PHP data. * @param bool|int|string $dent Specify the indent size or character(s). * @return null|string */ to(mixed $value, bool|int|string $dent = true): ?string;
测试
将此存储库克隆到支持PHP的Web服务器的根目录中,然后您可以使用浏览器打开test/from.php
和test/to.php
文件,以查看结果和此转换器在各种情况下的性能。
调整
您的YAML内容表示为变量$value
。如果在调用from_yaml()
函数之前修改内容,则表示在转换之前修改了YAML内容。如果在调用from_yaml()
函数之后修改内容,则表示修改了YAML转换的结果。
全局可重用函数
为了使from_yaml()
和to_yaml()
函数可全局重用,请使用此方法
<?php require 'from.php'; require 'to.php'; // Or, if you are using Composer… // require 'vendor/autoload.php'; function from_yaml(...$v) { return x\y_a_m_l\from(...$v); } function to_yaml(...$v) { return x\y_a_m_l\to(...$v); }
文档
此转换器不支持一个YAML文件中的多个文档功能,但可以稍加努力实现支持。
// Ensure line break after `---` and `...` $value = preg_replace('/^(-{3}|[.]{3})\s+/m', '$1' . "\n", $value); // Remove `---\n` prefix if any if (0 === strpos($value, "---\n")) { $value = substr($value, 4); } $values = []; foreach (explode("\n---\n", $value . "\n") as $v) { // Remove everything after `...` $v = explode("\n...\n", $v . "\n", 2)[0]; $values[] = from_yaml($v); } var_dump($values);
变量
在YAML中有几种声明变量的方式,它们都不符合标准。最常见的是类似于{{ var }}
格式的变量。为了添加变量功能,需要在解析数据之前将变量转换为YAML值。
$variables = [ 'var_1' => 'asdf', 'var_2' => true, 'var_3' => 1, 'var_4' => 1.5 ]; if (false !== strpos($value, '{{')) { $value = preg_replace_callback('/"\{\{\s*[a-z]\w*\s*\}\}"|\'\{\{\s*[a-z]\w*\s*\}\}\'|\{\{\s*[a-z]\w*\s*\}\}/', static function ($m) use ($variables) { $variable = $m[0]; // `"{{ var }}"` if ('"' === $variable[0] && '"' === substr($variable, -1)) { $variable = substr($variable, 1, -1); } // `'{{ var }}'` if ("'" === $variable[0] && "'" === substr($variable, -1)) { $variable = substr($variable, 1, -1); } // Trim variable from `{{` and `}}` $variable = trim(substr($variable, 2, -2)); // Get the variable value if available, default to `null` $variable = $variables[$variable] ?? null; // Return the variable value as YAML string return to_yaml($variable); }, $value); } $value = from_yaml($value); var_dump($value);