Основы PHP
  Что такое PHP?
  Возможности PHP
  Преимущества PHP
  История развития
  Что нового в PHP5?
  «Движок» PHP
  Переход на PHP 5.3
New Переход на PHP 5.6
  Введение в PHP
  Изучение PHP
  Основы CGI
  Синтаксис PHP
  Типы данных PHP
  Переменные в PHP
  Константы PHP
  Выражения PHP
  Операторы PHP
  Конструкции PHP
  Ссылки в PHP
  PHP и ООП
  Безопасность
  Функции PHP
  Функции по категориям
  Функции по алфавиту
  Стандартные функции
  Пользовательские
  PHP и HTTP
  Работа с формами
  PHP и Upload
  PHP и Cookies
  PHP и базы данных
  PHP и MySQL
  Документация MySQL
  Учебники
  Учебники по PHP
  Учебники по MySQL
  Другие учебники
  Уроки PHP
  Введение
  Самые основы
  Управление
  Функции
  Документация
  Математика
  Файлы
  Основы SQL
  Дата и время
  CURL
  Изображения
  Стили
  Безопасность
  Установка
  Проектирование БД
  Регулярные выражения
  Подготовка к работе
  Быстрый старт
  Установка PHP
  Установка MySQL
  Конфигурация PHP
  Download / Скачать
  Скачать Apache
  Скачать PHP
  Скачать PECL
  Скачать PEAR
  Скачать MySQL
  Редакторы PHP
  Полезные утилиты
  Документация
  PHP скрипты
  Скачать скрипты
  Инструменты
  PHP в примерах
  Новости портала
 Главная   »  Сборник статей
 
 

Обмен данными между приложениями с помощью XML+WDDX

Автор: Владимир Водолазкий, к.т.н.

В статье рассматривается методика организации кроссплатформенного межзадачного обмена данными на основе XML с применением WDDX-пакетов. Приведенные примеры демонстрируют возможность как формирования входных документов, так и загрузки массивов в формате XML+WDDX в PHP-приложение.
Одна из весьма серьезных проблем, возникающих при Web-программировании заключается в необходимости стыковки между расличными задачами (программами), объединяемыми в Internet/Intranet-систему. Например, при разработке сложных систем, которые ведутся в несколько этапов различными коммандами разработчиков, может возникнуть ситуация, при которой часть модулей реализована на Perl, а часть - на PHP.
Достаточно удобное решение возникающих в такой ситуации многочисленных проблем, которое было предложено фирмой Allaire, разработчиком известной инструментальной системы Gold Fusion, основано на формате XML. А точнее на одном из его расширений.
WDDX (Web Distributed Data eXchange - обмен данными, распределенными в сети), является производным от XML и предоставляет достаточно удобный механизм, позволяющий конвертировать структуры данных из Perl, Javascript или PHP в некоторый унифицированный формат на базе XML или обратно. (В отличие от пакета Gold Fusion, WDDX выпущен как проект с открытым кодом. Вы можете загрузить WDDX SDK с сервера http://www.openwddx.org. А при необходимости обеспечить работу с WDDX из программы на Perl, воспользуйтесь модулем WDDX.pm с CPAN.)

1. Первое знакомство с WDDX

Главное преимущество WDDX заключается в прозрачной для программиста поддержке не только разнообразных "элементарных" типов данных: строк, чисел, логических значений, даты и времени, но и составных - массивов, структур и записей. Кроме того, WDDX позволяет представлять и двоичные данные, например, графические изображения. Естественно, поддерживается как вывод, так и ввод данных.
По умолчанию, поддержка WDDX в PHP отключена, чтобы ее активизировать и иметь возможность проверить работоспособность примеров этой статье, вы должны перекомпилировать PHP-машину с конфигурационным ключом --enable-wddx.
После перезагрузки WWW-сервера с поддержкой WDDX мы можем приступить к изучению возможностей этого протокола. Вначале попробуем сериализировать (преобразовать в формат, пригодный для обмена) одно отдельное значение. Хитрость WDDX, которая находит отражение в терминологии, состоит в том, что исходные данные преобразуются в так называемые "пакеты данных", которые инкапсулируют имя переменной, её тип и значение.
Поэтому приведенная ниже программа:

<?php
print wddx_serialize_value("Преобразование PHP в WDDX", "PHP пакет");
?>

приведет к формированию пакета (текстовой строки):

<wddxPacket version='1.0'>
<header comment='PHP пакет'/>
<data>
<string>
Преобразование РНР в WDDX
</string>
</data>
</wddxPacket>

Итак, что мы видим... Вначале в поток помещен тэг, представляющий собой идентификатор версии протокола WDDX. Версия 1.0 является единственной существующей, поэтому просто принимайте эту информацию к сведению. Затем следует комментарий, в котором содержится либо описание переменной, либо иногда помещается имя переменной, в которой хранились данные в исходной программе. А уже затем следует тэг (в данном случае <string>), который определяет тип переменной и её значение.
Но использовать WDDX для хранения отднльных, изолированных переменных на практике не слишком удобно. Поэтому в WDDX предусмотрен механизм "накопления" переменных, подлежащих сериализации, с последующим помещением их "в один флакон". Вот как это выглядит на практике:

<?php
$pi = 3.1415926;
// Создаем пакет, в который будем сбрасывать данные
// Сразу же определяем его заголовок, в котором обычно
// помещается назначенние и/или происхождение пакета
$packet_id=wddx_packet_start("PHP");
// добавляем первую переменную
wddx_add_vars($packet_id,"pi");

// А теперь определим массив $cities
$cities=array("Austin", "Novato", "Seattle");
// и тоже сбросим его в пакет
wddx_add_vars($packet_id, "cities");

// теперь закрываем (и формируем) пакет
$packet=wddx_packet_end($packet_id);
// это большая строка, в которой содержится все
// помещенные в пакет переменные
print $packet;
?>

В результате выполнения этой программы вы получите следующий пакет WDDX:

<wddxPacket version='1.0'><header comment='PHP'/>
<data>
<struct>
<var name='pi'><number>3.1415926</number>
</var>
< name='cities'>
<array length='3'>
<string>Austin</string>
<string>Novato</string>
<string>Seattle</string>
</array>
</var>
</struct>
<data>
<wddxPacket>

2. Функции WDDX-генератора и анализатора

Теперь давайте приступим к подобному обсуждению функций WDDX.

2.1 Сериализация переменной - wddx_serialize_value

string wddx_serialize_value (mixed var [, string comment])

Функция wddx_serialize_value() используется для создания WDDX пакета, содержащего одно единственое значение. Это значение извлекается из переменной var, а при наличии необязательного комментария comment, он добавляется в заголовок пакета. Результатом работы функции является сформированный WDDX-пакет.

2.2 Сериализация множества - wddx_serialize_vars

string wddx_serialize_vars (mixed var_name [, mixed ...])

Функция wddx_serialize_vars() предназначена для создания пакета WDDX, в котором содержится структура с сериализованным представлением множества переменных, переданный в качестве аргументов функции.
Функция принимает переменное количество аргументов, каждый из которых может представлять собой либо строку, значение которойявляется именем переменной, подлежащей помещению в пакет, либо массив, элементы которого являются именами переменных или массивов, которые содержат такие имена и т.д. В общем рекурсивные возможности функции, на которые несомненное влияние оказал Лисп, предоставляют широкий простор для деятельности...
Вот так эта функция может использоваться в прикладной программе:

<?php
$a=1;
$b=5.5;
$c=array("blue","orange","violet");
$d="colors";

$clvars=array("c","d");
print wddx_serialize_vars("a","b",$clvars);
?>

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

<wddxPacket version='1.0'>
<header/>
<data>
<struct>
<var name='a'>
<number>1</number>
</var>
<var name='b'>
<number>5.5</number>
</var>
<var name='c'>
<array length='3'>
<string>blue</string>
<string>orange</string>
<string>violet</string>
<array>
<var>
<var name='d'>
<string>colors</string>
</var>
</struct>
</data>
</wddxPacket>

2.3 Создание нового пакета - wddx_packet_start

int wddx_packet_start ([string comment])

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

2.4 Закрытие пакета - wddx_packet_end

string wddx_packet_end (int packet_id)

Функция wddx_packet_end() завершает обработку пакета WDDX, идентифицируемого с помощью packet_id и возвращает строку, содержащую сформированный пакет.

2.5 Добавление данных в пакет - wddx_add_vars

wddx_add_vars (int packet_id, mixed name_var [, mixed ...])

Функция wddx_add_vars() используется для сериализации переданных ей аргументов с помещением в открытый ранее пакет с идентификатором id. Переменные, которые подлежат сериализации, определяются так же, как и в функции wddx_serialize_vars().

2.6 Восстановление данных - wddx_deserialize

mixed wddx_deserialize (string packet)

Функция wddx_deserialize() принимает в качестве аргумента строку, содержащую пакет WDDX, анализирует ее и восстанавливает переменные, содержащиеся в ней. Возвращаемый результат может представлять собой строку, число или массив. Сложные структуры данных при восстановлении помещаются в ассоциативные массивы.

3. Генерация системного журнала в XML+WDDX

Теперь, в качестве иллюстрации, рассмотрим практический пример работы подсистемы обработки ошибок в РНР (Листинг 1). Мы создадим собственную функцию обработчика ошибок, которая будет генерировать журнал, представленный в модном XML-формате, а также отправлять письмо администратору узла при обнаружении критических ошибок. Поскольку нам придется иметь дело с массивами, для их помещения в журнал мы воспользуемся WDDX.
Возможно, пример покажется вам достаточно длинным, но, поверьте, дело того стоит...
Состоит он из двух основных частей - формирования журнала и его последующего просмотра. Поскольку пользователь nobody, от имени которого обычно запускаются PHP-программы на сервере Apache, не имеет особых прав на работу с файловой системой, для размещения системного журнала мы будем использовать каталог tmp. В некоторых версиях Linux доступ на запись в этот каталог "посторонним" пользователям закрыт. Поэтому вам может потребоваться изменить права доступа к нему с помощью команды (такая комманда - это грубейшее нарушение безопасности и не рекомендуется проводить на узлах, подключенных с сети Интернет)
chmod a+w /tmp
Обратите внимание на команду unlink в самом начале программы. Дело в том, что XML-документ может содержать только один элемент верхнего уровня, а команда error_log осуществляет \textit{дописывание в конец существующего файла}. Поэтому, если вы не будете создавать системный журнал заново, то выполнить программу больше одного раза просто не сможете - анализатор XML аварийно завершит работу при обнаружении второго документа верхнего уровня.
После этого мы создаем новый файл журнала и помещаем в него открывающий тег <ERRORLOG>. Затем устанавливаем свой собственный обработчик ошибочных ситуаций, в задачу которого входит сформировать запись в XML-формате, которая будет записана в журнал.
До тех пор, пока структура записи определена достаточно жестко:

<ERRORLOG>
<ERRORENTRY>

<DАТЕТIМЕ>Дата и время события</DАТЕТIМЕ>
<ERRORNUM>Koд ошибки</ERRОRNUM>
<ERRORTYPE>Kaтeгopия</ERRORTYPE>
<ERRORMSG>Cooбщeнue об ошибке</ЕRRОRMSG>
<SСRIРТNAМЕ>Файл. в котором зафиксирована ошибка</SСRIРТNAМЕ>
<SCRIPTLINENUM>Hoмep строки в <j>aline</SCRIPTLINENUM>

</ERRORENTRY>

И никакой необходимости в использовании WDDX не возникает. Эти данные без особых проблем считываются и разбираются анализатором XML. Но в некоторых ситуациях нам бы хотелось, чтобы в системный журнал наряду с текстом сообщения об ошибках помешались также значения переменных, действующих на момент возникновения этой ошибки. Стандартный механизм обработки ошибочных ситуаций PHP-машины этой информации нам не дает.
Но мы сможем справиться с этой проблемой и самостоятельно... Для этого нам достаточно всего трех строчек:

$еrr .= "\t<VARTRACE>":
$err .= wddx_serialize_value($vars,"Variables");
$err .= "</VARTRACE>\n";

В результате мы создаем собственный элемент XML-документа <VARTRACE>. внутри которого поместим WDDX-пакет, составленный из списка локальных переменных (аргумент $vars, определенных в процедуре в момент обнаружения ошибки. Понятно, что и имена, и значения этих переменных будут меняться от функции к функции и от ошибки, к ошибке. Но для нас важно другое - РНР-машина автоматически формирует WDDX-пакет (который представлен в унифицированном, кроссплатформенном формате) и затем помещает его в выходной файл. В результате мы получаем запись вида:

<ERRORENTRY>
<DATETIME>09-Aug-2001 10:44:42</DATETIME>
<ERRORNUM>512</ERRORNUM>
<ЕRRORTYPE>Предупрехдение пользователя</ЕRRORTYPE>
<ERRORMSG>2-я координата вектора 1 не является чиспом</ERRORMSG>
<SCRIPTNAME>/usr/local/apache/htdocs/php/part2/error-proc.php</SCRIPTNAME>
<SCRIPTLINENUM>107</SCRIPTLINENUM>
<VARTRACE><wddxPacket version='1.0'>
<header>
<comment>Variables</comment>
</header>
<data>
<struct>
<var name='vect1' >
<array length='3'>
<number>2</number>
<number>3</number>
<string>foo</string>
</array>
</var>
<var name='vect2'>
<array length='3'>
<number>5.5</number>
<number>4.3</number>
<number>-1.6</number>
</array>
</var>
<var name='i'>
<number>2</number>
</var>
<var name='c1'>
<string>foo</string>
</var>
<var name='c2'>
<number>-1.6</number>
</var>
<var name='d'>
<number>0</number>
</var>
</struct>
</data>
</wddxPacket>
</VARTRACE>
</ERRORENTRY>

Как видите, WDDX-пакет органично помещается внутрь XML-документа, что одновременно и хорошо, и плохо. Хорошо с той точки зрения, что позволяет аккуратно закруглить (как это сделано в большинстве книг и руководств по РНР) обсуждение вопроса, заявив, что использование функции wddx_desrialize() автоматически решит все ваши проблемы. А плохо потому, что это на самом деле не так, и анализ XML-документа со встроенными пакетами WDDX реализуется не столь прямолинейно, как нам хотелось бы.
Собственно говоря, именно поэтому в рассматриваемый нами пример я включил и собственную версию анализатора на базе библиотеки Expat, ориентированную именно на обработку сгенерированного нами файла.
Проблема заключается именно в том, что теги WDDX ничем по сути не отличаются от тегов XML, a следовательно, они будут автоматически обрабатываться обработчиками событий. Но так ли это здорово на самом деле? Ведь чтобы разобрать XML-документ с вложенными WDDX-пакетами вам потребуется фактически самостоятельно реализовать обработку тегов WDDX внутри анализатора? При этом вам не удастся "просто так" получить исходный код пакета, который можно одним вызовом функции превратить в структуру данных, аналогичную той, которая использовалась для синтеза пакета. Но разве мы за это боролись?
Единственное достаточно компактное решение состоит в том, что мы в процессе анализа восстанавливаем текст WDDX-пакета со всеми его атрибутами, а после завершения его сборки (о чем нам сигнализирует тег </VARTRACE>) мы разбираем полученный нами пакет функцией wddx_deserialize, а уже затем извлекаем из нее список переменных и их значения.
Как видите, нам удалось реализовать механизм отладки программы, который позволяет старым добрым методом контрольной печати вскрыть практически любые ошибки времени исполнения программ. Но гораздо важнее, что теперь в вашем распоряжении имеется механизм, позволяющий полностью реализовать межзадачный обмен данными - как из приложения на РНР, так и загрузить данные из внешнего мира.
Литература

o [Vodolaz2000] В.Барсуков, В.Водолазкий Интегральная безопасность в системах и сетях передачи данных. М.: Knowledge, 2000, 450 стр.
o [Vodolaz2001] В.Водолазкий, А.Колядов Путь к Linux, изд. 2-е, М.: Knowledge, 2001, 560 стр.
o [XML2000] Н.Питц-Моултис, Ч.Кирк XML: Современная технология создания документов для Internet - С-Пб.: БХВ-Петербург, 2000, 736 стр.
o [php2001] Т.Ратшиллер, Т.Геркен РНР4: Разработка Web-приложений, С-Пб.: Питер, 2001, 384 стр.
o [Huews-2001] С.Хьюз, А.Змиевский РНР. Руководство разработчика, К.: Diasoft, 2001, 380 стр.
Листинг 1. Пример программы, генерирующей системный журнал.

<HTML>
<ТITLE>Генератор системного журнала в ХМL-Формате</ТITLE>
<BODY BGCOLOR="#FFFFFF">
<hЗ>Демонстрация работы пользовательского обработчика ошибок</hЗ>
В этой программе осуществляется формирование
пользовательского системного журнала, который располагается в
каталоге <b>/tmp</b>. Формат системного журнала - XML+WDDX.<p>

<h4>Первый этап - генерация журнала</h4>
<?рhр

$sysadmin = "root@1ocalhost"; // адрес администратора системы,
// который получает сообщение об ошибке в программе

@unlink("/tmp/errorlog.txt"); // прежний журнал не нужен
// Закрываем префиксом @ для предотвращения генерации сообщения
// при отсутствии такого файла

// Вначале открываем сеанс для записи
error_log("<ERRORLOG>\n".3."/tmp/errorlog.txt");

// И вводим свой собственный обработчик ошибок
function userErrorHandler ($errno, $errmsg, $filename, $linenum, $vars){
// Формат отображения времени о журнале в память об
// операционной системе РАФОС (RT-11)
$dt = date("d-M-Y H:i:s");

// теперь создадим хэш-массив с кодами и категориями
// сообщений об ошибках
$errortype = array (
1 => "Ошибка".
2 => "Предупреждение",
4 => "Ошибка компилятора",
8 => "Подсказка",
16 => "Ошибка РНР-машины",
32 => "Предупреждение РНР-машины",
64 => "Ошибка компилятора",
128 => "Предупреждение компилятора",
256 => "Ошибка пользователя",
512 => "Предупреждение пользователя",
1024 => "Подсказка пользователя"
);
// Сформируем маску отслеживаемых событий
$user_errors = array(E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE);

// теперь сформируем XML-запись сообщения об ошибке
// Поскольку формат прост, мы не будем использовать DOM-модель
// с автоматической генерацией документа...

$err ="<ERRORENTRY>\n .
$err.="
<DATETIME>".$dt."</DATETIME>\n";
$err.="
<ERRORNUM>".$errno."</ERRORNUM>\n";
$err.="
<ERRORTYPE>".$errortype[$errno]."</ERRORTYPE>\n";
$err.="
<ERRORMSG>".$errrmsg."</ERRORMSG>\n";
$err.="
<SCRIPTNAME>" $filename."</SCRIPTNAME>\n":
$err.="
<SCRIPTLINEMUM>".$linenum."</SCRIPTLINENUM>\n";

if (in_array($errno, $user_errors))
{
// Массив преобразуем с помощьо WODX
$err = "
\t<VARTRACE>";
$err.= wddx_serialize_value($vars, "
Variables");
$err.= "
</VARTRACE>\n";
}

$err.= "
</ERRORENTRY>\n\n";

// тестовая печать в процессе отладки программы
// echo "<pre>$err</pre><p>";

// теперь помешаем сформированную запись в журнал, и если
// это критическая ошибка, генерируем сообщение системному
// администратору
error_log($err, 3, "
/tmp/errorlog.txt");
if ($errno == E_USER_ERROR)
mail($sysadmin, "
Критическая ошибка в программе!".$err);

}

// Функция, вычисляющая расстояние между двумя векторами.
// которая генерирует немало сообщений об ошибках
function distance ($vect1, $vect2) {

if (is_array($vect1) || !is_array($vect2)) {
trigger_error("
Недопустимый тип аргументов!",
E_USER_ERROR);
return NULL;
}

if (count($vect1) != count($vect2)) {
trigger_error("
Векторы должны иметь одинаковый размер",
E_USER_ERROR);
return NULL;
}

for ($i=0; $i<count($vect1); $i++) {
$c1 = $vect1[$i];
$c2 = $vect2[$i];
$d = 0.0;

if (!is_numeric($c1)) {
trigger_error("
$i-я координата вектора 1
не является числом",E_USER_WARMING);
$c1 = 0.0;
}

if (!is_numeric($c2)) {
trigger_error("
$i-я координата вектора 2
не является числом", E_USER_WARNING);
$c2 = 0.0;
}

$d += $c2*$c2 - $c1*$c1.
}
return sqrt($d);
}

// переустанавливаем обработчик ошибок
$old_error_handler = set_error_handler("
userErrorHandler");

?>

<ul>
<li>Неопределенная константа - сформирует сообщение об ошибке

<?
$t = I_AM_NOT_DEFINED;

// теперь создадим несколько векторов
$а = array(2.3, "
foo");
$b = array(5.5, 4.3, -1.6);
$c = array (1,-3);

?>

<li>Генерируем сообщение об ошибке при вычислении функции
<?
$t1 = distance($c,$b)."
\n";
?>

<li> и еще одно - о неверных аргументах
<?
$t2 = distance($b,"
А я не массив...")."\n";
?>

<li>А в заключение, сгенерируем предупреждение...
<?
$t3 = distance($a,$b)."
\n";

// Восстановим системный обработчик
restore_error_handler($old_error_handler);
error_log("
</ERRORLOG>\n",3,"/tmp/errorlog.txt");

?>
</ul>
<h4>Восстанавливаем содержимое журнала и выводим его в виде таблицы</h4>

<?
class logger {
var $xml_parser;
var $xml_file;
var $html;
var $open_tag;
var $close_tag;
var $wddx_flag; // флажок обнаружения WDDX-пакета
var $wddx; // поток WDDX-данных (сборка пакета)

// Конструктор класса
function logger () {
$this->xml_parser = "
";
$this->xml_file = "
";
$this->html = "
";
$this->wddx_flag = 0;
$this->wddx = "
";
$this->open_tag = array(
// Настраиваем интерпретатор отдельных
// тегов нашего заказного формата
"
ERRORLOG" => "<TABLE CELLPADDING=5>",
"
ERRORENTRY" => "<TR><TD BGCOLOR=#f2f2f2>".
"
DATETIME" => "<FONT COLOR=#883800>",
"
ERRORNUM" => "<TD 8GCOLOR=#f2f2f2>",
"
Код ошибки: <FONT COLOR=#000A0C<B> ",
"
ERRORTYPE" => "Категория ошибки: <FONT COLOR=#3F3F00>",
"
ERRORMSG" => '<FONT SIZE=-1><FONT COLOR=#D22323>",
"SCRIPTNAME" => "<р>Файл: ",
"SCRIPTLINENUM" => "строка - <B>",
"VARTRACE" => "<p><FONT COLOR=\"BLUE\">Пepeмeнныe:");

// а здесь - закрывавшие теги
$this->close_tag = array(
"ERRORLOG" => "</TABLE>\n\n",
"ERRORENTRY" => "</TD></TR>",
"DATETIME" => "</FONT></TD>",
"ERRORNUM" => "</B>",
"ERRORTYPE" => "<br>",
"ERRORHSG" => "</FONT></FONT>",
"SCRIPTNAME" => " ",
"SCRIPTLINENUM => "</B>",
"
VARTRACE" => "</FONT> ");
}

// Деструктор класса. В отличие от Си++ и Perl его
// необходимо вызывать вручную
function destroy() {
xml_parser_free( $this->xml_parser);
}

//Основные функции введенного нами класса
function concat($str) {
// дописывает в генерируемый HTML-поток очередную строку
$this-> html .= $str;
}

// Вызывается при начале нового элемента в документе
function startElement( $parser, $name. $attrs) {

if ($format= $this->open_tag[$name]) {
$this-> html .= $format;
}

if ($name == "
VARTRACE") {
$this->wddx_flag = 1;
$this->wddx = "
":
} else
if ($this->wddx_fiag == 1) {
$this->wddx .= "
<".$name." "; // открываем тег
// теперь обрабатываем его аргументы (атрибуты)
while (list ($key, $val) = each($attrs)) {
$this->wddx .= $key."
='".$val."'";
}
$this->wddx .= "
>";
}
}
}
// Вызывается при окончании обработки элемента
function endElement($parser, $name ){
global $close_tag;
if ($format= $this->close_tag[$name]){
$this->html .= $format;
}
if ($name == "
VARTRACE"){
$this->wddx_flag = 0;
$m = wddx_deseriali2e($this->wddx);
// отладочная печать
// echo "<pre>".$this->wddx."</pre>";
// var_dump($m);
while (list ($key,$val) = each($m)){
// Добавляем в поток HTML информацию о переменных
$this->html.= "
Аргумент <font color=\"black\">";
$this->html.= "
<b>".$key."</b></font>: ";
if (is_array($val)){
$this->html.= implode(',',$val);
}
else{
$this->html.= $val;
}
$this->html.= "
";
}
}
if ($this->wddx_flag == 1){
$this->wddx.="
</".$name.">";
}
}

// Обработчик символьных данных СDАТА
function characterData ($parser, $data ) {
// во избежание недомолвок
if ($this->wddx_flag == 1) {
this->wddx.= $data;
}
else{
$this->html.= $data;
}
}

// Разбор файла
function parse() {
$this->xml_parser= xml_parser_create();
xml_set_object($this->xml_parser, &$this);
// обратите внимание на нивелирование регистров тегов
// что позволяет при лобом раскладе установить соответствие
// их с записями $mар_аrrау
xml_parser_set_option($this->xml_parser,
XML_OPTION_CASE_FOLDING, false );
xml_set_element_handler($this->xml_parser,
"
startElement", "endElement");
xml_set_character_data_handler($this->xml_parser,"
characterData");

if (!($fp = fopen($this->xml_file,"
r"))) {
die("
He могу открыть входной файл XML");
}

while ($data = fread($fp, 4096)) {
if (!xml_parse($this->xml_parser, $data, feof($fp))) {
die(sprintf("
Ошибка в XML файле : %s на строке %d",
xml_error_string( xml_get_error_code(
$this->xml_parser )),
хml_get_current_line_number($this->xml_parser)));
}
}
}

$log = new_logger();
$log->xml_file ="
/tmp/errorlog.txt";
$log->parse();
print ($log->html);

$log->destroy();

?>

 
 » Обсудить эту статью на форуме

 
 Сборник статей 
 Содержание раздела 
Есть еще вопросы или что-то непонятно - добро пожаловать на наш  форум портала PHP.SU 
 

 
Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS