Сегодня речь пойдет о работе с 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 купить киев


