PHP 4 на практике

       

Проект: адресная книга


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

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

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

mysql>CREATE table addressbook (

last_name char(35) NOT NULL,

first_name char(20) MOT NULL,

tel char(20) NOT NULL,

email char(55) NOT NULL );

Разумеется, вы можете самостоятельно добавить поля для хранения адреса, города и т. д. Для наглядности я буду использовать сокращенную таблицу, приведенную ранее.

Теперь я возьму на себя роль дизайнера и займусь созданием шаблонов. Для этого проекта нужны два шаблона. Код первого, «родительского» шаблона book.html приведен в листинге 12.8.

Листинг 12.8.

Основной шаблон адресной книги book.html

<html>

<head>



<title>:::::{page_title}:::::</title>

</head>

<body bgcolor="white">

<table cellpadding=2 cellspacing=2 width=600>

<h1>Address Book: {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>

{rows.addresses}

</table>

</body>

</html>

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



В странице встречаются три имени переменных, заключенных в ограничители: page_title, letter и rows_addresses. Смысл первых двух переменных очевиден: текст в заголовке страницы и буква адресной книги, использованная для выборки текущих адресных данных. Третья переменная относится к дополнительному шаблону (листинг 12.9) и определяет файл конфигурации таблицы, включаемый в основной шаблон. Файлы конфигурации таблиц используются в связи с тем, что в сложных страницах может быть одновременно задействовано несколько шаблонов, в каждом из которых данные форматируются в виде таблиц HTML. Шаблон rows.addresses (листинг 12.9) выполняет вспомогательные функции и вставляется в основной шаблон book.html. Вскоре вы поймете, почему это необходимо.

Листинг 12.9.

Вспомогательный шаблон 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>

В листинге 12.9 встречаются четыре переменных, заключенных в ограничители: last_name, first_name, telephone и emal. Смысл этих переменных очевиден (см. определение таблицы addressbook). Следует заметить, что этот файл состоит только из табличных тегов строк (<tr>...</tr>) и ячеек (<td>...</td>). Дело в том, что этот файл вставляется в шаблон многократно, по одному разу для каждого адреса, прочитанного из базы данных. Поскольку имя переменной rows.addresses в листинге 12.8 включается внутрь тегов <table>...</table>, форматирование HTML будет обработано правильно. Чтобы вы лучше поняли, как работает этот шаблон, взгляните на рис. 12.1 — на нем изображена копия страницы адресной книги. Затем проанализируйте листинг 12.10, содержащий исходный текст этой страницы. Вы увидите, что содержимое файла rows.addresses многократно встречается в странице.



Листинг 12.10.

Исходный текст страницы, изображенной на рис. 12.1

<html>

<head>

<title>:::::Address Book:::::</title>

</head>

<body bgcolor="white">

<table cellpadd1ng=2 cellspacing=2 width=600>

<hl>Address Book: f</hl>

<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?1etter=n">N</a> | 

<a href="index.php?letter=o">0</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>

<tr><t

bgcolor="#c0c0c0">

<b>Fries.Bobby</b>

</td></tr>

<tr><td>

<b>(212) 563-5678</b>

</td></tr>

<tr><td> "

<b>

<a href="mailto:bobby@fries.com">bobby@fries.com</a>

</b>

</td></tr>

<tr><td bgcolor="#c0c0c0">

<b>Frenchy.Pierre</b>

</td></tr>

<tr><td>

<b>002-(30)-09-7654321</b>

</td></tr>

<tr><td>

<b><a href = "mailto:frenchy@frenchtv.com">
frenchy@frenchtv.com</a></b>

</td></tr>

</table>

</body>

</html>

Как видно из приведенного листинга, в адресной книге хранятся записи двух лиц, фамилии которых начинаются с буквы F: Bobby Fries и Pierre Frenchy. Соответственно в таблицу вставляются данные двух записей.

Дизайнерская часть проекта адресной книги завершена, и я перехожу к роли программиста. Возможно, вас удивит тот факт, что класс tempiate. class (см. листинг 12.7) практически не изменился, если не считать появления одного нового метода — address_sql( ). Код этого метода приведен в листинге 12.11.

Листинг 12.11.

Обработка данных, полученных в результате запроса

class template {

VAR $files = array( );

VAR $variab!es = array( ):

VAR $sql = array();

VAR $opening_escape - '{';

VAR $closing_escape = '}';

VAR $host = "localhost";

VAR $user = "root";

VAR $pswd = "";

VAR $db = "book";

VAR $address table = "addressbook";

function address_sql($file_id, $vanable_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 lastjiame 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($th1s->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;

endwhile;

$sql_array_key = $variable_name;

$this->sql[$sql_array_key] = $complete_table;

// Включить ключ в массив variables для последующего поиска

$this->variables[$file_id][ ] = $variable_name;

// Закрыть файловый манипулятор fclose(lfh);

Комментариев, приведенных в листинге 12.11, вполне достаточно для того, чтобы вы разобрались в происходящем, однако я должен сделать несколько важных замечаний. Во-первых, обратите внимание на то, что файл rows.addresses открывается только один раз. Возможен и другой вариант — многократно открывать и закрывать файл rows.addresses, каждый раз производя замену и присоединяя его содержимое к переменной $complete_table. Впрочем, такое решение будет крайне неэффективным. Потратьте немного времени и разберитесь в том, как новые данные таблицы в цикле присоединяются к переменной $complete_table.



Второе, на что следует обратить внимание при просмотре листинга 12.11, — появление пяти новых атрибутов класса: $host, $user, $pswd, $db и $address_table. В этих атрибутах хранится информация, необходимая для сервера SQL. Полагаю, смысл каждого атрибута понятен без объяснений, а если нет — вернитесь и повторите материал главы 11.

 


Рис. 12.1.

Страница адресной книги

Все, что осталось сделать — написать файл index.php, инициирующий обработку шаблонов, Код этого файла приведен в листинге 12.12. Если щелкнуть на одной из ссылок (index.php?letter=буква) на странице book.html (см. листинг 12.8), загружается страница index.php, которая, в свою очередь, заново строит book.html с включением новой информации.

Листинг 12.12.

Обработчик шаблонов index.php

include("Listing12-11.php"); $page_title = "Address Book";

// По умолчанию загружается страница с фамилиями,

// начинающимися с буквы 'а' if (! isset($letter) ) :

$letter = "а";

endif ;

$tpl = new template;

$tpl->register_file("book", "book.html");

$tpl->register_variables("book", "page_title.letter");

$tpl ->address_sql("book", "rows.addresses", "$letter");

$tpl ->file_parser("book");

$tpl->phnt_fil("book");

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


Содержание раздела