Статьи

Создание системы управления контентом на основе XML с PHP

Как и большинство разработчиков, вы, наверное, много слышали о XML и системах управления контентом. Вполне вероятно, однако, что вы подвергались только теоретическим дискуссиям, не основанным на практических знаниях.

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

Несколько заметок, прежде чем мы начнем. Я использую функции и сеансы DOMXML, чтобы заставить это приложение работать, поэтому вам нужно будет использовать PHP 4.2.1 или выше и включить поддержку DOM.

Кроме того, не забудьте скачать весь код для этого урока. Это пригодится!

Краткое введение в XML и CMS

Позвольте мне сначала рассказать вам немного о CMS и XML. Я предполагаю, что вы читали или слышали об обеих этих технологиях в других местах, поэтому я буду кратко обсуждать это.

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

Например, для любой статьи, которую вы публикуете в онлайн-журнале, вы можете создать теги для имени автора, подписи автора (если она отличается от имени автора), длины слова, даты публикации, заголовка или заголовка, текста статьи, ключевых слов и скоро. Как вы увидите далее в этой статье, разбиение вашей статьи на эти XML-теги или узлы позволяет CMS делать полезные вещи со всеми статьями, которые он содержит.

По сути, XML позволяет вам создавать мини-базы данных из каждого документа без лишних затрат и затрат, которые многие базы данных приносят в веб-проект.

CMS используется для создания, публикации и поддержки контента на веб-сайте. Обычно он состоит из следующих частей:

  • Бэкэнд данных (XML или таблицы базы данных), который содержит все ваши статьи, новости, изображения и другой контент.
  • Компонент отображения данных, обычно шаблоны или другие страницы, на которые CMS «рисует» ваши статьи, изображения для посетителей сайта.
  • Компонент администрирования данных, обычно простые в использовании HTML-формы, которые позволяют администраторам сайтов создавать, редактировать, публиковать и удалять статьи в некотором безопасном рабочем процессе. Часть администрирования данных в CMS, как правило, самая сложная, и в которой вы, скорее всего, будете тратить большую часть времени на разработку.

За последнее десятилетие для создания CMS использовались разные языки сценариев, включая Perl / CGI, ASP, TCL, JSP, Python и PHP. У каждого из этих языков есть свои плюсы и минусы, но я собираюсь сосредоточиться на использовании PHP с XML для построения простой системы управления контентом.

Требования

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

Поскольку это довольно простой проект, и поскольку вы собираетесь сделать это для себя, подойдет простой список требований.

Какие требования нам нужно собрать? По сути, требования делятся на три основные категории:

  1. Какой контент будет обрабатывать CMS? Кроме того, как разбивается каждый тип контента? (Чем лучше вы поймете эту проблему, тем проще будет создать XML-файлы.)
  2. Кто будет посещать сайт, и какое поведение эти пользователи ожидают найти? (Например, захотят ли они просматривать иерархический список статей, искать статьи по ключевым словам и видеть ссылки на соответствующие статьи?)

  3. Что должны делать администраторы сайта? (Например, войдите в систему безопасно, создайте контент, отредактируйте контент, опубликуйте контент и удалите контент. Если ваша система управления контентом будет иметь роли для административных пользователей — таких как администратор сайта, редактор, писатель — тогда ваша система станет более сложной).

Чтобы не усложнять эту статью, я выберу самые основные требования для моей простой CMS на основе XML:

  • CMS будет управлять только статьями. Каждая статья будет иметь:
    • уникальный идентификатор
    • Заголовок
    • имя автора
    • электронная почта автора
    • абстрактный
    • тело статьи, которое может содержать абзацы и один уровень подзаголовка
    • статус (либо «в процессе», либо «в режиме реального времени»)
    • список ключевых слов
  • Посетители сайта смогут просматривать «живые» статьи, перечисленные по имени автора. Они также смогут выполнять поиск по заголовкам и ключевым словам.
  • Сам сайт будет состоять из следующих страниц:
    • Домашняя страница, на которой перечислены пять статей, опубликованных на сайте, и функция поиска.
    • Страница сведений о статье, отображающая одну статью за раз.
    • Страница результатов поиска, на которой будут перечислены все статьи по автору, ключевому слову или строке, введенной в поисковую систему.
    • Администраторы сайта получают безопасный вход в систему, способ добавления дополнительных администраторов и простые экраны, с которых можно добавлять новые файлы XML, редактировать существующие файлы, публиковать файлы и удалять файлы.

Определение файлов XML

Всякий раз, когда я создаю CMS, я сначала пытаюсь определить бэкэнд данных, потому что я нахожу, что все остальные элементы каскадно оттуда. В этом случае наш сервер данных является хранилищем файлов XML, поэтому нам нужно определить, как наши файлы должны быть структурированы.

XML-файлы состоят из вложенных начальных и конечных тегов, каждый из которых определяет некоторый фрагмент информации. XML-файлы также должны содержать «корневой» начальный и конечный тег, который включает в себя все остальные теги.

Поскольку в этом примере мы будем иметь дело только со статьями, наш «корневой» начальный и конечный тег должен быть:

<article>  
 
</article>

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

 <?xml version="1.0"?>  
<article id=\"xml-howto-1\">  
<headline>Writing XML Articles</headline>  
<status>in progress</status>  
<author>Joe Author</author>  
<email>[email protected]</email>  
<abstract>A short article about writing XML articles.</abstract>  
<keywords>XML,articles,how to</keywords>  
<para-intro>Intro paragraph here.</para-intro>  
<para-main>Main paragraph.</para-main>  
<para-conclusion>Conclusion paragraph.</para-conclusion>  
</article>

Несколько замечаний по поводу нашего примера статьи:

  • Обычно вы создаете DTD или схему, чтобы определить, как будет выглядеть статья. Создание эффективных DTD или схем — это само по себе учебное пособие, поэтому здесь я использовал метод ярлыков, включающий пример случая. Это быстрее, чем разработка схемы, но имейте в виду, что у вас могут возникнуть проблемы, потому что ваш пример может быть слишком простым. Кроме того, если вы хотите проверить свой XML-документ, вам нужно будет создать DTD.
  • Вы заметили часть « id= Это называется атрибутом. Позже мы поговорим о том, почему важно иметь уникальный атрибут id для каждой статьи, которую мы создаем в системе.
  • Поскольку мы хотим сохранить этот пример простым, я собираюсь предположить, что наши статьи будут состоять только из трех абзацев каждый, а формы, которые мы создадим позже, будут соответствовать этой структуре. В будущих уроках мы создадим более динамичную структуру, в которой мы вложим теги абзаца в тег <body>
Создание инструмента администратора

Инструмент администратора для нашей CMS на основе XML — это всего лишь несколько страниц PHP, которые позволят администраторам входить в систему, создавать, редактировать, публиковать и удалять статьи XML. Администраторы также смогут создавать, редактировать и удалять других администраторов.

Страница входа

Страница входа очень проста. Он включает в себя простую форму HTML, которая позволяет администраторам вводить имя пользователя и пароль. Логика PHP на этой странице должна проверять введенные значения по списку администраторов. Если бы у нас было достаточно времени, я бы провел с вами процесс создания файла admin.xml, который содержит эти значения. Но сейчас мы возьмем ярлык встраивания значений в наш PHP.

Вот код для страницы login.php:

 <?php  
session_start();  
?>  
<html>  
<title>Please Log In</title>  
<body>  
<form name="login" method="post" action="verify.php">  
<table width="290" border="0" align="center" cellpadding="4" cellspacing="1">  
   <tr>  
     <td colspan="2"><div align="center">Please log in</div>  
     </td>  
   </tr>  
   <tr>  
     <td width="99" bgcolor="#CCCCCC"> <div align="right">login</div></td>  
     <td width="181" bgcolor="#CCCCCC"> <div align="left">  
         <input name="username" type="text" id="username">  
       </div></td>  
   </tr>  
   <tr>  
     <td bgcolor="#CCCCCC"> <div align="right">password</div></td>  
     <td bgcolor="#CCCCCC"> <div align="left">  
         <input name="password" type="password" id="password">  
       </div></td>  
   </tr>  
   <tr>  
     <td colspan="2"><div align="center">  
         <input type="submit" name="Submit" value="Submit">  
         &nbsp;  
         <input name="reset" type="reset" id="reset" value="Reset">  
       </div></td>  
   </tr>  
 
 <tr>  
 <td colspan=2 align=center>  
 <?php echo $_SESSION[\"error\"]; ?>  
 </td>  
 </tr>  
 </table>  
</form>  
</body>  
</html>

Обратите внимание, что действие формы настроено на страницу с именем verify.php. Страница verify.php предельно проста. Все, что он делает, это проверяет, что переданные значения для имени пользователя и пароля соответствуют сохраненным значениям имени пользователя и пароля.

Если есть совпадение для обоих, PHP устанавливает переменную сеанса и перенаправляет пользователя на страницу администратора. Если нет, PHP отправляет пользователя обратно на страницу login.php, и отображается специальная переменная сеанса, содержащая сообщение об ошибке. Вот код для страницы verify.php:

 <?php  
session_start();  
 
$user = 'tom';  
$passw = 'test';  
 
if (($_POST["username"] == $user) and ($_POST["password"] == $passw)){  
 $_SESSION["login"] = "true";  
 header("Location:adminindex.php");  
 exit;  
} else {  
 $_SESSION["error"] = "<font color=red>Wrong username or password. Try again.</font>";  
 header("Location:login.php");  
}  
 
?>

Поскольку любой может ввести URL-адрес для страниц администратора, мы должны добавить дополнительный элемент безопасности. В верхней части каждой страницы нам нужно проверить, установлено ли значение переменной сеанса «login» равным «true». Если это не так, отправьте людей обратно на страницу login.php; если это так, покажите им страницу администратора.

Индексная страница администратора

Первая страница нашего инструмента администратора — adminindex.php. На этой странице перечислены все статьи XML, отображаемые в настоящее время на сайте, что позволяет редактировать или удалять их и изменять их статус (например, публиковать их). Это также позволяет создавать новые статьи XML.

Код для этой страницы очень прост и компактен. Мы хотим включить ссылку на страницу createArticle.php. Мы хотим открыть каталог xml / (где мы будем хранить все статьи), вытащить имена каждого файла и передать эти имена в ссылки на страницу editArticle.php. Мы сделаем то же самое для нашей страницы delArticle.php.

Вот код для adminindex.php:

 <?php   
session_start();  
if ($_SESSION["login"] != "true"){  
 header("Location:login.php");  
 $_SESSION["error"] = "<font color=red>You don't have privileges to see the admin page.</font>";  
 exit;  
}  
?>  
<h1>Welcome to the Admin Index Page</h1>  
<a href="createArticle.php">Create New XML Article</a><br><br>  
<table border=0 cellspacing=0 cellpadding=3 width="85%">  
<tr valign=top>  
<td width="75%">  
<table border=1 cellspacing=0 cellpadding=2>  
<?php  
$dh = opendir('./xml/');  
 
while ($file = readdir($dh)){  
 if (eregi("^..?$", $file)) {  
   continue;  
 }  
 echo "<tr valign=top><td width="80%">";  
 echo "<a href="editArticle.php?file=".$file . "">".$file . "</a></td>";  
 echo "<td width="20%">";  
 echo "<a href="delArticle.php?file=" .$file . "">delete</a>";  
 echo "&nbsp;</td></tr>";  
}  
?>  
</table>  
</td></tr></table>

Страница создания статьи

Страница createArticle.php очень важна — она ​​позволяет администратору сайта создавать новые XML-статьи на сайте. Это простая форма, которая позволяет администраторам сайта вводить соответствующую информацию. Каждое из полей формы соответствует структуре документа XML, которую мы выяснили ранее.

Форма также проверит, чтобы убедиться, что пользователи вводят идентификатор — без идентификатора статьи, большинство функций сайта не будет работать.

Вот код для этой страницы:

 <?php   
session_start();  
 
if ($_SESSION["login"] != "true"){  
 header("Location:login.php");  
 $_SESSION["error"] = "<font color=red>You don't have privileges to see the admin page.</font>";  
 exit;  
}  
 
?>  
<html>  
<head>  
<title>Create an XML Article</title>  
<script>  
function isReady(form){  
 if(form.id.value == "") {  
   alert("Please enter an ID!");  
   return false;  
 }  
}  
</script>  
</head>  
<body>  
<h1>Create an XML Article</h1>  
 
<a href="adminindex.php">Cancel</a><br><br>  
<form name="createArticle" action="addArticle.php" method="post" onSubmit="return isReady(this)">  
 <table border=1 cellspacing=0 cellpadding=3>  
   <tr valign=top>    
     <td width="135">Article ID</td>  
     <td width="634"> <input name="id" type="text" id="id"> <br> <font size="-1">(no    
       spaces, must be unique)</font></td>  
   </tr>  
   <tr valign=top>  
     <td>Status</td>  
     <td>In Progress <input type="hidden" name="status" value="in progress"></td>  
   </tr>  
   <tr valign=top>    
     <td>Headline</td>  
     <td> <input name="headline" type="text" id="headline" size="60"></td>  
   </tr>  
   <tr valign=top>    
     <td>Author Name</td>  
     <td> <input name="name" type="text" id="name" size="30"></td>  
   </tr>  
   <tr valign=top>    
     <td>Author Email</td>  
     <td> <input name="email" type="text" id="email" size="30"></td>  
   </tr>  
   <tr valign=top>    
     <td>Keywords</td>  
     <td> <p>    
         <input name="keywords" type="text" id="keywords">  
         <font size="-1"><br>  
         </font><font size="-1">(separate keywords with commas)</font> </p></td>  
   </tr>  
   <tr valign=top>    
     <td>Abstract</td>  
     <td><textarea name="abstract" cols="50" rows="5" id="abstract"></textarea></td>  
   </tr>  
   <tr valign=top>    
     <td> <p>Article Body<br>  
       </p></td>  
     <td> <p>Intro paragraph:</p>  
       <p>    
         <textarea name="body[intro]" cols="70" rows="10" wrap="soft" id="body[intro]"></textarea>  
       </p>  
       <p>Main paragraph:</p>  
       <p>    
         <textarea name="body[main]" cols="70" rows="10" wrap="soft" id="body[main]" ></textarea>  
       </p>  
       <p>&nbsp;</p>  
       <p>Conclusion paragraph:</p>  
       <p>    
         <textarea name="body[conclusion]" cols="70" rows="10" wrap="soft"></textarea>  
       </p></td>  
   </tr>  
   <tr valign=top>    
     <td colspan=2> <div align="center">    
         <input type="submit" name="Add Article" value="Add Article">  
         &nbsp;    
         <input name="reset" type="reset" id="reset" value="Reset">  
       </div></td>  
   </tr>  
 </table>  
</form>  
</body></html>

Действие этой формы установлено на странице addArticle.php, которая использует функции DOMXML для создания статьи XML из информации в форме. Поскольку это немного сложно, я перейду к коду раздел за разделом.

Первая часть кода инициализирует наш новый XML-файл, устанавливая версию и создавая корневой узел, которым является <article>

 <?php   
//create document root  
$doc = domxml_new_doc("1.0");  
$root = $doc->create_element("article");  
$root = $doc->append_child($root);

Затем мы добавляем атрибут id к узлу <article> Однако сначала нам нужно убедиться, что пользователи выбрали уникальное значение, так как идентификатор будет использоваться в качестве имени файла. Мы выполняем эту проверку, просматривая все статьи в каталоге xml. Если мы найдем имя файла, содержащее идентификатор из формы (сохраненный во входящей переменной $ id), то мы добавим « – Хотя не рекомендуется исправлять ввод пользователя без предупреждения, на данный момент это будет сделано. Наконец, мы добавляем атрибут id к узлу <article>

 //add ID attribute   
//FIRST, let's make sure that the id they chose isn't going to overwrite a file!  
$dh = opendir('./xml/');  
 
while ($file = readdir($dh)){  
 $string = $id . \\".xml\\";  
   
 if (eregi("^\.\.?$", $file)) {  
   continue;  
 }  
 if (eregi($string, $file)){  
   $time = date("U"); //num of seconds since unix epoch  
   $id = $id . "-" . $time;  
 }  
}  
 
$root->set_attribute('id', $id);

Теперь, когда мы создали корень, пришло время создать каждого из потомков этого узла по порядку. Первый — <headline> Обратите внимание, что узел <headline><article><headline>

 //create headline   
$head = $doc->create_element("headline");  
$head = $root->append_child($head);  
$htext = $doc->create_text_node($headline);  
$htext = $head->append_child($htext);

То же самое верно для узлов <author><email><abstract><status>

 //create author name   
$aname = $doc->create_element("author");  
$aname = $root->append_child($aname);  
$atext = $doc->create_text_node($name);  
$atext = $aname->append_child($atext);  
 
//create author email  
$mail = $doc->create_element("email");  
$mail = $root->append_child($mail);  
$mtext = $doc->create_text_node($email);  
$mtext = $mail->append_child($mtext);  
 
//create abstract  
$abs = $doc->create_element("abstract");  
$abs = $root->append_child($abs);  
$abstext = $doc->create_text_node($abstract);  
$abstext = $abs->append_child($abstext);  
 
//create status, always in progress when first created  
$stat = $doc->create_element("status");  
$stat = $root->append_child($stat);  
$stat_text = $doc->create_text_node($status);  
$stat_text = $stat->append_child($stat_text);

Далее идут ключевые слова:

 //create keyword listing   
$keylisting = $doc->create_element("keywords");  
$keylisting = $root->append_child($keylisting);  
$ktext = $doc->create_text_node($keywords);  
$ktext = $keylisting->append_child($ktext);

Абзацы могут быть обработаны как массив, так как они передаются как body[lead]body[second] Наш PHP-код настроен для создания тегов para с использованием этих переданных ключей; в итоге мы получим теги с именами <para-lead><para-second>

 //create paras   
if (is_array($body)){  
 foreach ($body as $K => $V){  
     
   if ($V != ""){  
     $para = $doc->create_element("para-$K");  
     $para = $root->append_child($para);  
     $ptext = $doc->create_text_node($V);  
     $ptext = $para->append_child($ptext);  
     //$para->set_attribute('order', $K);  
   }  
 }  
}

Наконец, мы можем записать все это дерево XML в файл, используя идентификатор в качестве имени файла, и отправить пользователя обратно в adminindex.php, где они должны увидеть только что созданный файл, добавленный в список статей XML.

 //write to the file   
$filename = "./xml/".$id . ".xml";  
$doc->dump_file($filename, false, true);  
 
//send user back to adminindex  
header("Location:adminindex.php");

Редактирование статьи XML

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

В этом примере мы не собираемся допускать каких-либо изменений в атрибуте id статьи, так как это затруднит нормальную работу остальной части приложения. Ограничение изменений атрибута id также позволяет нам легко и быстро выполнять обновление XML-файла — все, что нам нужно сделать, — это удалить старый файл и создать новый файл с нашей новой информацией. Это грубо, но быстро и эффективно.

Вот код для страницы editArticle.php. Обратите внимание, что действие формы установлено на updateArticle.php. Также обратите внимание на использование функции extractText()

 <?php    
session_start();    
   
   
   
function extractText($array){    
 if(count($array) <= 1){    
   //we only have one tag to process!    
   for ($i = 0; $i<count($array); $i++){    
     $node = $array[$i];    
     $value = $node->get_content();    
   }    
   return $value;    
 }    
     
}      
   
if ($_SESSION["login"] != "true"){    
 header("Location:login.php");    
 $_SESSION["error"] = "<font color=red>You don't have privileges to see the admin page.</font>";    
 exit;    
}    
//pull in the XML file    
   
if ($file == ""){    
   
 echo "<h2>You didn't choose a file to edit!</h2>";    
 echo "<a href="adminindex.php">Go back to index and choose a file</a>";    
 exit;    
} else {    
 $filename = "./xml/".$file;    
 $xml = domxml_open_file($filename);    
 $root = $xml->root();    
 $id = $root->get_attribute("id");    
   
 $h_array = $root->get_elements_by_tagname("headline");    
 $headline = extractText($h_array);    
   
 $stat_array = $root->get_elements_by_tagname("status");    
 $status = extractText($stat_array);    
   
       
 $a_array = $root->get_elements_by_tagname("author");    
 $author = extractText($a_array);    
     
 $e_array = $root->get_elements_by_tagname("email");    
 $email = extractText($e_array);    
     
 $ab_array = $root->get_elements_by_tagname("abstract");    
 $abstract = extractText($ab_array);    
   
 $kl_array = $root->get_elements_by_tagname("keywords");    
 $keywords = extractText($kl_array);    
     
 $lead_array = $root->get_elements_by_tagname("para-intro");    
 $plead = extractText($lead_array);    
   
 $second_array = $root->get_elements_by_tagname("para-main");    
 $pmain = extractText($second_array);    
   
 $con_array = $root->get_elements_by_tagname("para-conclusion");    
 $pcon = extractText($con_array);    
     
 $statusList = array("live","in progress");    
     
?>    
<html>    
<title>Edit an XML Article</title>    
<body>    
<h1>Edit an XML Article</h1>    
   
<a href="adminindex.php">Cancel</a><br><br>    
<form name="createArticle" action="updateArticle.php" method="post">    
 <table border=1 cellspacing=0 cellpadding=3>    
   <tr valign=top>    
     <td width="135">Article ID</td>    
     <td width="634"> <?php echo htmlspecialchars($id); ?> <input type="hidden" name="id" value="<?php echo $id; ?>">    
     </td>    
   </tr>    
   <tr valign=top>    
     <td>Status</td>    
     <td>    
   <select name="status">    
   <?php    
     foreach ($statusList as $stat){    
     if($stat == $status){    
       echo "<option value="".$stat."" selected>$stat";    
     } else {    
       echo "<option value="".$stat."">$stat";    
   
     }    
   }    
   ?>    
   </select>    
   </td>    
   </tr>    
   <tr valign=top>    
     <td>Headline</td>    
     <td> <input name="headline" type="text" id="headline" value="<?php echo htmlspecialchars($headline); ?>" size="60"></td>    
   </tr>    
   <tr valign=top>    
     <td>Author Name</td>    
     <td> <input name="name" type="text" id="name" value="<?php echo htmlspecialchars($author); ?>"size="30"></td>    
   </tr>    
   <tr valign=top>    
     <td>Author Email</td>    
     <td> <input name="email" type="text" id="email" value="<?php echo htmlspecialchars($email); ?>"size="30"></td>    
   </tr>    
   <tr valign=top>    
     <td>Keywords</td>    
     <td> <input name="keywords" type="text" value="<?php echo htmlspecialchars($keywords); ?>">    
       <br> <font size="-1">(separate keywords with commas)</font> </td>    
   </tr>    
   <tr valign=top>    
     <td>Abstract</td>    
     <td><textarea name="abstract" cols="50" rows="5" id="abstract"><?php echo htmlspecialchars($abstract); ?></textarea></td>    
   </tr>    
   <tr valign=top>    
     <td> <p>Article Body<br>    
       </p></td>    
     <td> <p>Intro paragraph:</p>    
       <p>    
         <textarea name="body[intro]" cols="70" rows="10" wrap="soft" id="body[intro]"><?php echo htmlspecialchars($plead); ?></textarea>    
       </p>    
       <p>Main paragraph:</p>    
       <p>    
         <textarea name="body[main]" cols="70" rows="10" wrap="soft" id="body[main]" ><?php echo htmlspecialchars($pmain); ?></textarea>    
       </p>    
       <p>Conclusion paragraph:</p>    
       <p>    
         <textarea name="body[conclusion]" cols="70" rows="10" wrap="soft"><?php echo htmlspecialchars($pcon); ?></textarea>    
       </p></td>    
   </tr>    
   <tr valign=top>    
     <td colspan=2> <div align="center">    
         <input type="submit" name="Add Article" value="Add Article">    
         &nbsp;    
         <input name="reset" type="reset" id="reset" value="Reset">    
       </div></td>    
   </tr>    
 </table>    
</form>    
</body>    
</html>    
<?php    
}//end if-else    
?>

Страница updateArticle.php очень похожа на страницу addArticle.php, но нет необходимости проверять уникальный атрибут id спереди. Кроме того, в конце код PHP удалит существующий файл, а затем сбросит новую информационную структуру XML во вновь созданное имя файла с тем же именем. Это экономит нам много времени, пытаясь вставить правки в соответствующие узлы.

 <?php    
   
//create document root    
$doc = domxml_new_doc("1.0");    
$root = $doc->create_element("article");    
$root = $doc->append_child($root);    
   
//add ID attribute    
$root->set_attribute('id', $id);    
   
//create headline    
$head = $doc->create_element("headline");    
$head = $root->append_child($head);    
$htext = $doc->create_text_node($headline);    
$htext = $head->append_child($htext);    
   
//create author name    
$aname = $doc->create_element("author");    
$aname = $root->append_child($aname);    
$atext = $doc->create_text_node($name);    
$atext = $aname->append_child($atext);    
   
//create author email    
$mail = $doc->create_element("email");    
$mail = $root->append_child($mail);    
$mtext = $doc->create_text_node($email);    
$mtext = $mail->append_child($mtext);    
   
//create abstract    
$abs = $doc->create_element("abstract");    
$abs = $root->append_child($abs);    
$abstext = $doc->create_text_node($abstract);    
$abstext = $abs->append_child($abstext);    
   
//create keyword listing    
$keylisting = $doc->create_element("keywords");    
$keylisting = $root->append_child($keylisting);    
$ktext = $doc->create_text_node($keywords);    
$ktext = $keylisting->append_child($ktext);    
   
//create status, always in progress when first created    
$stat = $doc->create_element("status");    
$stat = $root->append_child($stat);    
$stat_text = $doc->create_text_node($status);    
$stat_text = $stat->append_child($stat_text);    
   
   
//create paras    
if (is_array($body)){    
 foreach ($body as $K => $V){    
       
   if ($V != ""){    
     $V = stripslashes($V);    
     $para = $doc->create_element("para-$K");    
     $para = $root->append_child($para);    
     $ptext = $doc->create_text_node($V);    
     $ptext = $para->append_child($ptext);    
   }    
 }    
}    
   
//write to the file (first delete existing one!)    
$filename = "./xml/".$id . ".xml";    
unlink($filename);    
$doc->dump_file($filename, false, true);    
   
//send user back to adminindex    
header("Location:adminindex.php");    
?>

Удаление статьи XML

Удалить файл XML очень просто. Все, что вам нужно сделать, это передать имя файла на страницу delArticle.php, отсоединить файл и отправить пользователя обратно на страницу adminindex.php:

 <?php     
session_start();    
   
if ($_SESSION["login"] != "true"){    
 header("Location:login.php");    
 $_SESSION["error"] = "<font color=red>You don't have privileges to see the admin page.</font>";    
 exit;    
}    
$dir = "./xml/";    
$filetoburn = $dir . $file;    
unlink($filetoburn);    
header("Location: adminindex.php");    
?>

К этому моменту мы только что завершили раздел управления статьями нашей CMS на базе XML. Мы создали страницу входа, административный указатель и страницы для добавления, редактирования и удаления статей.

В следующей части нашей статьи мы создадим дисплейную часть веб-сайта, чтобы посетители могли читать и искать статьи.

Построение дисплея

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

Давайте повторим наши требования к дисплеям:

  • Посетители сайта смогут просматривать «живые» статьи, перечисленные по заголовкам. Они также смогут выполнять поиск по заголовкам и ключевым словам.
  • Сам сайт будет состоять из следующих страниц:
    • Домашняя страница, на которой перечислены пять статей, опубликованных на сайте, и функция поиска. Кроме того, посетители сайта могут нажать на ссылку, чтобы показать все статьи.
    • Страница сведений о статье, отображающая одну статью за раз.
    • Страница результатов поиска, на которой будут перечислены все статьи по автору, ключевому слову или строке, введенной в поисковую систему.

Домашняя страница

Домашняя страница index.php содержит код, который в основном повторяет то, что мы создали на стороне администратора. Он в основном просматривает все статьи в каталоге xml /, открывает каждый файл и ищет статус, заголовок и реферат. Если для статуса установлено что-то отличное от «live», то цикл находит следующую статью.

Результатом является список заголовков статей и рефератов, отображаемых на главной странице. Каждая ссылка ведет посетителя сайта на страницу showArticle.php.

Вот код (обратите внимание, что я также включил виджет поиска):

 <?php     
   
function extractText($array){    
 if(count($array) <= 1){    
   //we only have one tag to process!    
   for ($i = 0; $i<count($array); $i++){    
     $node = $array[$i];    
     $value = $node->get_content();    
   }    
   return $value;    
 }      
     
}      
?>    
   
<html>    
<head>    
<title>Welcome to XMLTEST</title>    
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">    
</head>    
   
<body>    
<h1>Welcome to the XMLTEST site</h1>    
<p><br>    
 <a href="adminindex.php">Admin Login</a> </p>    
<form name="search" method="post" action="searchArticles.php">    
 Search articles:      
 <input name="search" type="text" id="search">    
 <input name="Search" type="submit" id="Search" value="Search">    
</form>    
<p>The following articles are available: </p>    
<table border=1 cellspacing=0 cellpadding=2 width=500>    
<?php    
$dh = opendir('./xml/');    
   
$fileCount = 0;    
while ($file = readdir($dh) and $fileCount <= 5){    
 if (eregi("^\.\.?$", $file)) {    
   continue;    
 }    
 $open = "xml/".$file;    
 $xml = domxml_open_file($open);    
   
 //we need to pull out all the things from this file that we will need to      
 //build our links    
 $root = $xml->root();    
 $stat_array = $root->get_elements_by_tagname("status");    
 $status = extractText($stat_array);    
     
 $ab_array = $root->get_elements_by_tagname("abstract");    
 $abstract = extractText($ab_array);    
   
 $h_array = $root->get_elements_by_tagname("headline");    
 $headline = extractText($h_array);    
   
 if ($status != "live"){    
   continue;    
 }    
 echo "<tr valign=top><td>";    
 echo "<a href="showArticle.php?file=".$file . "">".$headline . "</a><br>";    
 echo $abstract;    
 echo "</td></tr>";    
     
 $fileCount++;    
}    
?>    
</table>    
   
<br><a href="adminindex.php">Admin Login</a>    
</body>    
</html>

Показать страницу статьи

На странице showArticle.php отображаются отдельные статьи.

Все, что вы узнали о извлечении текста из XML-структуры, применимо и здесь. По сути, вы открываете статью XML на основе имени файла, которое вы передаете на страницу. Затем вы извлекаете каждый нужный вам узел и сохраняете их как переменные. В случае наших абзацев мы будем хранить их в массиве, чтобы мы могли распечатать их с помощью простого цикла foreach. Затем мы печатаем переменные на экране.

Вот код:

 <?php     
session_start();    
   
function extractText($array){    
 if(count($array) <= 1){    
   //we only have one tag to process!    
   for ($i = 0; $i<count($array); $i++){    
     $node = $array[$i];    
     $value = $node->get_content();    
   }    
   return $value;    
 }      
     
}      
   
   
//pull in the XML file    
   
if ($file == ""){    
   
 echo "<h2>You didn't choose a file to edit!</h2>";    
 echo "<a href="index.php">Go back to index and choose a file</a>";    
 exit;    
} else {    
 $open = "./xml/" . $file;    
 $xml = domxml_open_file($open);    
 $root = $xml->root();    
     
 $id = $root->get_attribute("id");    
   
 $h_array = $root->get_elements_by_tagname("headline");    
 $headline = extractText($h_array);    
   
 $stat_array = $root->get_elements_by_tagname("status");    
 $status = extractText($stat_array);    
   
       
 $a_array = $root->get_elements_by_tagname("author");    
 $author = extractText($a_array);    
     
 $e_array = $root->get_elements_by_tagname("email");    
 $email = extractText($e_array);    
     
 $ab_array = $root->get_elements_by_tagname("abstract");    
 $abstract = extractText($ab_array);    
   
 $kl_array = $root->get_elements_by_tagname("keywords");    
 $keywords = extractText($kl_array);    
     
 $lead_array = $root->get_elements_by_tagname("para-intro");    
 $para["intro"] = extractText($lead_array);    
   
 $second_array = $root->get_elements_by_tagname("para-main");    
 $para["main"] = extractText($second_array);    
   
 $con_array = $root->get_elements_by_tagname("para-conclusion");    
 $para["con"] = extractText($con_array);    
     
   
?>    
<html>    
<head>    
<title><?php echo $headline; ?></title>    
<meta name="keywords" content="<?php echo $keywords; ?>">    
<meta name="description" content="<?php echo $abstract; ?>">    
   
</head>    
<body>    
<h1><?php echo $headline; ?></h1>    
<a href="index.php">back to main</a>    
<p>by <a href="mailto:<?php echo $email; ?>"><?php echo $author; ?></a></p>    
<p><small><?php echo $abstract; ?></small></p>    
<?php    
foreach ($para as $k => $v){    
 echo "<p>".$v."</p>n";    
}    
   
?>    
</body>    
</html>    
   
<?php    
}    
?>

Поиск по статьям

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

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

Когда я отправляю результаты на экран, я проверяю количество записей в этом массиве. Если счетчик равен 0, я отображаю сообщение о том, что ни один файл не соответствует поисковому запросу. В противном случае я отображаю связанный заголовок и реферат для каждой найденной статьи.

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

Вот код:

 <?php      
session_start();      
$results = array();      
     
//this is a very simple, potentially very slow search      
function extractText($array){      
 if(count($array) <= 1){      
   //we only have one tag to process!      
   for ($i = 0; $i<count($array); $i++){      
     $node = $array[$i];      
     $value = $node->get_content();      
   }      
   return $value;      
 }      
       
}        
     
$dh = opendir('./xml/');      
     
while ($file = readdir($dh)){      
 if (eregi("^\.\.?$", $file)) {      
   continue;      
 }      
 $open = "./xml/".$file;      
 $xml = domxml_open_file($open);      
     
 //we need to pull out all the things from this file that we will need to      
 //build our links      
 $root = $xml->root();      
 $stat_array = $root->get_elements_by_tagname("status");      
 $status = extractText($stat_array);      
       
 $k_array = $root->get_elements_by_tagname("keywords");      
 $keywords = extractText($k_array);      
     
 $h_array = $root->get_elements_by_tagname("headline");      
 $headline = extractText($h_array);      
       
 $ab_array = $root->get_elements_by_tagname("abstract");      
 $abstract = extractText($ab_array);      
     
 if ($status != "live"){      
   continue;      
 }      
     
 if (eregi($searchTerm, $keywords) or eregi($searchTerm,$headline)){      
   $list['abstract'] = $abstract;      
   $list['headline'] = $headline;      
   $list['file'] = $file;      
   $results[] = $list;      
 }      
     
}      
     
$results = array_unique($results);      
     
?>      
<h1>Search Results</h1>      
<a href="index.php">back to main</a>      
<p>You searched for: <i><?php echo $searchTerm ?></i></p>      
<hr>      
     
     
<?php      
     
if (count($results)>0){      
 echo "<p>Your search results:</p>";      
 foreach ($results as $key => $listing){      
   echo "<br><a href="showArticle.php?file=".$listing["file"]."">" . $listing["headline"]."</a>n";      
   echo "<br>". $listing["abstract"];      
   echo "<br>";      
 }      
} else {      
     
 echo "<p>Sorry, no articles matched your search term.";      
}      
     
?>
Вывод

Это оно! Хорошо сделано — мы покрыли большую территорию. Мы изучили:

  • Некоторые элементарные инструменты для разработки XML-структур
  • Как создать очень простой и безопасный инструмент администратора, чтобы позаботиться об основных функциях сайта
  • Как создать домашнюю страницу, страницу просмотра статьи и простую поисковую систему

В каждом случае есть место для улучшений, утонченности и надежности. Главное, работая с инструментами, вы познакомились с некоторыми основными понятиями структур данных XML, рабочего процесса приложения и простого проектирования CMS.