Сегодня речь пойдет о работе с XML, а точнее об отправке данных PHP скриптов браузеру в формате XML.
Сразу скажу, что готовых решений в этой области существует масса. Но написание собственного скрипта занимает не больше времени, чем поиск и изучение чужого варианта. К тому же, добавить новые функции в свой скрипт значительно проще.
Постановка задачи
Есть PHP массив (может быть многомерным). Нужно получить xml строку с данными из этого массива.
Немного теории
В дистрибутив PHP входит модуль XMLWriter, который предназначен для записи данных в XML формате. Использовать непосредственно этот модуль в своих скриптах не очень удобно, т.к. он поддерживает только самые базовые функции и преобразование массива в этот формат «выливается» в несколько десятков строк кода.
Поэтому мы напишем собственный класс (Array2XML), который будет представлять собой оболочку для XMLWriter'а и решать одну узкую задачу – преобразовывать PHP массив в XML формат.
Прежде чем переходить к коду класса покажу, как им пользоваться.
require_once('Array2XML.php'); header('Content-type: application/xml'); $data = array( 'val1' => 111, 'val2' => '222', 'val3' => 333, 500, 'container' => array( 'mystr' => 'test test', 'myobj' => array( 'x' => 250, 'y' => 150, 'name' => 'objName' ) ) ); $converter = new Array2XML(); $xmlStr = $converter->convert($data); echo $xmlStr;
Как видите, после подключения файла с классом и установки заголовка (строки 1, 3), мы объявили массив с данными.
Обратите внимание. Не для всех элементов массива явно заданы имена ключей.
После этого, мы создаем объект типа Array2XML()
и вызываем его метод convert
. В качестве параметра этот метод получает наш массив. Как несложно догадаться, после его выполнения мы получим XML документ с данными из массива.
И сразу же покажу скриншот страницы с результатом работы скрипта.
Думаю, принцип преобразования понятен. Для каждого элемента массива мы создаем XML тег, название которого совпадает с ключом элемента в массиве. Внутрь этого тега мы вставляем значение элемента.
Если массив многомерный, то его структура будет полностью повторяться в XML документе (вложенные массивы будут находиться внутри соответствующих тегов).
Единственное отличие в названиях касается элементов массива, для которых явно не заданы ключи. PHP присваивает им порядковые номера, но число нельзя использовать в качестве XML тега. Поэтому я добавил к его номеру приставку «key». Лучше, конечно, задавать ключи для всех элементов массива явно.
Теперь переходим непосредственно к классу
class Array2XML { private $writer; private $version = '1.0'; private $encoding = 'UTF-8'; private $rootName = 'root'; function __construct() { $this->writer = new XMLWriter(); } public function convert($data) { $this->writer->openMemory(); $this->writer->startDocument($this->version, $this->encoding); $this->writer->startElement($this->rootName); if (is_array($data)) { $this->getXML($data); } $this->writer->endElement(); return $this->writer->outputMemory(); } public function setVersion($version) { $this->version = $version; } public function setEncoding($encoding) { $this->encoding = $encoding; } public function setRootName($rootName) { $this->rootName = $rootName; } private function getXML($data) { foreach ($data as $key => $val) { if (is_numeric($key)) { $key = 'key'.$key; } if (is_array($val)) { $this->writer->startElement($key); $this->getXML($val); $this->writer->endElement(); } else { $this->writer->writeElement($key, $val); } } } } //end of Array2XML.php
Прежде всего, в конструкторе мы создаем объект типа XMLWriter
. С помощью которого, будем выполнять всю рутинную работу.
Теперь, обратите внимание на метод convert
(строки 14-23). В качестве единственного параметра он получает массив с данными.
Метод openMemory()
начинает запись нового XML документа.
startDocument
– вставляет заголовок.
startElement($this->rootName)
– создает корневой тег. По-умолчанию, используется имя root, но его можно изменить.
После этого, мы проверяем, являются ли полученные данные массивом (строка 18) и вызываем метод getXML
(строки 33-47), который и выполняет преобразование массива в XML формат.
Рассмотрим его подробнее. Алгоритм следующий:
1) обходим в цикле массив;
1.1) если ключ текущего элемента является числом, добавляем к нему приставку «key»;
1.2) если текущий элемент является массивом:
1.2.1) создаем открывающий тег, в качестве названия используем ключа данного элемента (строка 39);
1.2.2) вызываем метод getXML
, а в качестве параметра передаем текущий элемент, т.е. вложенный массив (рекурсия);
1.2.3)создаем закрывающий тег;
1.3) создаем тег для текущего элемента массива (с помощью метода writeElement
)
Важно. PHP позволяет задать максимальную глубину рекурсии. И если глубина вложенности массивов будет больше этого значения, то скрипт просто не будет работать.
Кроме того, класс содержит методы, которые позволяют указать версию XML, кодировку и имя корневого тега (setVersion
, setEncoding
, setRootName
).
Как видите, класс получился довольно простой, но вполне работоспособный 🙂
Скачать
Вы можете скачать архив с этим примером.
P.S. Если у вас есть аналогичное решение буду рад обсудить 😉
Интересно почитать:
Оптимизация сайтов — единственный способ вырваться в ТОП поисковиков.
Хотите отдохнуть и расслабиться? Японский сад создаст нужное настроение.
Забудьте о CD болванках. DVD диски превосходят их по всем параметрам. dvd купить киев