Привет, Хабр! Сегодня я расскажу вам о том, как использовать YAML‑парсер в Symfony.
YAML — это человекочитаемый формат сериализации данных, который используется для конфигурационных файлов. И в Symfony для этого есть компонент Yaml, который позволяет парсить YAML‑строки и файлы в PHP‑значения и обратно.
Компонент Yaml состоит из двух основных классов:
-
Parser: парсит YAML‑строки и файлы в PHP‑значения.
-
Dumper: преобразует PHP‑значения обратно в YAML‑строки.
Для упрощения есть фасадный класс Yaml, который имеет статические методы для наиболее распространенных операций.
Чтение YAML-строк и файлов
Чтобы распарсить YAML‑строку, есть метод Yaml::parse():
use Symfony\Component\Yaml\Yaml; $yamlString = " foo: bar baz: - qux - quux "; $data = Yaml::parse($yamlString); // $data будет содержать: // [ // 'foo' => 'bar', // 'baz' => ['qux', 'quux'], // ]
Для чтения YAML из файла метод Yaml::parseFile():
use Symfony\Component\Yaml\Yaml; $data = Yaml::parseFile('/path/to/file.yaml');
Если в процессе парсинга произойдет ошибка, будет выброшено исключение ParseException. Лучше обрабатывать это исключение, чтобы получать информацию об ошибке:
use Symfony\Component\Yaml\Exception\ParseException; use Symfony\Component\Yaml\Yaml; try { $data = Yaml::parseFile('/path/to/file.yaml'); } catch (ParseException $exception) { printf('Не удалось распарсить YAML: %s', $exception->getMessage()); }
Чтобы преобразовать PHP‑значение в YAML‑строку, используйте метод Yaml::dump():
use Symfony\Component\Yaml\Yaml; $data = [ 'foo' => 'bar', 'baz' => ['qux', 'quux'], ]; $yamlString = Yaml::dump($data); // $yamlString будет содержать: // foo: bar // baz: // - qux // - quux
Можно настроить уровень вложенности, при котором массивы будут инлайнены, передав второй аргумент в метод dump():
$yamlString = Yaml::dump($data, 1); // $yamlString будет содержать: // foo: bar // baz: [qux, quux]
Yaml поддерживает сериализацию и десериализацию объектов. Для этого при дампе данных необходимо использовать флаг Yaml::DUMP_OBJECT:
use Symfony\Component\Yaml\Yaml; $object = new \stdClass(); $object->foo = 'bar'; $yamlString = Yaml::dump($object, 2, 4, Yaml::DUMP_OBJECT); // $yamlString будет содержать: // !php/object 'O:8:"stdClass":1:{s:3:"foo";s:3:"bar";}'
При парсинге такого YAML необходимо использовать флаг Yaml::PARSE_OBJECT:
use Symfony\Component\Yaml\Yaml; $yamlString = "!php/object 'O:8:\"stdClass\":1:{s:3:\"foo\";s:3:\"bar\";}'"; $data = Yaml::parse($yamlString, Yaml::PARSE_OBJECT); // $data будет объектом stdClass с свойством foo, равным 'bar'
Также YAML поддерживает различные типы данных, такие как даты, булевы значения и т. д. Компонент Yaml автоматом преобразует их в соответствующие PHP‑значения:
is_active: true created_at: 2025-02-08
use Symfony\Component\Yaml\Yaml; $yamlString = " is_active: true created_at: 2025-02-08 "; $data = Yaml::parse($yamlString); // $data будет содержать: // [ // 'is_active' => true, // 'created_at' => new \DateTime('2025-02-08'), // ]
Помимо этого, можно использовать пользовательские теги для обозначения специальных типов данных. Компонент Yaml позволяет работать с такими тегами с помощью класса TaggedValue:
custom_tag: !mytag foo: bar
use Symfony\Component\Yaml\Tag\TaggedValue; use Symfony\Component\Yaml\Yaml; $yamlString = " custom_tag: !mytag foo: bar "; $data = Yaml::parse($yamlString, Yaml::PARSE_CUSTOM_TAGS); // $data будет содержать: // [ // 'custom_tag' => new TaggedValue('mytag', ['foo' => 'bar']), // ]
Пример использования YAML-парсера
Представим, что у нас есть YAML‑файл, описывающий конфигурацию приложения с различными средами (development, testing, production), настройками базы данных, кэша и сервисов:
environments: development: debug: true database: host: localhost port: 3306 name: dev_db user: dev_user password: dev_pass cache: enabled: false testing: debug: true database: host: localhost port: 3306 name: test_db user: test_user password: test_pass cache: enabled: true type: memory production: debug: false database: host: db.prod.example.com port: 3306 name: prod_db user: prod_user password: prod_pass cache: enabled: true type: redis host: cache.prod.example.com port: 6379 services: email: provider: smtp host: smtp.example.com port: 587 username: no-reply@example.com password: email_pass payment: provider: stripe api_key: sk_live_12345
Задача: написать скрипт на PHP, который будет читать этот файл и выводить настройки для указанной среды.
require 'vendor/autoload.php'; use Symfony\Component\Yaml\Yaml; use Symfony\Component\Yaml\Exception\ParseException; function getConfigForEnvironment($env) { try { $config = Yaml::parseFile('app_config.yaml'); } catch (ParseException $e) { printf('Не удалось разобрать YAML: %s', $e->getMessage()); return null; } if (!isset($config['environments'][$env])) { echo "Среда '$env' не найдена в конфигурации." . PHP_EOL; return null; } $envConfig = $config['environments'][$env]; $servicesConfig = $config['services']; return [ 'environment' => $envConfig, 'services' => $servicesConfig ]; } // Пример использования $environment = 'production'; $config = getConfigForEnvironment($environment); if ($config) { echo "Настройки для среды '$environment':" . PHP_EOL; print_r($config['environment']); echo "Настройки сервисов:" . PHP_EOL; print_r($config['services']); }
Вывод:
Настройки для среды 'production': Array ( [debug] => [database] => Array ( [host] => db.prod.example.com [port] => 3306 [name] => prod_db [user] => prod_user [password] => prod_pass ) [cache] => Array ( [enabled] => 1 [type] => redis [host] => cache.prod.example.com [port] => 6379 ) ) Настройки сервисов: Array ( [email] => Array ( [provider] => smtp [host] => smtp.example.com [port] => 587 [username] => no-reply@example.com [password] => email_pass ) [payment] => Array ( [provider] => stripe [api_key] => sk_live_12345 ) )
Ограничения
Компонент Yaml не поддерживает некоторые возможности YAML 1.2, такие как:
-
Многостраничные документы (
---и...маркеры); -
Комплексные ключи в маппингах;
-
Некоторые теги и типы (
!!set,!!omap,!!pairsи т. д.).
В заключение хочу напомнить про открытый урок, который пройдёт в Otus 13 февраля — «Генерируем API-клиент без помощи ChatGPT». На нём вы научитесь генерировать API-клиент на базе спецификации Open API и использовать его в своих приложениях. Записаться можно на странице курса «Symfony Framework».
ссылка на оригинал статьи https://habr.com/ru/articles/880762/
Добавить комментарий