什么是 YAML?
YAML(YAML Ain't Markup Language)是一种数据序列化语言,它的设计目标是为了使人类可读性更高,同时也易于编写程序进行解析。YAML 的语法简洁明了,适合用于配置文件、数据交换等方面。
Symfony YAML组件
Symfony YAML组件是一个强大的PHP库,用于处理YAML配置文件。该组件可以轻松地将YAML数据转换为PHP数组,并且可以方便地对PHP数组进行序列化。
使用场景
使用 Symfony Yaml,你可以轻松地将 YAML 数据解析为 PHP 数组,也可以将 PHP 数组转换为 YAML 字符串。这使得它在以下场景中非常有用。
- 配置文件:YAML 文件是一种理想的配置文件格式,因为它们既清晰又易于阅读。
- 数据交换:如果你需要与别的系统交换数据,YAML 提供了一种简洁且易于理解的方式来表示结构化的数据。
- 设置对象属性:通过将 YAML 数据映射到 PHP 对象的属性,可以使对象更容易配置。
特点
- 易用性:Symfony Yaml 提供了一个简单直接的 API,使得操作 YAML 数据变得非常容易。
- 灵活性:Symfony Yaml 支持多种不同的 YAML 样式和特性,包括锚点、别名、标签等。
- 强大性:Symfony Yaml 具有强大的错误处理能力,能够捕获并报告各种类型的解析错误。
- 兼容性:Symfony Yaml 可以在 PHP 5.6 版本上运行,并且与大部分现代 PHP 框架兼容。
基础使用
安装
通过 Composer 来安装
代码语言:javascript复制composer require symfony/yaml
config.yaml
配置文件
# Redis配置
redis:
master:
host: '127.0.0.1'
port: 6379
password: '123456'
加载 YAML 文件
代码语言:javascript复制<?php
/**
* @desc 加载 YAML 文件
* @author Tinywan(ShaoBo Wan)
* @date 2024/6/15 10:09
*/
declare(strict_types=1);
require_once '../vendor/autoload.php';
use SymfonyComponentYamlYaml;
$yamlContent = Yaml::parseFile('../config.yaml');
var_dump($yamlContent);
打印输出
代码语言:javascript复制array(1) {
["redis"]=>
array(1) {
["master"]=>
array(3) {
["host"]=>
string(10) "127.0.0.1"
["port"]=>
int(6379)
["password"]=>
string(6) "123456"
}
}
}
解析 YAML 字符串
代码语言:javascript复制use SymfonyComponentYamlYaml;
$yamlString = 'name: Tinywan';
$parsedData = Yaml::parse($yamlString);
var_dump($parsedData);
打印输出
代码语言:javascript复制array(1) {
["name"]=>
string(7) "Tinywan"
}
将数据转换为 YAML 并写入文件
代码语言:javascript复制$data = [
'name' => 'Tinywan',
'age' => 24
];
$yamlString = Yaml::dump($data, 3, 2); // 第二个参数是缩进级别,第三个参数是换行符数量
$yamlPath = '../tinywan.yaml';
file_put_contents(base_path() . $yamlPath, $yamlString, LOCK_EX);
在这里,我们首先使用use导入Symfony YAML组件,然后使用Yaml::parseFile
方法将YAML
文件解析为PHP
数组。接下来,我们使用Yaml::dump
方法将PHP数组序列化为YAML
格式。
高级用法
高级用法主要是结合项目框架使用,不忘初衷的webman
,那就是你了!!!
用法:这里尝试使用
config.yaml
文件替换config/redis.php
配置文件,通过修改config.yaml
文件而变相的修改config/redis.php
配置文件。
config.yaml
文件内容
# Redis配置
redis:
master:
host: '127.0.0.1'
port: 6379
password: '123456'
config/redis.php
配置文件
<?php
/**
* @desc Redis配置
* @author Tinywan(ShaoBo Wan)
* @date 2024/6/15 0:09
*/
declare(strict_types=1);
return [
'default' => [
'host' => yaml('redis.master.host', '127.0.0.1'),
'port' => yaml('redis.master.port', '6379'),
'password' => yaml('redis.master.password', null),
'database' => 0,
],
];
自定义 yaml() 助手函数。助手函数位置很重要,该助手函数需要放在support/helpers.php
文件里,或者在support
目录下新建一个自定的函数,如support/resty.php
,然后需改composer.json
文件的autoload
自定加载文件即可
"autoload": {
"files": [
"./support/helpers.php",
"./support/resty.php"
]
}
yaml()
助手函数文件
/**
* @desc 自定义 yaml 助手函数
* @param string|null $key
* @param mixed|null $default
* @param string|null $path
* @param bool $static
* @return mixed
* @author Tinywan(ShaoBo Wan)
*/
function yaml(?string $key = null, ?string $default = null, ?string $path = null, bool $static = false)
{
if (!file_exists(($path = $path ?? base_path() . DIRECTORY_SEPARATOR . 'config.yaml'))) {
return $default;
}
if ($static) {
global $yaml;
if (!$yaml) {
$yaml = SymfonyComponentYamlYaml::parseFile($path);
}
$data = $yaml;
} else {
$data = SymfonyComponentYamlYaml::parseFile($path);
}
$keys = explode('.', $key);
if ($key !== null) {
foreach ($keys as $k) {
if (!is_array($data)) {
$data = $default;
break;
}
$data = $data[$k] ?? $default;
}
}
return $data;
}
注意区别:每次安装
workerman/webman-framework
或者升级workerman/webman-framework
时会自动覆盖start.php
和helpers.php
。所以这里推荐新建一个support/resty.php
文件。
composer.json
里将此文件加入到自动加载中,类似
"files": [
"./support/helpers.php",
"./support/resty.php"
]
执行composer dumpautoload
这样你的项目就可以在启动时加载support/check.php
了。不需要更改start.php
和 helpers.php
啦!!!
测试校验读取Redis默认配置文件
代码语言:javascript复制$config = config('redis.default');
var_dump($config);
打印输出
代码语言:javascript复制array(4) {
'host' =>
string(9) "127.0.0.1"
'port' =>
int(6379)
'password' =>
string(6) "123456"
'database' =>
int(0)
}
代码语言:javascript复制尝试修改
config.yaml
文件内容
# Redis配置
redis:
master:
host: 'dnmp-redis'
port: 6379
password: '123456'
再次打印输出,可以看到默认redis配置已经发生变化了,自动从config.yaml
文件读取了
array(4) {
'host' =>
string(10) "dnmp-redis"
'port' =>
int(6379)
'password' =>
string(6) "123456"
'database' =>
int(0)
}