Компонент Yaml
Дата оновлення перекладу 2024-05-07
Компонент Yaml
Компонент Yaml завантажує та скидає файли YAML.
Що це?
Компонент Symfony Yaml парсить YAML рядки, щоб перетворити їх на PHP-масиви. Він також може перетворити PHP-масиви на рядки YAML.
YAML, YAML не є мовою розмітки - це дружній стандарт серіалізації даних для всіх мов програмування. YAML є чудовим форматом для ваших файлів конфігурації. Файли YAML настільки ж експресивні, як і файли XML, і настільки ж читані, як файли INI.
Tip
Дізнайтеся більше проспецифікацію YAML.
Установка
1
$ composer require symfony/yaml
Note
Якщо ви встановлюєте цей компонент поза додатком Symfony, вам потрібно підключити
файл vendor/autoload.php
у вашому коді для включення механізму автозавантаження
класів, наданих Composer. Детальніше можна прочитати у цій статті.
Чому?
Швидкість
Одна з цілей Symfony Yaml - знайти правильний баланс між швидкістю та функціональністю. Він підтримує лише необхідні функції для обробки файлів конфігурації. Не вистачає таких помітних функцій: директив документів, багаторядкових цитованих повідомлень, компактних колекцій блоків та багатодокументних файлів.
Реальний парсер
Підтримує реальний парсер та розуміє більшу частину сецифікації YAML для всіх ваших потреб конфігурації. Це також означає, що парсер достатньо великий, легкий у розумінні та достньо простий для розширення.
Чіткі повідомлення про помилки
Кожний раз, коли у вас є проблема синтаксису у ваших файлах YAML, бібліотека виводить корисне повідомлення з іменем файлу та номером рядку, де виникла проблема. Це дуже полегшує налагодження.
Підтримка скидання
Він також може скидати PHP-масиви в YAML з підтримкою обʼєктів, та вбудовуваний рівень конфігурації для гарних виведень.
Підтримка типів
Підтримує більшість вбудованих типів YAML на кшталт дат, цілих чисел, чисел у вісімковій системі, булевих значень та багато інших...
Підтримка ключів повного злиття
Повна підтримка посилань, додаткових імен та ключів повного злиття. Не повторюйте самостійно, посилаючись на розповсюджені частини конфігурації.
Використання компонента Symfony YAML
Компонент Symfony Yaml складається з двох головних класів: один парсить рядки YAML (Parser), а другий - скидає PHP-масив у рядок YAML (Dumper).
Над цима двома класами, клас Yaml працює як тонкий прошарок та спрощує часті варіанти використання.
Читання змісту YAML
Метод parse() парсить рядок YAML та претворює його на PHP-масив:
1 2 3 4
use Symfony\Component\Yaml\Yaml;
$value = Yaml::parse("foo: bar");
// $value = ['foo' => 'bar']
Якщо помилка виникає під час парсингу, парсер викликає виключення ParseException, демонструючи тип помилки та рядок початкового рядку YAML, де виника помилка:
1 2 3 4 5 6 7
use Symfony\Component\Yaml\Exception\ParseException;
try {
$value = Yaml::parse('...');
} catch (ParseException $exception) {
printf('Неможливо парсувати рядок YAML: %s', $exception->getMessage());
}
Читання файлів YAML
Метод parseFile() парсить зміст YAML у вказаному файлі та перетворює його на PHP-значення:
1 2 3
use Symfony\Component\Yaml\Yaml;
$value = Yaml::parseFile('/path/to/file.yaml');
Якщо під час парсингу виникає помилка, парсер викликає виключення ParseException
.
Запис YAML файлів
Метод dump() перетворює будь-який PHP-масив на його представлення YAML:
1 2 3 4 5 6 7 8 9 10
use Symfony\Component\Yaml\Yaml;
$array = [
'foo' => 'bar',
'bar' => ['foo' => 'bar', 'bar' => 'baz'],
];
$yaml = Yaml::dump($array);
file_put_contents('/path/to/file.yaml', $yaml);
Якщо помилка виникає під час скидання, парсер викликає виключення DumpException.
Розширені та вбудовані масиви
Формат YAML підтримує два типи представлення для масивів, розширене та вбудоване. За замовчуванням, дампер використовує розширене представлення:
1 2 3 4
foo: bar
bar:
foo: bar
bar: baz
Другий аргумент методу dump() налаштовує рівень, на якому виведення перемикається з розширеного представлення на вбудоване:
1
echo Yaml::dump($array, 1);
1 2
foo: bar
bar: { foo: bar, bar: baz }
1
echo Yaml::dump($array, 2);
1 2 3 4
foo: bar
bar:
foo: bar
bar: baz
Відступи
За замовчуванням, компонент YAML використовує 4 пробіли для відступу. Це можна змінити за допомогою третього аргументу таким чином:
1 2
// використовує 8 пробілів для відступу
echo Yaml::dump($array, 2, 8);
1 2 3 4
foo: bar
bar:
foo: bar
bar: baz
Числові літерали
Довгі числолві літерали, цілі числа, плаваючі чи шістнадцяткові, відомі своєю поганою читаністю в коді та файлах конфігурації. Тому файли YAML дозволяють додавати нижні підкреслення для покращення їх читаності:
1 2 3 4 5
parameters:
credit_card_number: 1234_5678_9012_3456
long_number: 10_000_000_000
pi: 3.14159_26535_89793
hex_words: 0x_CAFE_F00D
Під час парсингу змісту YAML, всі символи _
видаляються зі змісту числових
літералів, тому ліміту кількості нижніх підкреслень, які ви можете додавати, або
те, як ви групуєте зміст, не існує.
Просунуте використання: прапорці
Парсинг та скидання обʼєктів
Ви можете скидати обʼєкти, використовуючи прапорець DUMP_OBJECT
:
1 2 3 4 5
$object = new \stdClass();
$object->foo = 'bar';
$dumped = Yaml::dump($object, 2, 4, Yaml::DUMP_OBJECT);
// !php/object 'O:8:"stdClass":1:{s:5:"foo";s:7:"bar";}'
Та парсити їх, використовуючи прапорець PARSE_OBJECT
:
1 2 3
$parsed = Yaml::parse($dumped, Yaml::PARSE_OBJECT);
var_dump(is_object($parsed)); // true
echo $parsed->foo; // bar
Компонент YAML використовує метод PHP serialize()
для генерування представлення
рядку обʼєкта.
Caution
Серіалізація обʼєкта специфічна в цій реаізації, інші парсери PHP YAML
скоріш за все впізнають тег php/object
, а не-PHP реалізації точно не
впізнають - використовуйте з обережністю!
Парсинг та скидання обʼєктів у вигляді мап
Ви можете скидати обʼєкти як Yaml-мапи, використовуючи прапорець DUMP_OBJECT_AS_MAP
:
1 2 3 4 5
$object = new \stdClass();
$object->foo = 'bar';
$dumped = Yaml::dump(['data' => $object], 2, 4, Yaml::DUMP_OBJECT_AS_MAP);
// $dumped = "data:\n foo: bar"
Та парсити їх, використовуючи прапорець PARSE_OBJECT_FOR_MAP
:
1 2 3 4
$parsed = Yaml::parse($dumped, Yaml::PARSE_OBJECT_FOR_MAP);
var_dump(is_object($parsed)); // true
var_dump(is_object($parsed->data)); // true
echo $parsed->data->foo; // bar
Компонент YAML використовує привид PHP (array)
, щоб згенерувати рядкове
представлення обʼєкта у вигляді мапи.
Робота з невалідними типами
За замовчуванням, парсер зашифрує невалідні типи як null
. Ви можете змусити
парсер викликати виключення, використовуючи прапорець PARSE_EXCEPTION_ON_INVALID_TYPE
:
1 2
$yaml = '!php/object \'O:8:"stdClass":1:{s:5:"foo";s:7:"bar";}\'';
Yaml::parse($yaml, Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE); // throws an exception
Схожим чином ви можете використати DUMP_EXCEPTION_ON_INVALID_TYPE
при скиданні:
1 2
$data = new \stdClass(); // by default objects are invalid.
Yaml::dump($data, 2, 4, Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE); // викликає виключення
Робота з датою
За замовчуванням, парсер YAML перетворює рядки без лапок, які виглядатимуть як дата
або дата-час, на часову відмітку Unix; наприклад, 2016-05-27
або
2016-05-27T02:59:43.1Z
(ISO-8601):
1
Yaml::parse('2016-05-27'); // 1464307200
Ви можете змусити його перетворювати на екземпляр DateTime
, використовуючи
прапорець PARSE_DATETIME
:
1 2
$date = Yaml::parse('2016-05-27', Yaml::PARSE_DATETIME);
var_dump(get_class($date)); // DateTime
Скидання багаторядкових блоків літералів
В YAML багаторядкові рядки можуть бути представлені як блоки літералів. За замовчуванням, дампер зашифрує багато рядків у вигляді будованого рядку:
1 2 3
$string = ["string" => "Multiple\nLine\nString"];
$yaml = Yaml::dump($string);
echo $yaml; // рядок: "Multiple\nLine\nString"
Ви можете змусити його використовувати блок літералів за допомогою прапорця
DUMP_MULTI_LINE_LITERAL_BLOCK
:
1 2 3 4 5 6 7
$string = ["string" => "Multiple\nLine\nString"];
$yaml = Yaml::dump($string, 2, 4, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK);
echo $yaml;
// string: |
// Multiple
// Line
// String
Парсинг PHP-констант
За замовчуванням, YAML-парсер відноситься до PHP-констант, доданим у зміст, як до
звичайних рядків. Використайте прапорець PARSE_CONSTANT
та спеціальний синтаксис
!php/const
, щоб пропарсити їх, як відповідні PHP-константи:
1 2 3
$yaml = '{ foo: PHP_INT_SIZE, bar: !php/const PHP_INT_SIZE }';
$parameters = Yaml::parse($yaml, Yaml::PARSE_CONSTANT);
// $parameters = ['foo' => 'PHP_INT_SIZE', 'bar' => 8];
Парсинг PHP-зчислень
Парсер YAML підтримує PHP-зчислення, як одиничні так і підкріплені. За замовчуванням,
вони парсуються як звичайні рядки. Використайте прапорець PARSE_CONSTANT
та спеціальний
синтаксис !php/enum
, щоб парсувати їх як PHP-зчислення:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
enum FooEnum: string
{
case Foo = 'foo';
case Bar = 'bar';
}
// ...
$yaml = '{ foo: FooEnum::Foo, bar: !php/enum FooEnum::Foo }';
$parameters = Yaml::parse($yaml, Yaml::PARSE_CONSTANT);
// значення ключа 'foo' - це рядок, так як пропущено синтаксис `!php/enum`
// $parameters = ['foo' => 'FooEnum::Foo', 'bar' => FooEnum::Foo];
$yaml = '{ foo: FooEnum::Foo, bar: !php/enum FooEnum::Foo->value }';
$parameters = Yaml::parse($yaml, Yaml::PARSE_CONSTANT);
// значення ключа 'foo' - це рядок, так як пропущено синтаксис `!php/enum`
// $parameters = ['foo' => 'FooEnum::Foo', 'bar' => 'foo'];
Ви також можете використовувати !php/enum
, щоб отримати всі випадки зчислення, просто
задавши зчисленню FQCN:
1 2 3 4 5 6 7 8 9 10 11
enum FooEnum: string
{
case Foo = 'foo';
case Bar = 'bar';
}
// ...
$yaml = '{ bar: !php/enum FooEnum }';
$parameters = Yaml::parse($yaml, Yaml::PARSE_CONSTANT);
// $parameters = ['bar' => ['foo', 'bar']];
7.1
Підтримку зчислення FQCN без вказування випадку використання було представлено в Symfony 7.1.
Парсинг та скидання бінарних даних
Ви можете скинути бінарні дані, використовуючи прапорець DUMP_BASE64_BINARY_DATA
:
1 2 3 4
$imageContents = file_get_contents(__DIR__.'/images/logo.png');
$dumped = Yaml::dump(['logo' => $imageContents], 2, 4, Yaml::DUMP_BASE64_BINARY_DATA);
// logo: !!binary iVBORw0KGgoAAAANSUhEUgAAA6oAAADqCAY...
Бінарні дані автоматично парсяться, якщо вони включають у себе прапорець YAML
!!binary
(немає необхідності передавати будь-який прапорець парсеру Yaml):
1 2 3
$dumped = 'logo: !!binary iVBORw0KGgoAAAANSUhEUgAAA6oAAADqCAY...';
$parsed = Yaml::parse($dumped);
$imageContents = $parsed['logo'];
Парсинг та скидання користувацьких тегів
Окрім вбудованої підтримка тегів на кшталт !php/const
і !!binary
, ви можете
визначати ваші власні YAML-теги та парсити їх за допомогою прапорця PARSE_CUSTOM_TAGS
:
1 2 3 4 5
$data = "!my_tag { foo: bar }";
$parsed = Yaml::parse($data, Yaml::PARSE_CUSTOM_TAGS);
// $parsed = Symfony\Component\Yaml\Tag\TaggedValue('my_tag', ['foo' => 'bar']);
$tagName = $parsed->getTag(); // $tagName = 'my_tag'
$tagValue = $parsed->getValue(); // $tagValue = ['foo' => 'bar']
Якщо зміст для скидання містить обʼєкти TaggedValue, то вони автоматично перетворюються на YAML-теги:
1 2 3 4 5
use Symfony\Component\Yaml\Tag\TaggedValue;
$data = new TaggedValue('my_tag', ['foo' => 'bar']);
$dumped = Yaml::dump($data);
// $dumped = '!my_tag { foo: bar }'
Скидання Null-значень
Офіційна специфікація YAML використовує і null
, і ~
для представлення значення null.
Цей компонент використовує за замовчуванням null
при скиданні значень null, але ви можете
скидати їх як ~
з прапорцем DUMP_NULL_AS_TILDE
:
1 2 3 4 5
$dumped = Yaml::dump(['foo' => null]);
// foo: null
$dumped = Yaml::dump(['foo' => null], 2, 4, Yaml::DUMP_NULL_AS_TILDE);
// foo: ~
Скидання числових ключів як рядків
За замовчуванням, ключі, що складаються лише з цифр, скидаються як цілі числа.
Ви можете використати прапорець DUMP_NUMERIC_KEY_AS_STRING
, якщо ви хочете
скидати тільки ключі-рядки:
1 2 3 4 5
$dumped = Yaml::dump([200 => 'foo']);
// 200: foo
$dumped = Yaml::dump([200 => 'foo'], 2, 4, Yaml::DUMP_NUMERIC_KEY_AS_STRING);
// '200': foo
Валідація синтаксису
Синтаксис змісту YAML може бути валідований через CLI, використовуючи команду LintCommand.
Спочатку встановіть компонент Console:
1
$ composer require symfony/console
Створіть консольний додаток з lint:yaml
в якості його єдиної команди:
1 2 3 4 5 6 7 8 9
// lint.php
use Symfony\Component\Console\Application;
use Symfony\Component\Yaml\Command\LintCommand;
(new Application('yaml/lint'))
->add(new LintCommand())
->getApplication()
->setDefaultCommand('lint:yaml', true)
->run();
Далі, виконайте скрипт для валідації змісту:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
# валідує один файл
$ php lint.php path/to/file.yaml
# або валідує декілька файлів
$ php lint.php path/to/file1.yaml path/to/file2.yaml
# або всі файли у каталозі
$ php lint.php path/to/directory
# або всі файли у декількох каталогах
$ php lint.php path/to/directory1 path/to/directory2
# або зміст, переданий STDIN
$ cat path/to/file.yaml | php lint.php
# ви також можете виключити один або більше файлів з перевірки
$ php lint.php path/to/directory --exclude=path/to/directory/foo.yaml --exclude=path/to/directory/bar.yaml
Результат записується у STDOUT і використовує формат простого тексту за замовчуванням.
Додайте опцію --format
, щоб отримати виведення у форматі JSON:
1
$ php lint.php path/to/file.yaml --format json
Tip
Команда перевірки дотримання стандартів коду також повідомить про всі старіння у YAML файлах, що перевіряються. Це може бути, наприклад, корисним для виявлення старінь змісту YAML-файлів під час автоматизованих тестів.