web - tec / PHP 5 для начинающи
.pdfXML 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, а затем манипулировать им, используя методы, которые
364 Глава 8
являются частью класса созданного объекта. Существует множество доступных классов объектов. Для начала можно использовать DOMDocument объект и получить новые объек ты, отражающие такие компоненты XML документа, как элементы, атрибуты и т.д.
Например, чтобы открыть созданный ранее XML файл, можно использовать сле дующий код, создающий DOM объект с именем $my_dom_obj:
$my_dom_obj = domxml_open_file("first_xml.xml");
Затем, чтобы создать переменную, представляющую найденный в документе кор невой элемент, можно использовать такой код:
$the_root_element = $my_dom_obj->document_element();
Манипулировать созданными DOM объектами можно также с помощью несколь ких других PHP DOM функций, включая create_element(), которая создает новый элемент, и append_child(), которая добавляет какой либо элемент в качестве до чернего для существующего элемента.
Например, если в XML документе, скомпонованном согласно DOM, требуется найти определенный элемент, то можно воспользоваться функцией get_element_by_tagname DOMElement объекта, позволяющей находить элемент как узел в DOM, и он будет най ден как дочерний узел в DOM иерархии корень ветвь лист.
В DOM расширении доступно множество других классов объектов, а также боль шое количество функций для создания и манипулирования XML документами. Объект но ориентированная природа данных функций широко раскрывается в книге Профес сиональное программирование на PHP (ИД ‘‘Вильямс’’, 2006 г), в которой можно найти более подробную информацию о DOM и PHP.
XML-функции PHP5
PHP4 включает в себя некоторые базовые функции для синтаксического анализа XML, а в PHP5 имеется множество новых функций, основанных на библиотеке libxml2. Под держка расширения simpleXML в PHP5 включена автоматически, поэтому нет необхо димости подключать какие либо дополнительные расширения. PHP5 также поддержи вает проверку корректности XML документов при обращении к DTD или XML схеме.
Расширение SimpleXML
Расширение SimpleXML также является экспериментальным, но в PHP5 оно пол ностью переработано. Данное расширение устанавливается по умолчанию (параметр --enable-simplexml). Оно включает в себя функции для работы с XML докумен тами, которые значительно упрощают распространенные операции. Например, рас ширение позволяет сценарию принимать строку, преобразовывать ее в XML до кумент и отображать этот документ. Главное преимущество заключается в том, что XML документ становится объектом, который можно обрабатывать, как любые другие объекты в PHP, причем доступ к элементам и атрибутам документа, а также к их дан ным осуществляется с помощью обычных объектных операций (объекты более под робно рассматриваются в последующих главах).
В состав SimpleXML расширения входят следующие функции:
simplexml_load_file: принимает в качестве аргумента путь к файлу и, если содержимое файла является правильно сформированным XML документом, то выгружает данные файла в виде объекта;
XML 365
simplexml_load_string: принимает в качестве аргумента строку, которая должна быть правильно сформированным XML+документом, и преобразовыва+ ет эту строку в объект;
simplexml_import_dom: принимает узел из DOM+документа и превращает его в simplexml+узел;
simplexml_element->asXML: возвращает правильно сформированную XML+ строку из simpleXML+объекта;
simplexml_element->attributes: предоставляет определения атрибутов и значений внутри правильно сформированной XML+строки;
simplexml_element->children: данный метод предоставляет дочерние эле+ менты заданного элемента;
simplexml_element->xpath: метод выполняет XPath+запрос по simpleXML+узлу.
Использование функции simplexml_load_string()
В PHP+программе можно написать (или получить как результат какого+либо выра+ жения или функции) строку, представляющую собой правильно сформированный XML+документ. Эту строку с помощью функции simplexml_load_string() можно превратить в simpleXML+объект. Чтобы преобразовать значение строковой перемен+ ной $string в simpleXML+объект на основании XML+кода внутри PHP+программы, необходимо использовать код, аналогичный следующему:
<?php
$string = <<<XML
<?xml version='1.0'?> <root_element> <child01>First element</child01> <child02>Second element</child02>
</root_element> XML;
$xml_string = simplexml_load_string($string); ?>
Сначала рассмотрим чтение XML+строки с помощью функции simplexml_load_ string. Все что требуется сделать, это передать в данную функцию строку. Как толь+ ко simpleXML+объект создан, можно использовать его метод asXML() для отображе+ ния правильно сформированной XML+строки.
Ниже приведен пример использования функции simplexml_load_string и ме+ тода asXML объекта simplexml_element. Откройте текстовый редактор и создайте
.php+документ, содержащий следующий код:
<?php
//Метод asXML форматирует данные родительского объекта в //строку XML версии 1.0. Создаем XML-строку
$my_xml_string = <<<XML
<a>
<b>
<c>text content</c> <c>more text content</c> </b>
<d>
<c>even more text content</c> </d>
</a>
XML;
366 Глава 8
//загрузка строки в объект
$xml_object = simplexml_load_string($my_xml_string); //отображение содержимого XML-объекта
echo $xml_object->asXML(); ?>
Сохраните сценарий как create_xml_doc.php и откройте его в браузере. При+ мерный результат показан на рис. 8.4.
Рис. 8.4.
Использование функции simplxml_load_file()
Если данные уже записаны в XML+файл, то с помощью функции simplexml_ load_file() содержимое этого файла можно преобразовать в simpleXML+объект. Как бы ни был создан simpleXML+объект, им можно манипулировать с помощью дру+ гих simpleXML+функций.
XML 367
В последующем примере для простоты используется внешний файл, содержащий XML+ строки. Данные строки считываются с помощью функции simplexml_load_file(). На+ пример, чтобы прочитать XML+файл, такой как был создан в начале данной главы, можно использовать функцию simplexml_load_file().
Ниже приводится тот же XML+файл (его следует сохранить как php_programs.xml):
<?xml version="1.0" ?> <php_programs>
<program name="cart"> <price>100</price>
</program>
<program name="survey"> <price>500</price>
</program> </php_programs>
Чтобы прочитать имена и значения элементов и атрибутов в данном XML+документе, используется simpleXML+функция для загрузки файла ++++++ simplexml_load_file(). Те+ перь следует создать PHP+документ (и назвать его, например, simplexml_01.php), а за+ тем присвоить переменной результат выполнения функции simplexml_load_file().
<?php
$php_programs = simplexml_load_file('php_programs.xml');
Данная переменная содержит объект, который можно использовать почти так же, как обычный массив. Чтобы из этой переменной извлечь имена и значения, использу+ ется цикл foreach, который возвращает ключи и значения точно так же, как и в случае обычного массива:
foreach ($php_programs->program as $program_key => $program_val) { echo "Корневой элемент <B>php_programs</B> содержит элемент с именем
<B>$program_key</B><BR>";
Однако вывести содержимое переменной $program_val непосредственно на экран не удастся; в переменной содержится подобный массиву объект, и поэтому снова при+ дется использовать цикл foreach как для дочерних элементов, так и для их атрибутов:
foreach($program_val->children() as $child_of_program_key => $child_of_program_val)
{
if ($child_of_program_key == "price") { foreach($program_val->attributes() as $att => $val) {
if ($att == "name") {
foreach($program_val->price as $the_price) {
echo "Элемент <B>$program_key</B> имеет атрибут с именем <B>$att</B> и значением <B>$val</B>.<BR>";
echo "Элемент <B>$program_key</B> имеет дочерний элемент с именем
<B>$child_of_program_key</B> и значением <B>$the_price</B>.<BR>"; echo "Следовательно, можно сказать, что ключ <B>$child_of_program_key</B> <B>$val</B> <B>$program_key</B> равен
<B>\$$the_price</B>.<BR><BR>";
}
}
}
}
}
}
?>
Результат работы данного сценария представлен на рис. 8.5.
368 Глава 8
Рис. 8.5.
Изменение значений с помощью simpleXML
Можно не только считывать части XML+документа в simpleXML+объект. Кроме этого, можно изменять данные в документе, загруженном в память. Все что требуется сделать, это правильно обратиться к данным, которые нужно изменить, а затем запи+ сать вместо них необходимые значения.
Практика Изменение значения узла
Создайте новый файл, сохраните его как simplexml_change_value.php и вве+ дите в него следующий код:
<?php
$xmlstr = <<<XML
XML 369
<php_programs>
<program name="cart"> <price>100</price>
</program>
<program name="survey"> <price>500</price>
</program> </php_programs> XML;
$first_xml_string = simplexml_load_string($xmlstr); $first_xml_string->program[0]->price = '250';
echo "<pre>"; var_dump($first_xml_string); echo "</pre>";
?>
Сохраните файл, а затем вызовите его в браузере. Результат работы сценария по+ казан на рис. 8.6.
Рис. 8.6.
370 Глава 8
Как это работает
После того как XML+строка считана в переменную $xmlstr, обращаться к частям документа можно почти так же, как если бы документ был массивом, т.е. можно исполь+ зовать имена и индексы для каждого уровня. Очевидно, что program и price ++++++ это элементы и что первая цена должна быть равна 100. Однако во второй строке приве+ денного здесь кода значение изменено на 250, а содержимое элементов распечатывает+ ся на экране с помощью функции var_dump (var_dump ++++++ PHP+функция, которая ото+ бражает структуру и данные PHP+переменных независимо от их типа). Для сохранения форматирования распечатываемых на экране данных используется HTML+тег <PRE>.
$first_xml_string = simplexml_load_string($xmlstr); $first_xml_string->program[0]->price = '250';
echo "<PRE>"; var_dump($first_xml_string); echo "</PRE>";
Практика Импорт DOM с помощью simpleXML
Используя расширение simpleXML, можно получать и создавать DOM+объекты. Создайте файл simplexml_dom.php со следующим кодом:
<?php
$xmlstr = <<<XML
<php_programs>
<program name="cart"> <price>100</price>
</program>
<program name="survey"> <price>500</price>
</program> </php_programs> XML;
$dom = new domDocument; $dom->loadXML($xmlstr);
$s_dom = simplexml_import_dom($dom);
echo "Цена первой программы: <B>$" . $s_dom->program[0]->price . "</B>"; ?>
Сохраните созданный файл и откройте его в браузере. Результат работы сценария показан на рис. 8.7.
Как это работает
Сначала с помощью ключевого слова new из класса domDocument создается новый XML+документ (более подробно создание объекта с помощью ключевого слова new рассматривается в главе 12, ‘‘Введение в объектно+ориентированное программирова+ ние’’). Затем с помощью функции loadXML этого объекта XML+строка передается в DOMDocument+объект. Наконец, на экран выводится содержимое элемента price.
$dom = new domDocument; $dom->loadXML($xmlstr);
$s_dom = simplexml_import_dom($dom);
echo "Цена первой программы: <B>$" . $s_dom->program[0]->price . "</B>";
XML 371
Рис. 8.7.
Резюме
Вданной главе рассматривались основы технологии XML, включая правила фор+ мирования XML+документа, а также определение типа документа (DTD), написанное
вформате EBNF, и обращение к DTD для проверки корректности XML+документа. В главе обсуждалась поддержка пространств имен в XML и ссылки на несколько XML+ схем из одного XML+документа.
Вглаве также рассматривалась документная объектная модель (DOM) ++++++ иерархи+ ческая модель структуры XML+документов, и некоторые PHP+функции, связанные с DOM. Также здесь были описаны некоторые функции PHP4 для использования XML+ анализаторов, а также с новое расширение simpleXML, которое появилось в PHP5.
Примеры сценариев помогают понять процесс создания и чтения XML+ документов, работы с их содержимым с помощью simpleXML+ и DOM+функций. Не+ смотря на то, что в книге пока не рассматривались все объектно+ориентированные функции расширений simpleXML и DOM, читатель уже, несомненно, уяснил способы эффективного создания и обработки XML+документов и их компонентов.
Упражнение
Создайте приложение, которое считывало бы XML+файл с несколькими элемента+ ми и атрибутами в simpleXML+объект, изменяло бы значения некоторых или всех элементов или атрибутов файла, а затем записывало бы модифицированный документ обратно в файл.
9
Введение в базы данных
иSQL
Вдвух последних главах было показано, как PHP+сценарии могут использовать внеш+ ние файлы для хранения и получения данных. Хотя непосредственный доступ к файлам во многих обстоятельствах позволяет решать серьезные задачи, по мере увеличения реше+ ний для хранения данных такой доступ становится все более ограниченным ++++++ что видим, то и получаем, ни больше ни меньше. В конце концов, на плечи разработчика и его сцена+ рия ложится реализация выборки и сортировки данных, а также других операций с дан+ ными, и чем больше данных приходится обрабатывать, тем дольше выполняется сцена+ рий. Это не такая уж большая проблема, если иметь дело с несколькими килобайтами данных, но что произойдет, если эти килобайты превратятся в мегабайты (или даже гигабайты)? Разработчик, намеревающийся создать успешный, популярный, управ+ ляемый данными Web+сайт, действительно должен учитывать такую возможность.
Подумать только: если бы в крупном коммерческом сайте, таком как Amazon, все данные извлекались непосредственно из простых текстовых файлов, то поиск какой+ либо одной книги, не говоря уже о размещении заказа, занял бы несколько месяцев.
Базы данных специально предназначены для решения описанной проблемы. Учи+ тывая их собственные специальные возможности по организации и безупречному хранению данных, базы данных можно представить себе как огромные библиотеки мира IT. Нет необходимости часами просматривать полки пыльных томов, одно только слово, неясное описание ++++++ и на столе немедленно появляется нужная книга.
Эта глава ++++++ первая из трех глав, в которых рассматриваются базы данных и возмож+ ности их применения для создания мощных, эффективных (и потенциально очень больших) PHP+приложений. Эти главы познакомят читателя с преимуществами хране+ ния информации с помощью баз данных вместо файлов, а также с популярными базами данных (и их отличиями), с которыми сталкиваются разработчики PHP+приложений.
Вглаве рассматриваются реляционные базы данных, а также связанные с ними понятия, такие как нормализация и индексирование. Читатель узнает, как устанавли+