Условия лабораторных работ (Лаб практикум) / Лабораторная работа 7 – Использование шаблонов
.docЛабораторная работа № 7 – Использование шаблонов
Цель работы:
Изучение технологии и получение практических навыков отслеживания сеанса пользователя.
Теоретические сведения
Шаблоны можно рассматривать как «расширение» программного кода. Шаблоны не только автоматизируют утомительный процесс кодирования, но и обеспечивают структурное деление проекта в рабочих группах. Роль такого деления возрастает с увеличением объемов проекта и численности групп, а также с усложнением архитектуры проекта, причем не только на стадии программирования, но и при последующем сопровождении программы.
Нетривиальная система шаблонов
Сказанное стоит пояснить на конкретном примере. Допустим, имеется команда разработчиков, состоящая из web-дизайнеров и программистов. В идеале группа web-дизайнеров трудится над созданием привлекательного и удобного сайта, а группа программистов в это время работает над эффективностью и широтой возможностей web-приложения. К счастью, шаблоны заметно упрощают подобное структурирование процесса. Настоящая глава посвящена созданию системы шаблонов, обеспечивающих подобное «разделение труда».
Представлен некий базовый шаблон.
Пример шаблона
<html>
<head>
<title>:::::{page_title}:::::</title>
</head>
<body bgcolor="{bg_color}">
Welcome to your default home page. {user_name}!<br>
You have 5 MB and 3 email addresses at your disposal.<br>
Have fun!
</body>
</html>
Обратите внимание на три строки (page_title, bg_color и user_name), заключенные в фигурные скобки ({ }). Фигурные скобки имеют особый смысл при обработке шаблонов — заключенная в них строка интерпретируется как имя переменной, вместо которого подставляется ее значение. Дизайнер строит страницу по своему усмотрению; все, что от него потребуется, — включать в соответствующие места документа эти ключевые строки. Конечно, программисты и дизайнеры должны заранее согласовать имена всех переменных!
Итак, как же работает эта схема? Прежде всего, возможно, нам придется одновременно работать с несколькими шаблонами, обладающими одними и теми же общими атрибутами. В таких ситуациях применение технологии объектно-ориентированного программирования (ООП) оказывается особенно эффективным По этой причине все функции построения и выполнения операций с шаблонами будут оформлены в виде методов класса.
<?
class template {
VAR $files = array( );
VAR $variables = array( );
VAR $opening_escape = '{';
VAR $closing_escape = '}' ;
VAR $sql = array();
VAR $host = "localhost";
VAR $user = "root";
VAR $pswd = "";
VAR $db = "templ";
VAR $address_table = "addressbook";
function address_sql($file_id, $variable_name, $letter) {
// Подключиться к серверу MySQL и выбрать базу данных
mysql_connect($this->host, $this->user, $this->pswd) or die("Couldn't connect to MySQL server!");
mysql_select_db($this->db) or die("Couldn't select MySQL database!");
// Обратиться с запросом к базе данных
$query = "SELECT last_name, first_name, tel, email FROM $this->address_table WHERE last_name LIKE '$letter%' ";
$result = mysql_query($query);
// Открыть файл "rows.addresses"
// и прочитать его содержимое в переменную
$fh = fopen("$variable_name", "r");
$file_contents = fread($fh, filesize("rows.addresses") );
// Заменить имена переменных в ограничителях
// данными из базы.
while ($row = mysql_fetch_array($result)) {
$new_row = $file_contents;
$new_row=str_replace($this->opening_escape."last_name".$this->closing_escape, $row["last_name"], $new_row);
$new_row=str_replace($this->opening_escape."first_name".$this->closing_escape,$row["first_name"], $new_row);
$new_row=str_replace($this->opening_escape."telephone".$this->closing_escape,$row["tel"], $new_row);
$new_row = str_replace($this->opening_escape."email".$this->closing_escape, $row["email"],$new_row);
// Присоединить запись к итоговой строке замены
$complete_table .= $new_row;
}
$sql_array_key = $variable_name;
$this->sql[$sql_array_key] = $complete_table;
// Включить ключ в массив variables для последующего поиска
$this->variables[$file_id][ ] = $variable_name;
// Закрыть файловый манипулятор
fclose($fh);
}
// Функция: register_file( )
// Назначение: сохранение в массиве содержимого файла.
// определяемого идентификатором $file_id
function register_file($file_id, $file_name) {
// Открыть $file_name для чтения или завершить программу
// с выдачей сообщения об ошибке.
$fh = fopen($file_name, "r") or die("Couldn't open $file_name!");
// Прочитать все содержимое файла $file_name в переменную.
$file_contents = fread($fh, filesize($file_name));
// Присвоить содержимое элементу массива
// с ключом $file_id.
$this->files[$file_id] = $file_contents;
// Работа с файлом завершена, закрыть его.
fclose($fh);
}
// Функция: register_variables( )
// Назначение: сохранение переменных, переданных
// в параметре $variable_name. в массиве с ключом $file_id.
function register_variables($file_id, $variable_name) {
// Попытаться создать массив.
// содержащий переданные имена переменных
$input_variables = explode(".", $variable_name);
// Перебрать имена переменных
while (list(, $value) = each($input_variables)) :
// Присвоить значение очередному элементу массива $this->variables
$this->variables[$file_id][] = $value;
endwhile;
}
// Функция: file_parser( )
// Назначение: замена всех зарегистрированных переменных
// в файле с идентификатором $file_id
function file_parser($file_id) {
// Сколько переменных зарегистрировано для данного файла?
$varcount = count($this->variables[$file_id]);
// Сколько файлов зарегистрировано?
$keys = array_keys($this->files);
// Если файл $file_id существует в массиве $this->files
// и с ним связаны зарегистрированные переменные
if ( (in_array($file_id, $keys)) && ($varcount > 0) ) :
// Сбросить $х
$x = 0;
// Пока остаются переменные для обработки...
while ($x < sizeof($this->variables[$file_id])) :
// Получить имя очередной переменной
$string = $this->variables[$file_id][$x];
// Получить значение переменной. Обратите внимание:
// для получения значения используется конструкция $$.
// Полученное значение подставляется в файл вместо
// указанного имени переменной.
// Построить точный текст замены вместе с ограничителями
$needle = $this->opening_escape.$string.$this->closing_escape;
if (in_array($string, array_keys($this->sql))){
$this->files[$file_id] = str_replace($needle, $this->sql[$string], $this->files[$file_id]);
}
else {
GLOBAL $$string;
// Выполнить замену.
$this->files[$file_id] = str_replace($needle, $$string, $this->files[$file_id]);
}
// Увеличить $х
$x++;
endwhile;
endif;
}
// Функция: print_file()
// Назначение: вывод содержимого файла,
// определяемого параметром $file_id
function print_file($file_id) {
// Вывести содержимое файла с идентификатором $file_id
print $this->files[$file_id];
}
} //END template.class
?>
. Вспомогательный шаблон rows.addresses
<tr><td bgcolor="#c0c0c0">
<b>{last_name},{first_name}</b>
</td></tr>
<tr><td>
<b>{telephone}</b>
</td></tr>
<tr><td>
<b><a href = "mailto:{email}">{email}</a></b>
</td></tr>
В массиве $files хранятся идентификаторы файлов и содержимое каждого файла. Атрибут $variables представляет собой двухмерный массив для хранения файлового идентификатора (ключа) и всех соответствующих переменных, обрабатываемых в схеме шаблонов. Наконец, атрибуты $opening_escape и $closing_escape задают ограничители для частей шаблона, которые должны заменяться системой. Как было показано в примере в качестве ограничителей будут использоваться фигурные скобки ({ }). Впрочем, можно изменить два последних атрибута и выбрать ограничители по своему усмотрению. Главное — проследить за тем, чтобы эти символы не использовались для других целей.
Каждый метод класса решает конкретную задачу, соответствующую той или иной операции в процессе обработки шаблона. На простейшем уровне этот процесс можно разделить на четыре стадии.
Регистрация файлов — регистрация всех файлов, обрабатываемых сценариями шаблонов.
Регистрация переменных — регистрация всех переменных, которые должны заменяться своими значениями в зарегистрированных файлах.
Обработка файлов — замена всех переменных, находящихся между ограничителями, в зарегистрированных файлах.
Вывод файла — вывод обработанных зарегистрированных файлов в браузере.
Шаблон представлен ниже:
<html>
<head>
<title>:::::{page_title}:::::</title>
</head>
<body bgcolor="white">
<table cellpadding=2 cellspacing=2 width=600>
<h1>Книги на букву: {letter}</h1> <tr><td>
<a href="index.php?letter=a">A</a> |
<a href="index.php?letter=b">B</a> |
<a href="index.php?letter=c">C</a> |
<a href="index.php?letter=d">D</a> |
<a href="index.php?letter=e">E</a> |
<a href="index.php?letter=f">F</a> |
<a href="index.php?letter=g">G</a> |
<a href="index.php?letter=h">H</a> |
<a href="index.php?letter=i">I</a> |
<a href="index.php?letter=j">J</a> |
<a href="index.php?letter=k">K</a> |
<a href="index.php?letter=l">L</a> |
<a href="index.php?letter=m">M</a> |
<a href="index.php?letter=n">N</a> |
<a href="index.php?letter=o">O</a> |
<a href="index.php?letter=p">P</a> |
<a href="index.php?letter=q">Q</a> |
<a href="index.php?letter=r">R</a> |
<a href="index.php?letter=s">S</a> |
<a href="index.php?letter=t">T</a> |
<a href="index.php?letter=u">U</a> |
<a href="index.php?letter=v">V</a> |
<a href="index.php?letter=w">W</a> |
<a href="index.php?letter=x">X</a> |
<a href="index.php?letter=y">Y</a> |
<a href="index.php?letter=z">Z</a>
</td></tr>
</table>
</body>
</html>
Программа представлена ниже:
<?
require_once("tplclass.php");
$page_title = "Адресная книга";
if (!isset($letter))
$letter = 'a';
$tpl = new template;
$tpl->register_file("book", "book.html");
$tpl->register_variables("book", "page_title.letter");
$tpl ->file_parser("book");
$tpl->print_file("book");
?>
Задание:
Модифицировать результаты лабораторной работы №6 путем использования шаблонов.
Контрольные вопросы
1. Назовите плюсы и минусы использования шаблонов?
2. Опишите алгоритм обработки шаблона?
3. Назначение функций implode и explode?
