Компонент Yaml

Компонент Yaml загружает и сбрасывает файлы YAML.

Что это?

Компонент Symfony Yaml анализирует YAML строки, чтобы преобразовать их в PHP массивы. Он также может преобразовывать PHP массивы в YAML строки.

YAML, YAML не является языком разметки - это дружелюбный стандарт сериализации данных для всех языков программирования. YAML является отличным форматом для ваших файлов конфигурации. Файлы YAML так же экспрессивны, как файлы XML, и так же читаемы, как файлы INI.

Компонент Symfony Yaml реализует выбранный поднабор функций, определённых в спецификации версии YAML 1.2.

Tip

Узнайте больше о компоненте Yaml в статье The YAML Format.

Установка

1
$ composer require symfony/yaml

Также вы можете клонировать репозиторий https://github.com/symfony/yaml.

Note

If you install this component outside of a Symfony application, you must require the vendor/autoload.php file in your code to enable the class autoloading mechanism provided by Composer. Read this article for more details.

Почему?

Быстро

Одна из целей Yaml Symfony - найти правильный баланс между скоростью и функциями. Он поддерживает только необходимые функции для обработки файлов конфигурации. Заметно не хватает таких функций: директив документов, многострочных цитируемых сообщений, компактных коллекций блоков и многодокументных файлов.

Реальный анализатор

Поддерживает реальный анализатор и может анализировать большой поднабор спецификации YAML для всех ваших потребностей конфигурации. Это также означает, что анализатор достаточно обширен, легок в понимании и достаточно прост для расширения.

Ясные сообщения ошибок

Каждый раз, когда у вас есть проблема синтаксиса в ваших YAML файлах, библиотека выводит полезное сообщение с именем файла и номером строки, где возникла проблема. Это очень облегчает отладку.

Поддержка сброса

Он также может сбрасывать PHP массивы в YAML с поддержкой объекта, и встраиваемый уровень конфигурации для красивых выводов.

Поддержка типов

Поддерживает большинство встроенных типов YAML вроде дат, чисел, окталов, булевых значений и многие другие...

Поддержка ключей полного слияния

Полная поддержка ссылок, дополнительных имён и ключей полного слияния. Не повторяйте самостоятельно, ссылаясь на распространённые части конфигурации.

Использование компонента Symfony YAML

Компонент Symfony Yaml очень простой и состоит из двух главных классов: один анализирует YAML строки (Parser), а второй - сбратсывает PHP массив в строку YAML (Dumper).

On top of these two classes, the Yaml class acts as a thin wrapper that simplifies common uses.

Чтение содержания YAML

Метод parse() анализирует строку YAML и преобразует её в PHP массив:

1
2
$value = Yaml::parse("foo: bar");
// $value = array('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('Unable to parse the YAML string: %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 = array(
    'foo' => 'bar',
    'bar' => array('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

Числовые литералы

Длинные числовые литералы, будь они целыми числами, float или шестнадцатиричными, известны своей плохой читаемостью в коде и файлах конфигурации. Поэтому файлы 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(array('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
3
4
$data = new \stdClass(); // by default objects are invalid.
Yaml::dump($data, 2, 4, Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE); // вызывает исключение

echo $yaml; // { foo: bar }

Работа с данными

По умолчанию, анализатор 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 = array("string" => "Multiple\nLine\nString");
$yaml = Yaml::dump($string);
echo $yaml; // строка: "Multiple\nLine\nString"

Вы можете заставить его использовать блок литералов с помощью флажка DUMP_MULTI_LINE_LITERAL_BLOCK:

1
2
3
4
5
6
$string = array("string" => "Multiple\nLine\nString");
$yaml = Yaml::dump($string, 2, 4, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK);
echo $yaml;
//  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 = array('foo' => 'PHP_INT_SIZE', 'bar' => 8);

Анализ и сброс бинарных данных

Вы можете сбросить бинарные данные, используя флажок DUMP_BASE64_BINARY_DATA:

1
2
3
4
$imageContents = file_get_contents(__DIR__.'/images/logo.png');

$dumped = Yaml::dump(array('logo' => $imageContents), 2, 4, Yaml::DUMP_BASE64_BINARY_DATA);
// лого: !!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', array('foo' => 'bar'));
$tagName = $parsed->getTag();    // $tagName = 'my_tag'
$tagValue = $parsed->getValue(); // $tagValue = array('foo' => 'bar')

Если содержание для сброса содержит объекты TaggedValue, то они автоматически преобразуются в YAML теги:

1
2
3
4
5
use Symfony\Component\Yaml\Tag\TaggedValue;

$data = new TaggedValue('my_tag', array('foo' => 'bar'));
$dumped = Yaml::dump($data);
// $dumped = '!my_tag { foo: bar }'

Валидация синтаксиса

Синтаксис содержания YAML может быть валидирован через CLI, используя команду LintCommand.

Для начала, установите компонент Консоль:

1
$ composer require symfony/console

Создайте консоль приложения с lint:yaml в качестве его единственной команды:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// 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
# валидирует один файл
$ php lint.php path/to/file.yaml

# или все файлы в каталоге
$ php lint.php path/to/directory

# или содержание, переданное в STDIN
$ cat path/to/file.yaml | php lint.php

Результат записывается в STDOUT и использует формат простого текста по умолчанию. Добавьте опцию --format, чтобы получить вывод в формате JSON:

1
$ php lint.php path/to/file.yaml --format json

Tip

Команда проверки соблюдения стандартов кода также сообщит обо всех устареваниях в провеяемых YAML файлах. Это может быть, к примеру, быть полезным для определения устареваний содержания YAML файлов во время автоматизированных тестов.

Узнать больше

Эта документация является переводом официальной документации Symfony и предоставляется по свободной лицензии CC BY-SA 3.0.