Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

PHP5_nachinayushim

.pdf
Скачиваний:
29
Добавлен:
20.03.2015
Размер:
26.79 Mб
Скачать

354 Глава 8

в PHP4 задействуют программу Джеймса Кларка (James Clark) expat (синтаксический анализатор XML 1.0, написанный на языке C). Expat+анализаторы могут определить, является ли XML+документ правильно сформированным, но не проверяют коррект+ ность XML+документов. Поэтому анализаторам, созданным на основе expat, необхо+ димо передавать правильно сформированные XML+документы. В противном случае будет сгенерирована ошибка (место возникновения ошибки можно локализовать).

Ниже перечислены некоторые наиболее распространенные функции.

xml_parser_create: базовая функция для создания XML+анализатора, кото+ рый затем можно использовать с другими XML+функциями для чтения и записи данных, определения ошибок, а также для многих других полезных задач. По окончании работы с созданным анализатором рекомендуется использовать функцию xml_parser_free для освобождения ресурсов.

xml_parse_into_struct: разбирает XML+данные в массив. Эту функцию можно использовать для передачи содержимого правильно сформированного XML+файла в PHP+массив, и впоследствии работать с элементами этого массива.

xml_get_error_code: определяет код ошибки XML+анализатора (определяется как константа, например, XML_ERROR_NONE и XML_ERROR_SYNTAX). Чтобы с помощью данного кода получить текстовое описание ошибки, используется функция xml_error_string.

xml_set_option: существует несколько параметров, которые можно задавать для XML+анализатора: XML_OPTION_CASE_FOLDING и XML_OPTION_TARGET_ ENCODING. По умолчанию используется первый параметр. Его включение означа+ ет, что имена элементов будут записываться в верхнем регистре. Второй параметр позволяют указать используемую кодировку для целевого документа; по умолчанию действует кодировка, используемая функцией xml_parser_create ++++++ ISO+8859+1. Чтобы определить, какие параметры для XML+анализатора установлены в те+ кущий момент, можно использовать функцию xml_parser_get_option.

Существует также большое число других, связанных с XML+анализаторами функ+ ций для установки обработчиков различных типов (для распространенных XML+ком+ понентов, например инструкций, символьных данных и т.д.).

Практика Создание XML-документа

Вследующем примере для создания XML+документа используются обычные строки

истроковые функции PHP. Примечательно то, что сценарий работает вообще без XML+ функций. Он получает введенные имена и значения для нескольких элементов и атрибу+ тов, а затем использует эти данные для создания XML+документа, после чего сохраняет этот документ в файле. Недостаток такого сценария в том, что он предоставляет очень слабые возможности по созданию или обработке документов произвольной сложности; можно использовать только два элемента с двумя атрибутами каждый, кроме того, нет никакой проверки корректности документа. Но иногда все, что нужно, это вывести XML+код (как показано ниже, это можно сделать без использования XML+функций).

Для работы данного сценария необходимо создать подкаталог (в Web+каталоге, со+ держащем файл сценария) с именем xml_files. В данном каталоге будут сохраняться созданные XML+файлы (убедитесь в том, что задан правильный каталог по умолча+ нию, $default_dir, если он отличается от указанного в примере). Запустите HTML+ редактор, создайте файл php_xml.php и введите в него следующий код:

XML 355

<html>

<head>

<title>XML-функции PHP</title>

<meta http-equiv="Content-Type" content="text/html; charset=windows-1251"> </head>

<body bgcolor="#FFFFFF">

<form method="POST" action="php_xml.php"> <input type="hidden" name="posted" value="true">

<table width="100%" border="1" cellpadding="10"> <tr><td><h2>Использование XML-средств PHP</h2>

<?php

if (isset($_POST['posted'])) { $cmdButton = $_POST['cmdButton'];

$root_element_name = $_POST['root_element_name']; $element01_name = $_POST['element01_name']; $att0101_name = $_POST['att0101_name']; $att0101_value = $_POST['att0101_value']; $att0102_name = $_POST['att0102_name']; $att0102_value = $_POST['att0102_value']; $element0101_name = $_POST['element0101_name']; $att010101_name = $_POST['att010101_name']; $att010101_value = $_POST['att010101_value']; $att010102_name = $_POST['att010102_name']; $att010102_value = $_POST['att010102_value'];

switch ($cmdButton) {

case "Создать XML-документ"; //формирование XML-документа

$xml_dec = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; $doc_type_dec = "";

$root_element_start = "<" . $root_element_name . ">"; $root_element_end = "</" . $root_element_name . ">"; $xml_doc = $xml_dec;

$xml_doc .= $doc_type_dec; $xml_doc .= $root_element_start;

$xml_doc .= "<" . $element01_name . " "

. $att0101_name . "=" . "'" . $att0101_value . "'" . " "

. $att0102_name . "=" . "'" . $att0102_value . "'" . ">"; $xml_doc .= "<" . $element0101_name . " "

. $att010101_name . "=" . "'" . $att010101_value . "'" . " "

. $att010102_name . "=" . "'". $att010102_value . "'" . ">"; $xml_doc .= "</" . $element0101_name . ">";

$xml_doc .= "</" . $element01_name . ">";

$xml_doc .= $root_element_end;

//открыть файл, скопировать в него XML-текст, а затем закрыть его $default_dir = "./xml_files";

$fp = fopen($default_dir . "\\" . $_POST['xml_file_name'] . ".xml", 'w');

$write = fwrite($fp, $xml_doc); $response_message = "XML-документ создан";

break;

default;

break;

}

}

?>

<table width="100%" border="1"><tr>

<td><font face="Arial, Helvetica, sans-serif" size="-1"><b>

Создание правильно сформированного XML-документа

</b></font></td>

</tr><tr><td><table width="100%" border="1"><tr>

<td colspan="3"><font size="-1"><b><font face="Arial, Helvetica, sans-serif">Ответ:

<?php echo $response_message; ?></font></b></font></td> </tr><tr>

<td><font size="-1"><b><font face="Arial, Helvetica, sans-serif">

356 Глава 8

Элемент или атрибут</font></b></font></td> <td><font size="-1"><b><font face="Arial, Helvetica,

sans-serif">Имя</font></b></font></td>

<td><font size="-1"><b><font face="Arial, Helvetica, sans-serif">Значение</font></b></font></td>

</tr><tr>

<td><font size="-1"><b><font face="Arial, Helvetica, sans-serif">Корневой элемент:</font></b></font></td>

<td><input type="text" name="root_element_name"> </td><td> </td></tr><tr>

<td><font size="-1"><b><font face="Arial, Helvetica, sans-serif">Элемент01:</font></b></font></td>

<td><input type="text" name="element01_name"> </td><td> </td></tr><tr>

<td><font size="-1"><b><font face="Arial, Helvetica, sans-serif">Атрибут0101:</font></b></font></td>

<td><input type="text" name="att0101_name"> </td><td><input type="text" name="att0101_value"> </td></tr><tr>

<td><font size="-1"><b><font face="Arial, Helvetica, sans-serif">Атрибут0102:</font></b></font></td>

<td><input type="text" name="att0102_name"> </td><td><input type="text" name="att0102_value">

</td></tr><tr><td>

<font size="-1"><b><font face="Arial, Helvetica, sans-serif">Элемент0101: </font></b></font></td>

<td><input type="text" name="element0101_name"> </td><td> </td></tr><tr>

<td><font size="-1"><b><font face="Arial, Helvetica, sans-serif">Атрибут010101:</font></b></font></td>

<td><input type="text" name="att010101_name"> </td><td><input type="text" name="att010101_value"> </td></tr><tr>

<td><font size="-1"><b><font face="Arial, Helvetica, sans-serif">Атрибут010102:</font></b></font></td>

<td><input type="text" name="att010102_name"> </td><td><input type="text" name="att010102_value"> </td></tr><tr>

<td><b><font face="Arial, Helvetica, sans-serif">Текущие XML-файлы</font></b><hr>

<?php

$default_dir = "./xml_files";

if (!($dp = opendir($default_dir))) { die("Невозможно открыть каталог $default_dir.");

}

while ($file = readdir($dp)) {

if ($file != '.' && $file != '..') { echo "$file<hr>";

}

}

closedir($dp); ?>

<font size="-1"><b><font face="Arial, Helvetica, sans-serif">Имя файла нового XML-документа:</font></b></font>

</td><td colspan="2" valign="bottom">

<input type="text" name="xml_file_name" size="30"> </td></tr><tr><td> </td>

<td colspan="2">

<input type="submit" name="cmdButton" value="Создать XML-документ"> </td></tr></table></td></tr> </table>

</td></tr></table>

</form>

</body>

</html>

XML 357

Сохранив данный файл как php_xml.php, запустите его в браузере и с помощью формы (рис. 8.1) создайте правильно сформированный XML+документ.

Рис. 8.1.

Имя первого XML+документа, созданного с помощью данной формы ++++++ first_xml.xml. Если в сценарии использовались те же имена элементов и значения, что и в книге, то файл first_xml.xml будет выглядеть так:

<?xml version="1.0" encoding="UTF-8" ?><rootelement><element01 attr0101="attr0101 val" attr0102="attr0102 val"><element0101 attr010101="attr010101 val" attr010102="attr010102 val" /></element01></rootelement>

Откройте данный .xml+файл в браузере. Результат должен выглядеть аналогично рис. 8.2 при условии, что используемый браузер способен анализировать XML.

358 Глава 8

Рис. 8.2.

Как это работает

Сценарий генерирует стандартную Web+страницу, состоящую из HTML+кода. На стра+ нице отображается таблица с формой, в которую пользователь может вводить имена и значения для фиксированного набора XML+элементов и атрибутов. Функция isset() позволяет определить факт отправки формы, и если форма отправлена, то запускается код. После извлечения значений из $_POST+переменной используется блок switch case, определяющий следующий выполняемый блок сценария. Хотя в данном случае существует только один case+блок, при необходимости такие блоки можно добавить:

<?php

if (isset($_POST['posted'])) { $cmdButton = $_POST['cmdButton'];

$root_element_name = $_POST['root_element_name']; $element01_name = $_POST['element01_name'];

XML 359

$att0101_name = $_POST['att0101_name']; $att0101_value = $_POST['att0101_value']; $att0102_name = $_POST['att0102_name']; $att0102_value = $_POST['att0102_value']; $element0101_name = $_POST['element0101_name']; $att010101_name = $_POST['att010101_name']; $att010101_value = $_POST['att010101_value']; $att010102_name = $_POST['att010102_name']; $att010102_value = $_POST['att010102_value'];

switch ($cmdButton) {

case "Создать XML-документ";

В данном примере в case+блоке выполняется форматирование введенных пользо+ вателем данных в строку, содержащую все необходимые компоненты правильно сформированного XML+документа:

//формирование XML-документа

$xml_dec = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; $doc_type_dec = "";

$root_element_start = "<" . $root_element_name . ">"; $root_element_end = "</" . $root_element_name . ">"; $xml_doc = $xml_dec;

$xml_doc .= $doc_type_dec; $xml_doc .= $root_element_start;

$xml_doc .= "<" . $element01_name . " "

. $att0101_name . "=" . "'" . $att0101_value . "'" . " "

. $att0102_name . "=" . "'" . $att0102_value . "'" . ">"; $xml_doc .= "<" . $element0101_name . " "

. $att010101_name . "=" . "'" . $att010101_value . "'" . " "

. $att010102_name . "=" . "'". $att010102_value . "'" . ">"; $xml_doc .= "</" . $element0101_name . ">";

$xml_doc .= "</" . $element01_name . ">"; $xml_doc .= $root_element_end;

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

//открыть файл, скопировать в него XML-текст, а затем закрыть его $default_dir = "./xml_files";

$fp = fopen($default_dir . "\\" . $_POST['xml_file_name'] . ".xml", 'w'); $write = fwrite($fp, $xml_doc);

Наконец, создается сообщение и данный блок кода заканчивается оператором break:

$response_message = "XML-документ создан"; break;

XML-анализаторы

Итак, очевидно, что XML+документы можно создавать с помощью обычных, стро+ ковых PHP+функций. Однако ясно также и то, что эти функции не представляют простого способа работы с XML+документом. Можно было бы написать какие+либо регулярные выражения и специальные функции, упрощающие работу с XML, но разработчики PHP уже создали множество полезных функций.

В следующем примере демонстрируется использование функций xml_parser_ create() и xml_parse_into_struct(). Кроме того, в приведенном ниже сцена+ рии используется функция file_get_contents(), которая позволяет получить содержимое файла и передать его в строку.

360 Глава 8

Практика Чтение XML-документа

Для изучения данного примера можно скопировать файл php_xml.php под име+ нем php_xml02.php. Затем в него необходимо будет вставить новый case+блок и но+ вую таблицу для отображения результатов.

1.Создайте копию файла php_xml.php, сохраните ее с именем php_xml02.php

иоткройте в HTML+редакторе.

2.Вставьте следующий код вместо прежнего блока, который начинается с if (isset

изаканчивается switch ($cmdButton):

if (isset($_POST[posted])) {

$xml_file_chosen = $_POST[xml_file_chosen]; $cmdButton = $_POST[cmdButton];

switch ($cmdButton) {

3. Теперь вместо прежнего case+блока вставьте следующий код:

case "Проанализировать XML-документ";

//найти заданный файл $default_dir = "./xml_files";

$xml_string = file_get_contents ($default_dir . "/" . $xml_file_chosen,"rb");

//Прочитать имеющиеся данные и превратить их в массивы $xp = xml_parser_create();

xml_parse_into_struct($xp, $xml_string, $values, $keys); xml_parser_free($xp);

break;

4. Вместо прежней HTML+таблицы вставьте новую, код которой показан ниже:

<table width="100%" border="1">

<tr><td><font face="Arial, Helvetica, sans-serif" size="-1"> <b>Проанализировать XML-документ</b></font></td></tr><tr><td>

<table width="100%" border="1"><tr><td>

<font face="Arial, Helvetica, sans-serif" size="-1"> <b>Выберите XML-файл</b></font></td></td>

<td><select name="xml_file_chosen">

<?php

$default_dir ="./xml_files";

if (!($dp = opendir($default_dir))) { die("Невозможно открыть каталог $default_dir.");

}

while ($file = readdir($dp)) {

if ($file != '.' && $file != '..') {

echo "<option value='$file'>$file</option>\n";

}

}

closedir($dp); ?>

</select></td></tr><tr>

<td><font face="Arial, Helvetica, sans-serif" size="-1"> <b>Содержимое XML-файла</b></font><hr>

<?php

if ($cmdButton == "Проанализировать XML-документ") {

XML 361

echo "Массив ключей<BR><BR><PRE>";

print_r($keys);

echo "</PRE><BR><BR>Массив значений<BR><BR><PRE>"; print_r($values);

echo "</PRE>";

}

?>

</td><td>

<input type="submit" name="cmdButton" value="Проанализировать XML-документ"> </td></tr></table>

</td></tr></table>

5.Сохраните данный файл и вызовите его в браузере. Значение атрибута action необходимо изменить на новое имя файла, php_xml02.php. На странице в выпа+ дающем списке должен отобразиться XML+файл, созданный с помощью исходно+ го сценария php_xml.php (а также остальные файлы, если было создано не+ сколько XML+файлов). Выберите файл и нажмите кнопку Проанализировать

XML-документ. На рис. 8.3 показаны выводимые на экран массивы ключей и значений.

Рис. 8.3.

362 Глава 8

Как это работает

Case+блок начинается с поиска выбранного пользователем файла и считывания из него данных в переменную $xml_string. После этого для создания нового объекта+ анализатора (с именем $xp) используется функция xml_parser_create, а функция xml_parse_into_struct() превращает XML+документ в два массива: массив ключей и массив значений.

Функция xml_parse_into_struct() принимает в качестве аргументов XML+ана+ лизатор (объектная переменная $xp), строковую переменную (содержимое XML+докумен+ та), а также имена двух массивов, которые необходимо создать:

//найти заданный файл $default_dir = "./xml_files"; $xml_string = file_get_contents

$xml_file_chosen,"rb");

($default_dir . "/" .

//Прочитать имеющиеся данные и превратить их в массивы $xp = xml_parser_create();

xml_parse_into_struct($xp, $xml_string, $values, $keys); xml_parser_free($xp);

break;

HTML+таблица предоставляет средство для выбора необходимого .xml+файла. За+ тем, если была нажата кнопка Проанализировать XML-документ, сценарий посред+ ством функции print_r() распечатывает на экране два массива. Для того чтобы дан+ ные отображались в удобочитаемом виде, используется HTML+тег <PRE>:

<table width="100%" border="1">

<tr><td><font face="Arial, Helvetica, sans-serif" size="-1"> <b>Проанализировать XML-документ</b></font></td></tr><tr><td>

<table width="100%" border="1"><tr><td>

<font face="Arial, Helvetica, sans-serif" size="-1"> <b>Выберите XML-файл</b></font></td></td>

<td><select name="xml_file_chosen">

<?php

$default_dir = "./xml_files";

if (!($dp = opendir($default_dir))) { die("Невозможно открыть каталог $default_dir.");

}

while ($file = readdir($dp)) {

if ($file != '.' && $file != '..') {

echo "<option value='$file'>$file</option>\n";

}

}

closedir($dp); ?>

</select></td></tr><tr>

<td><font face="Arial, Helvetica, sans-serif" size="-1"> <b>Содержимое XML-файла</b></font><hr>

<?php

if ($cmdButton == "Проанализировать XML-документ") { echo "Массив ключей<BR><BR><PRE>";

print_r($keys);

echo "</PRE><BR><BR>Массив значений<BR><BR><PRE>"; print_r($values);

echo "</PRE>";

XML 363

}

?>

</td><td>

<input type="submit" name="cmdButton" value="Проанализировать XML-документ"> </td></tr></table>

</td></tr></table>

Объектная модель документа

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

XML+документы можно моделировать с помощью DOM, так как между частями лю+ бого XML+документа существуют специфические отношения. Как уже было показано, может существовать только один корневой элемент, и он является родительским для всех остальных элементов в XML+документе. Это означает, что корневой документ находится внизу (отсюда и название) иерархии или дерева, из которого ‘‘произрас+ тают’’ остальные элементы. Следовательно, отношения между компонентами XML+ документа могут быть выведены программно (именно это и делают функции DOM+ расширения PHP; это расширение подробнее рассматривается далее).

Элементы, расположенные внутри другого элемента, являются дочерними для этого элемента, тогда как элемент, внутри которого он расположен, является для него роди+ тельским. Поэтому элементы можно представлять как родителей и детей или как де+ рево с корнем, ветвями и листьями. Внутри модели DOM допустимы обе абстракции. Элементы и другие компоненты XML+документа внутри модели DOM считаются узлами.

DOM-расширение

DOM+расширение в PHP строго придерживается рекомендации Консорциума W3C, касающейся второго уровня DOM, которая гласит: ‘‘Модель DOM представляет собой API (application programming interface ++++++ программный интерфейс приложений) для корректных HTML+ и правильно сформированных XML+документов’’. DOM позво+ ляет программно создавать и осуществлять навигацию в любом правильно сформиро+ ванном XML+документе, а также добавлять, редактировать и удалять из него узлы.

Чтобы данное расширение было доступно в сценариях, необходимо скомпилиро+ вать PHP с параметром --with-dom=dom_dir. Для инсталляции PHP в Windows не+ обходимо скопировать файл libxml2.dll или iconv.dll в каталог System32. Даль+ нейшие инструкции приведены в документации.

Поддержка функций DOM+расширения на момент написания книги остается экс+ периментальной (поэтому в данной книге нет примеров его использования), в книге

Профессиональное программирование на PHP (ИД ‘‘Вильямс’’, 2006 г) DOM+расширение PHP освещается более подробно.

Использование функций DOM-расширения PHP

В PHP имеются следующие DOM+функции: domxml_new_doc() для создания новых XML+документов, domxml_open_file() для открытия файла XML+документа в виде DOM+объекта, а также domxml_open_mem() для создания DOM+объекта из уже имеюще+ гося в памяти XML+документа. Функции возвращают DOM+объект, а не строку или дан+ ные другого типа. Чтобы использовать PHP DOM+функции, обычно сначала необходимо создать объект DOMDocument, а затем манипулировать им, используя методы, которые

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]