Джино: хостинг и веб-сервисы

Система Orphus
Russian version
Добавить на Del.icio.us
English version
Добавить на Digg.com

 dkLab | Конструктор | Dom_varimport: PHP-расширение для преобразования вложенных массивов в DOMDocument 

Карта сайта :: Форум «Лаборатории» :: Проект «Денвер»
Проект «Orphus» :: Куроводство: наблы :: Конструктор


2014-04-17

Принять участие в разработке библиотеки/утилиты можно на GitHub.

Некоторые проекты используют XSLT в качестве основного "движка" шаблонов. Помимо известных недостатков XSLT (например, его многословности) у него есть и преимущества: например, "стандартность" языка, его идеология отсутствия "побочных эффектов" и широко применяемый pattern matching, богатые возможности по наследованию шаблонов и блоков, возможность при необходимости вызывать PHP-функции или методы helper-классов из шаблонов (через exslt-расширение). Какое-то время назад я писал про библиотеку ShortXSLT, позволяющую вместо громоздких <xsl:value-of select="/root/abc"/> и <xsl:choose>...</xsl:choose> писать просто {/root/abc} и {if...}...{elseif}...{/if}, так что проблема многословности отчасти решается.

Но сейчас речь не о преимуществах и недостатках XSLT (я уверен, и противники, и сторонники этой технологии найдутся в изобилии). Я бы хотел описать один прием, который удобно применять в существующих проектах с XSLT-шаблонами, и привести ссылку на библиотеку, реализующую данный прием с хорошей производительностью.

Передаем данные в XSLT, минуя генерацию текстового представления XML

Представьте, что у нас есть контроллер, генерирующий некоторый вложенный PHP-список объектов для отображения на странице. Он должен этот массив преобразовать в XML, который потом пойдет на вход XSLT-шаблону. Хорошо бы, чтобы данное преобразование из структур PHP в XML выполнялось не вручную в каждом контроллере, а был некоторый промежуточный слой абстракции, который умеет применять XSLT-шаблон прямо к PHP-данным, минуя текстовое XML-представление. Так мы уменьшим вероятность ошибок, да и письмо сократится. Мы сможем работать с XSLT-шаблонами напрямую, минуя XML-представление данных.

Некоторое время назад я написал на Си PHP-расширение dom_varimport. Оно содержит одноименную функцию, на вход которой подается объект DOMDocument и PHP-массив любой вложенности. Функция заполняет переданный ей DOMDocument XML-представлением входного массива, и делает она это очень быстро — примерно в 20 раз быстрее, чем делал бы код, написанный на чистом PHP. Большой документ размером около 1 МБ с тысячами вложенных свойств и объектов формируется примерно за 1-2 миллисекунды.

Например, вызов:

Листинг 1: Пример вызова dom_varimport()
$doc = new DOMDocument();
dom_varimport(
    $doc,
    array(
        "some_key" => 111,
        123,
        0.5,
        "arr" => array("1a" => "1a"),
        "obj" => (object)array("prop" => "val"),
        true,
        false,
        "b" => null,
        "empty" => array(),
    ),
    "root" // optional, defaults to "root"
);
$doc->formatOutput = true;
echo $doc->saveXML();

напечатает вот такой XML-документ:

Листинг 2: Результирующий XML-документ
<?xml version="1.0"?>
<root>
    <some_key key="some_key">111</some_key>   <!-- plain key=value -->
    <item key="0">123</item>         <!-- numeric keys are "item" tags -->
    <item key="1">0.5</item>         <!-- double -->
    <arr key="arr">                  <!-- nested array -->
        <item key="1a">1a</item>         <!-- invalid tag names are converted to "item" -->
    </arr>
    <obj key="obj">                  <!-- nested object -->
        <prop key="prop">val</prop>
    </obj>
    <item key="2">1</item>           <!-- true converts to 1 -->
    <item key="3"/>                  <!-- false converts to an empty string -->
    <b key="b"/>                     <!-- null also converts to an empty string -->
    <empty key="empty"/>             <!-- empty array is an empty element -->
</root>

Как видите, все достаточно прозрачно: ключи массива и свойства объектов становятся XML-элементами, по возможности с теми же именами (но если имя недопустимо для XML-элемента, то вместо него используется "item"). Такой XML-документ очень легко читать при отладке, он весьма компактен.

Как установить расширение

Расширение написано на Си, поэтому его нужно откомпилировать на машине, на которой установлены GCC и пакеты типа php5-src (или php5-devel). Это совсем не страшно:

Листинг 3: Компилируем расширение и получаем modules/dom_varimport.so
git clone https://github.com/DmitryKoterov/dom_varimport.git
cd dom_varimport
phpize
./configure
make
make test
make install  # or copy modules/dom_varimport.so manually
phpize --clean

Этап "make install" можно и не делать: достаточно взять бинарный файл modules/dom_varimport.so и скопировать его в директорию с расширениями PHP (например, /usr/lib/php5), в том числе и на других машинах. Наконец, нужно подключить расширение и перезапустить php5-fpm или apache:

Листинг 4: Файл /etc/php5/conf.d/dom_varimport.ini
extension = /usr/lib/php5/dom_varimport.so





Лучшие сео компании - Скобеев и Партнеры


Дмитрий Котеров, Лаборатория dk. ©1999-2016
GZip
Добавить на Del.icio.us   Добавить на Digg.com   Добавить на reddit.com