Статьи

Использование YAML в ваших проектах PHP

Все тестовые данные, файлы конфигурации и файлы журналов должны быть удобочитаемыми для человека и компьютера. YAML (YAML не является языком разметки) — менее подробный формат сериализации данных, чем XML, и стал популярным форматом среди разработчиков программного обеспечения, главным образом потому, что он удобочитаем. Файлы YAML — это просто текстовые файлы, которые содержат данные, записанные в соответствии с правилами синтаксиса YAML, и обычно имеют расширение .yml В этой статье вы познакомитесь с основами YAML и с тем, как интегрировать синтаксический анализатор PHP YAML в свои проекты.

Понимание синтаксиса YAML

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

Ниже показано, как представить перечисляемый массив в YAML:

  - 2
 - "Уильям О'Нил"
 - ложный 

Каждый элемент массива представлен после дефиса и пробела. Его синтаксис для представления значений аналогичен синтаксису в PHP (цитирование строк и т. Д.)

Вышесказанное эквивалентно следующему PHP:

 <?php
array(2, "William O'Neil", false);

Как правило, каждый элемент отображается в отдельной строке в YAML, но перечисляемые массивы также могут быть выражены в одной строке с помощью скобок:

  [2, «Уильям О'Нил», ложь] 

Следующий код показывает, как представить ассоциативный массив в YAML:

  id: 2
 имя: "Уильям О'Нил"
 isActive: false 

Сначала указывается ключ элемента, затем двоеточие и один или несколько пробелов, а затем указывается значение. Достаточно всего одного пробела после двоеточия, но вы можете использовать больше пробелов для лучшей читаемости, если хотите.

Эквивалентный массив PHP вышеупомянутого YAML:

 <?php
array("id" => 2, "name" => "William O'Neil", "isActive" => false);

И подобно перечисляемым массивам, вы можете выразить ассоциативные массивы в одной строке, используя фигурные скобки:

  {id: 2, имя: «Уильям О'Нил», isActive: false} 

С одним или несколькими пробелами для отступа вы можете представить многомерный массив следующим образом:

  автор:
   0: {id: 1, имя: "Брэд Тейлор", isActive: true}
   1: {id: 2, имя: "Уильям О'Нил", isActive: false} 

Обратите внимание, что хотя массивы второго уровня являются перечисляемыми массивами, для ясности я использовал синтаксис для отображений (двоеточий) вместо синтаксиса для последовательностей (дефисов).

Вышеупомянутый блок YAML эквивалентен следующему PHP:

 <?php
array(
    "author" => array(
        0 => array("id" => 1, "name" => "Brad Taylor", "isActive" => true),
        1 => array("id" => 2, "name" => "William O'Neil", "isActive" => false)
    )
);

YAML также позволяет представлять коллекцию элементов данных в одном документе, не требуя корневого узла. В следующем примере показано содержимое article.yml

  автор:
   0: {id: 1, имя: "Брэд Тейлор", isActive: true}
   1: {id: 2, имя: "Уильям О'Нил", isActive: false}

 категория:
   0: {id: 1, name: "PHP"}
   1: {id: 2, name: "YAML"}
   2: {id: 3, name: "XML"}

 статья:
   0:
     id: 1
     title: «Как использовать YAML в вашем следующем PHP-проекте»
     содержание:>
                YAML - это менее подробный формат сериализации данных.
                Это означает "ЯМЛ не язык разметки".
                YAML был популярным форматом сериализации данных среди
                разработчики программного обеспечения в основном потому, что он читабелен.
     автор: 1
     статус: 2

 articleCategory:
   0: {articleId: 1, categoryId: 1}
   1: {articleId: 1, categoryId: 2} 

Хотя большая часть синтаксиса YAML интуитивно понятна и ее легко запомнить, есть одно важное правило, на которое следует обратить внимание. Отступы должны быть сделаны с одним или несколькими пробелами; вкладки не допускаются. Вы можете настроить IDE для вставки пробелов вместо вкладок при нажатии клавиши табуляции, которая является обычной конфигурацией для разработчиков программного обеспечения, чтобы убедиться, что код правильно вставлен и отображается при просмотре в других редакторах.

Вы можете узнать более сложные функции и синтаксис, которые поддерживает YAML, прочитав официальную документацию , справочник Symfony или Википедию .

YAML не должен быть альтернативой XML

Если вы исследуете YAML с помощью своей любимой поисковой системы, вы, несомненно, найдете обсуждение «YAML vs XML», и, естественно, когда вы впервые познакомитесь с YAML, вы предпочтете его XML, главным образом потому, что его легче читать и писать. Тем не менее, YAML должен быть еще одним инструментом в вашем арсенале разработчиков и не должен быть альтернативой XML. Вот некоторые преимущества YAML и XML.

Преимущества YAML

  • Менее многословный, простой в написании и более читаемый
  • Не нужно иметь древовидную структуру с одним родительским узлом

Преимущества XML

  • Более встроенная поддержка PHP по сравнению с YAML
  • XML является стандартом де-факто для взаимодействия между приложениями и широко признан
  • Теги XML могут иметь атрибуты, предоставляющие дополнительную информацию о вложенных данных.

Несмотря на многословность, XML более читабелен и удобен в обслуживании, когда иерархия элементов глубока по сравнению с пространственно-ориентированным иерархическим представлением YAML.

Учитывая преимущества обоих языков, YAML кажется более подходящим для коллекций различных наборов данных и когда люди также являются потребителями данных.

Выбор PHP YAML парсера

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

В настоящее время синтаксический анализатор PHP YAML доступен как расширение PECL и не входит в состав PHP. Кроме того, есть парсеры, написанные на чистом PHP, которые будут немного медленнее по сравнению с расширением PECL.

Ниже приведены несколько парсеров YAML, доступных для PHP:

Расширение PECL

  • Не в комплекте с PHP
  • Для установки потребуется root-доступ к серверу

Symfony 1.4 YAML Компонент

  • Реализовано в PHP
  • Будет работать в PHP 5.2.4+
  • Нужно извлечь из фреймворка Symfony

Symfony 2 YAML Компонент

  • Реализовано в PHP
  • Будет работать в PHP 5.3.2+

SPYC

  • Реализовано в PHP
  • Будет работать в PHP 5+

Мой предпочтительный выбор — YAML-компонент Symfony 1.4 из-за его переносимости (он работает с версиями PHP 5.2.4+) и зрелости (Symfony 1.4 — хорошо зарекомендовавший себя PHP-фреймворк). После того, как вы извлекли компонент YAML из архива Symfony, классы YAML доступны в lib/yaml Статические методы load()dump()sfYaml

Примечание редактора, 28 октября 2012 г .: сопровождающий код на GitHub был обновлен для использования Composer для получения зависимостей компонентов PHPUnit и Symfony 1.4 YAML.

Интеграция PHP YAML парсера в ваш проект

Всякий раз, когда вы интегрируете сторонний класс или библиотеку в ваш проект PHP, рекомендуется создать оболочку и набор тестов. Это позволит вам позже изменить стороннюю библиотеку с минимальными изменениями в коде вашего проекта (код проекта должен ссылаться только на оболочку) и с уверенностью, что изменение не будет тормозить какую-либо функциональность (тестовые наборы скажут вам).

Ниже приведен тестовый пример ( YamlParserTest.phpYamlParser.php Вам нужно знание PHPUnit для запуска и поддержки контрольного примера. Вы можете добавить больше тестов, если хотите, для неправильных имен файлов и расширений файлов, отличных от .yml

 <?php
require_once "YamlParser.php";

class YamlParserTest extends PHPUnit_Framework_TestCase
{
    private $yamlParser;

    public function setup() {
        $this->yamlParser = new YamlParser();
    }

    public function testMainArrayKeys() {
        $parsedYaml    = $this->yamlParser->load("article.yml");
        $mainArrayKeys = array_keys($parsedYaml);
        $expectedKeys  = array("author", "category", "article", "articleCategory");

        $this->assertEquals($expectedKeys, $mainArrayKeys);

    }

    public function testSecondLevelElement() {
        $parsedYaml    = $this->yamlParser->load("article.yml");
        $actualArticle = $parsedYaml["article"][0];
        $title         = "How to Use YAML in Your Next PHP Project";
        $content = "YAML is a less-verbose data serialization format. "
                 . "It stands for "YAML Ain't Markup Language". "
                 . "YAML has been a popular data serialization format among "
                 . "software developers mainly because it's human-readable.n";

        $expectedArticle = array("id" => 1, "title" => $title, "content" => $content, "author" => 1, "status" => 2);

        $this->assertEquals($expectedArticle, $actualArticle);
    }

    /**
     * @expectedException YamlParserException
     */
    public function  testExceptionForWrongSyntax() {
        $this->yamlParser->load("wrong-syntax.yml");
    }
}

А вот класс оболочки:

 <?php
require_once "yaml/sfYaml.php";

class YamlParser
{
    public function load($filePath) {
        try {
            return sfYaml::load($filePath);
        }
        catch (Exception $e) {
            throw new YamlParserException(
                $e->getMessage(), $e->getCode(), $e);
        }
    }

    public function dump($array) {
        try {
            return sfYaml::dump($array);
        }
        catch (Exception $e) {
            throw new YamlParserException(
                $e->getMessage(), $e->getCode(), $e);
        }
    }
}

class YamlParserException extends Exception
{
    public function __construct($message = "", $code = 0, $previous = NULL) {
        if (version_compare(PHP_VERSION, "5.3.0") < 0) {
            parent::__construct($message, $code);
        }
        else {
            parent::__construct($message, $code, $previous);
        }
    }
}

Резюме

Теперь вы знаете, что такое YAML, как представлять массивы PHP в YAML и как интегрировать синтаксический анализатор PHP YAML в свои проекты. Потратив немного больше времени на использование синтаксиса YAML, вы сможете использовать его мощные функции. Вы также можете рассмотреть возможность использования платформ Symfony 1.4 и 2, которые широко используют YAML. И если вы заинтересованы в игре с кодом из этой статьи , он доступен на GitHub.

Изображение через Fotolia