Анимация
JavaScript
|
Главная Библионтека ( Замечание С горечью отмечаю, что разработчики PHP практически не приблизили нас к решению проблемы отделения кода от шаблона страницы. Создается впечатление, что они преследовали как раз противоположные цели: максимально упростить совмещение HTML и PHP за счет снижения функциональности последнего. Когда мы будем разбирать код шаблонизатора ниже в этой главе, вы увидите, на какие "увертки" нам придется пойти, чтобы обойти все "подводные камни", невольно расставленные для нас авторами PHP. Двухуровневая схема Итак, мы желаем максимально отделить работу программистов и дизайнеров. Давайте будем делать это не сразу, а постепенно, детализируя ситуацию. Вначале решим более простую проблему: разделим код сценария и шаблон его страницы (что я называю двухуровневой схемой построения сценария). Это довольно несложно. Мы уже поступали так в главе 28, когда писали сценарий простейшего фотоальбома. Теперь мы поставим задачу более точно. Шаблон страницы Пусть нам нужно завести новый раздел сайта - гостевую книгу. Выделим для нее отдельный каталог на сервере и создадим в нем файл примерно следующего содержания (листинг 30.1). Назовем его шаблоном страницы. \ Листинг 30.1. Шаблон: gbook.htm <html><head><title>Гостевая книга</title></head> <body> <h2>Добавьте свое сообщение:</h2> <form action=gbook.php method=post> Ваше имя: <input type=text name="New[name]"><br> Комментарий:<br> <textarea name="New[text]" wrap=virtual cols=60 rows=5></textarea><br> <input type=submit name="doAdd" value="Добавить!"> </form> <h2>Гостевая книга:</h2> <?foreach($Book as $id=>$Entry) {?> Имя человека: <?=$Entry[name]?><br> Его комментарий:<br> <?=$Entry[text]?><hr> <?}?> </body></html> Видите, здесь почти нет PHP-кода, за исключением разве что одного-единственного цикла foreach. Для человека, занимающегося внешним видом вашей гостевой книги и совершенно не разбирающегося в программировании, это не должно выглядеть, как непреодолимое препятствие. В некоторых других языках программирования мы могли бы написать систему, лишенную и указанного недостатка, но обладающую всеми качествами рассматриваемой. Честно говоря, существует всего лишь один способ добиться этого: "замаскировать" инструкцию foreach специальным псевдотэгом (который, как это ни удивительно, гораздо лучше воспринимается дизайнерами), чтобы код выглядел примерно так: <foreach src=../../../cl/Book> Имя человека: $name<br> Его комментарий:<br>$text<hr> </foreach> Согласен, для программиста такая замена действительно кажется смешной. Однако она сильно приближает шаблон нашей страницы к идеалу - практически "чистому" HTML-коду. Примечание Хочу сразу сказать всем любителям разбивать один шаблон на множество файлов: их способ чаще всего не оправдывает себя при написании крупных сценариев. Дело в том, что при такой организации довольно тяжело переставлять подшаблоны внутри страницы. Кроме того, подшаблоны нужно как-то загружать, а поручать эту задачу коду страницы не очень удобно все из тех же соображений: придется работать и программисту, и верстальщику. Легче всего это представить на примере все той же гостевой книги: если бы мы выделили тело цикла foreach в отдельный файл и попытались избавиться от этой инструкции, то пришлось бы переложить задачу циклического вывода данных на плечи программиста, сообщив ему попутно имя подшаблона. Чувствуете, сколько лишних зависимостей?.. Надо заметить, что реализовать "прозрачную" замену подобных тэгов на соответствующие инструкции в PHP практически невозможно (во всяком случае, без ущерба простоте отладки сценария). Это связано с чрезвычайной слабостью этого интерпретатора в вопросе, касающемся "перехвата" и обработки ошибок во время выполнения кода. К счастью, такая слабость оказывается непреодолимой лишь в подобных "экзотических" случаях. При написании шаблонизатора она сказывается гораздо меньше. Генератор данных Конечно, это еще далеко не весь сценарий. Вы, наверное, заметили, что сердце шаблона - цикл foreach вывода записей - использует непонятно откуда взявшуюся переменную $Book, по контексту - двумерный массив. Кроме того, при отправке формы тоже ведь нужно предусмотреть некоторые действия (а именно, добавление записи в книгу). Мы видим, что где-то должен быть скрыт весь этот код. Он, действительно, располагается в отдельном файле с именем gbook.php. Отличительная черта этого файла - то, что в нем нет никакого намека на то, как нужно форматировать результат работы сценария. Именно поэтому я называю его генератором данных (листинг 30.2). i Листинг 30.2. Генератор данных: gbook.php <? define("GBook","gbook.dat"); имя файла с данн1ми гостевой книги Загружает гостевую книгу с диска. Возвращает содержание книги. function LoadBook($fname) { $f=@fopen("gbook.dat","rb"); if(!$f) return array(); $Book=Unserialize(fread($f,100000)); fclose($f); return $Book; Сохраняет содержимое книги на диске. function SaveBook($fname,$Book) { $f=fopen("gbook.dat","wb"); fwrite($f,Serialize($Book)); fclose($f); Исполняемая часть сценария. Сначала - загрузка гостевой книги. $Book=LoadBook(GBook); Обработка форм:, если сценарий вызван через нее. Если сценарий запущен после нажатия кнопки Добавить... if(!empty($doAdd)) { Добавить в книгу запись пользователя - она у нас хранится в массиве $New, см. форму в шаблоне. Запись добавляется, как водится, в начало книги. $Book=array(time()=>$New)+$Book; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 [ 138 ] 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |