Внимание! Для работы с этим курсом необходимы учебные файлы, которые Вы можете загрузить здесь.
К концу книги в качестве завершающего штриха выполним итоговое упражнения для создания системы управления содержимым для обновления информации о странах. С ее помощью сотрудники Newland Tours смогут добавлять новые профили стран, а также изменять или удалять уже существующие, взаимодействуя с приложением при помощи простых HTML-форм. Поскольку SQL-операторы INSERT и UPDATE уже применялись для управления содержимым, единственным новым оператором в этом уроке является DELETE.
В отличие от предыдущих уроков, в которых создавались приложения для добавления и обновления данных, в этом уроке не будут применяться серверные модели поведения, встроенные в Dreamweaver. Это не означает, что использовать модели поведения не следует, но одна из главных задач этой книги — дать принципиальные основы и опыт работы с кодом, и, тем самым, способствовать формированию ценных навыков, которые пригодятся вам в дальнейшем при самостоятельной разработке динамичных сайтов. Как не раз подчеркивалось в книге, при создании динамичных сайтов нередко требуется понимание кода ASP, ColdFusion или PHP.
Несмотря на то, что серверные модели поведения довольно удобны, принципы их работы не всегда понятны, поскольку добавляемый код скрывается за диалоговыми окнами. Модели поведения позволяют увеличить скорость разработки, но не подходят для обучения. Помимо этого, код, который генерируется серверными моделями поведения, как правило, невероятно сложен, особенно для тех, кто только начинает заниматься веб-разработками. Причиной этого является не сложность задачи, для выполнения которой предназначен код, а гигантское количество всевозможных условий, при которых этот код должен работать. Именно поэтому в добавляемые модели поведения очень непросто вносить изменения (благодаря простоте языка технологии ColdFusion ее пользователям гораздо проще разбираться в коде серверных моделей поведения, чем пользователям ASP или PHP). Написание кода вручную дает намного больше, чем применение готовых моделей поведения.
Рис. 16.1. Окончательный вариант CMS, позволяющий пользователям управлять контентом сайта при помощи веб-форм, будет написан вручную, "с нуля"
Большинство компонентов CMS уже использовались в предыдущих уроках. К ним относятся группы страниц, которые выполняют определенные функции, работая в комбинации с другими; формы, получающие информацию от пользователя; SQL-запросы для перемещения данных между страницей и базой данных, а также наборы основной и детальной страниц. Разница заключается в том, что все это будет использоваться одновременно, и, кроме того, код будет полностью создаваться вручную.
В то же время инструкции рассчитаны на более высокий уровень сложности. Другими словами, для определенных задач, которые не раз выполнялись в разных разделах книги (например, создание новых страниц или форм) подробных инструкций приводиться не будет, поскольку подразумевается, что достаточно общих указаний. Это позволит уделить должное внимание более сложным задачам – подключению ASP, ColdFusion или PHP к базе данных и написанию запросов, благодаря которым и будет работать CMS.
Подготовка системы управления контентом
При разработке веб-приложений нередко возникает желание запустить Dreamweaver и сразу приступить к созданию страниц. Но для более эффективной работы предварительно следует точно определить, что именно требуется создать, и какие файлы необходимы для того, чтобы приложение работало. Создаваемая система управления содержимым должна состоять из группы страниц, позволяющей добавлять в базу новые профили стран, а также изменять или удалять старые.
Разница между этими двумя видами действий заключается в том, что при добавлении записи достаточно создать форму, в которую вводятся нужные данные, а для удаления или обновления существующей записи, необходимо предоставить пользователям возможность выбрать нужную запись. Другими словами, для добавления записи не требуется создавать основную и детальную страницу, а для обновления и удаления этот набор страниц необходим. При этом детальные страницы, которые отвечают за обновление и удаление записей, могут иметь общую основную страницу.
Для выполнения каждого из этих действий нужен свой сценарий, соответственно добавляющий, обновляющий и удаляющий записи. Проще всего поместить каждый сценарий на свою страницу, и добавить в ее название частицу _processor, которая использовалась в названиях многих файлов на сайте. После выполнения сценария пользователь будет переведен на основную страницу, чтобы убедиться в том, что необходимые изменения были внесены. Эти страницы будут скрыты, поскольку они загружаются на доли секунды, во время которых производится обработка сценария, после чего загружается другая страница.
Примечание. Несмотря на то, что поместить сценарий в отдельный файл совсем не сложно, многие разработчики помещают его на страницу, где расположена форма. Таким образом, после заполнения формы пользователем, страница передает полученные данные самой себе. В верхней части кода добавляется условная конструкция, проверяющая наличие переменных формы. Если переменные присутствуют, то запускается сценарий. В противном случае, сценарий игнорируется, и загружается страница с формой. Такой подход уменьшает количество файлов на сервере и позволяет хранить все сценарии, выполняющие общую задачу, в одном месте. Однако раздельное хранение сценариев тоже имеет свои достоинства. Во-первых, опытный программист может написать универсальный сценарий, который будет использоваться несколькими страницами. Во-вторых, если поместить все сценарии в отдельную папку и закрыть ее для общего доступа, это повысит защищенность сайта.
На приведенной ниже схеме отмечены все страницы, необходимые для создания приложения.
На странице admin_index.asp пользователи могут выбрать нужное действие: добавить информацию о новой стране (в этом случае загружается страница admin_cp_insert.asp) либо удалить или обновить существующий профиль (в этом случае загружается страница admin_cp_ master.asp).
На странице admin_cp_insert.asp содержится незаполненная форма. Пользователи заполняют ее, чтобы создать новый профиль страны. После заполнения формы данные пересылаются на страницу admin_cp_ insert_processor.asp, которая добавляет их в базу данных, после чего пользователь переводится на основную страницу. Наличие новой страны на основной странице служит доказательством того, что операция прошла успешно.
На той же странице admin_cp_master.asp пользователи могут перейти по ссылке для обновления существующей записи. При таком варианте развития событий они переводятся на страницу admin_cp_update.asp, на которой находится форма, содержащая уже существующие данные. После изменения данных и нажатия кнопки Submit сценарий на странице admin_cp_update_processor.asp внесет соответствующие изменения в базе данных, а затем снова загрузится основная страница. Чтобы убедиться в успешности операции обновления, достаточно вновь взглянуть на профиль страны.
Другая ссылка на основной странице служит для удаления профиля страны. При переходе по ней загружается страница admin_cp_delete_ processor.asp, содержащая сценарий, который удаляет выбранную страну, после чего снова загружается основная страница. Этот процесс занимает доли секунды, при этом пользователям может показаться, что они не покидали основной страницы, – просто после ее обновления в из списка была удалена выбранная страна.
Итак, основная схема системы управления содержимым ясна, и пора переходить к ее реализации.
- На основе шаблона admin_template.asp создайте следующие видимые для пользователя страницы.
admin_cp_insert.asp
admin_cp_master.asp
admin_cp_update.asp
Эти страницы будут видимы для пользователя, поэтому не следует удалять их исходный код. Также требуется соответствующим образом настроить страницы. Для этого необходимо на панели инструментов изменить заголовки документов, а на месте заменителей заголовка (в верхней части страниц) следует ввести подходящий текст, например, Insert a new country profile ("Добавить профиль новой страны"), Select a country profile to modify or delete ("Выберите профиль страны, который требуется изменить или удалить") и Update a country profile ("Обновить профиль страны").
- Создайте три скрытые страницы и сохраните их под приведенными ниже названиями. В режиме кода (не дизайна) удалите весь код этих страниц.
admin_cp_insert_processor.asp
admin_cp_update_processor.asp
admin_cp_delete_processor.asp
Эти страницы не будут видны пользователю, поэтому в них не должно быть HTML-кода. В них должен содержаться только код сценария, необходимый для выполнения нужной операции (добавление, обновление записи и т.д.).
Совет. Самый простой способ выполнения этого шага – создать новый файл, удалить и него весь код и трижды сохранить под разными именами.
Итак, создано шесть файлов. Несмотря на то, что они пусты, они существуют, поэтому гораздо легче создать на них ссылки, поскольку приложение создается вручную.
Создание формы и написание набора записей вручную
В этом упражнении создается форма, используемая сотрудниками для добавления новых профилей стран. Данные формы должны передаваться на страницу admin_cp_insert_processor.asp, в которой будет содержаться код, необходимый для добавления новой записи в базу.
- В документе admin_cp_insert.asp создайте форму (Form Name [Имя формы]: frm_insertProfile; Action [Действие]: admin_cp_insert_processor.asp). Внутри нее вставьте таблицу, состоящую из семи строк (Rows), двух столбцов (Columns) и с границей толщиной в 1 пиксел (Border), как показано на рисунке.
Семь элементов, содержащихся в левом столбце, соответствуют семи из восьми полей в таблице tbl_country (восьмое поле – это создаваемый автоматически первичный ключ).
- В правый столбец добавьте элементы формы, указанные в приведенной таблице.
Тип элемента |
Имя элемента |
Примечания |
Список/Меню |
region |
На панели Property Inspector (Инспектор свойств) следует оставить выбранный по умолчанию тип Menu. |
Текстовое поле |
countryName |
|
Текстовое поле |
population |
|
Текстовое поле |
currency |
|
Текстовая область |
description |
Ввод описаний должен быть удобным, поэтому на панели инспектора свойств необходимо указать следующие параметры для размеров: Char Width (раз-мер поля) – 55; Num Lines (Число строк) — 9; Wrap (перенос) – Virtual (автоматический). |
Текстовое поле |
imageURL |
|
Текстовая область |
imageALT |
Эта текстовая область не должна быть такой большой, как область для описания. В этом случае следует указать параметры Char Width – 55 и Wrap — Virtual, а поле Num Lines оставить неза-полненным. |
Имена элементов и имена полей в соответствующей таблице снова совпадают, что облегчает их сопоставление. На этот раз SQL-запрос будет создаваться вручную без применения диалогового окна Insert Record (Вставка записи), тем не менее совпадающие имена полей формы и соответствующих полей базы данных даже в этом случае облегчают работу.
Форма практически готова, за исключением одного момента: в меню, расположенном вверху, не содержится никаких данных. Оно должно наполняться данными из таблицы tbl_region, а поэтому необходимо создать набор записей.
- В режиме Code (Код) найдите участок кода, расположенный после серверной модели поведения Restrict Access to Page (Ограничить доступ к странице), но перед открывающим тегом <!DOCTYPE…>. Введите код, необходимый для подключения к базе данных.
Для ASP:
<%
'Create connection object
Dim dbConn
Dim rs_regions
set dbConn = server.CreateObject("adodb.connection")
'Connect to database via DSN
dbConn.open("newland")
%>
Для ColdFusion:
<cfquery name="rs_regions" datasource="newland">
</cfquery>
Для PHP:
<?php
// Set up connection to MySQL
$host = "localhost";
$user = "[введите имя пользователя]";
$pwd = "[введите пароль]";
$dbConn = mysql_connect($host,$user,$pwd);
// Connect to newland_tours database
$database = "newland_tours";
mysql_select_db($database);
?>
Этого кода достаточно для подключения к базе данных. Однако после подключения больше ничего не происходит. Для обеспечения дальнейших действий требуется добавить SQL-запрос.
Рассмотрим введенный код. Код для ColdFusion выделяется своей простотой: в нем используется тег <cfquery>, в котором запросу присваивается имя (rs_regions) и указывается источник данных (newland).
Для написания кода ASP требуется значительно больше усилий. Ключевое слово Dim употребляется для объявления новых переменных. В приведенном участке кода создано две переменные: dbConn и rs_regions. Переменная dbConn применяется для создания самого подключения, а rs_region предназначена для хранения набора записей. Вместо указанных имен вполне могут использоваться другие. Строка, идущая после объявления переменных и начинающаяся с кода dbConn =, включает указание для ASP создать новый объект подключения к базе данных, названный dbConn. В следующей строке содержится указание применить это подключение к DSN под названием "newland".
Примечание. Возникает вопрос: почему в коде ASP и PHP присутствуют (соответственно) названия "newland" и "newland_tours" вместо "conn_newland", которое использовалось в предыдущих разделах книги. В случае с ASP "newland" – это имя DSN, которое хранится на сервере и указывает на базу данных Newland Tours. В случае с PHP "newland_tours" – это имя базы данных, расположенной на сервере MySQL. В свою очередь, "conn_newland" – это соединение, созданное в Dreamweaver, которое просто ссылается на DSN newland (ASP) или на базу данных newland_tours (PHP), но при этом отделено от них. Поскольку в данном случае код пишется вручную, и серверные модели поведения Dreamweaver не применяются, DSN newland для ASP и база данных newland_tours для PHP задаются напрямую.
Помимо прочего, основу технологии ASP составляет группа готовых объектов, разработанных для выполнения типичных задач. Таких объектов довольно много, и некоторые из них использовались в предыдущих уроках (хотя и не всегда это было понятно). В частности, к объектам ASP относятся Request, Response, Session и Application. Объекты Connection и Recordset входят в состав ADO (ActiveX Data Objects – объекты данных технологии ActiveX). Объектно-ориентированное программирование (ООП) в этой книге не рассматривается, однако сейчас достаточно сказать, что код, созданный в этом уроке, в дальнейшем с уверенностью можно использовать в качестве шаблона для подключения к базе данных.
Несмотря на то, что участок кода для PHP оказался более объемным, чем остальные, его достаточно легко читать. Встроенная функция mysql_connect() позволяет обработчику PHP найти сервер MySQL. Как видно из кода, для нее требуется указать три параметра: адрес, имя пользователя и пароль от учетной записи, к которой требуется получить доступ. Имя пользователя и пароль должны быть теми же, что указывались в диалоговом окне MySQL Connection (Соединение MySQL) в одном из предыдущих уроков при настройке подключения к базе данных. Их следует ввести вместо участков кода [введите имя пользователя] и [введите пароль]. Поскольку обработчик PHP не может найти сервер MySQL, он должен провести поиск самой базы данных. Для этого применяется встроенная функция mysql_select_db(), единственным параметром которой является имя базы данных на сервере MySQL.
- В пустой строке, оставленной на предыдущем шаге, введите код, необходимый для извлечения нужных записей.
Для ASP:
Set rs_regions = dbConn.Execute("SELECT * FROM tbl_region ORDER BY regionName")
Для ColdFusion:
Для ColdFusion:
Для PHP:
$query_rs_regions = "SELECT * FROM tbl_region ORDER BY regionName";
$rs_regions = mysql_query($query_rs_regions);
$row_rs_regions = mysql_fetch_assoc($rs_regions);
На данный момент этот SQL-код не должен вызывать вопросов. Он извлекает все поля из всех записей таблицы tbl_region и упорядочивает их в алфавитном порядке по названию региона.
Код ASP и PHP снова может вызвать недоумение. Начнем с ASP. Как известно, dbConn – это не набор записей, а объект соединения. Для формирования набора записей в приведенной строке кода создается объект набора записей (Recordset), содержимое которого эквивалентно данным, извлеченным при помощи переданного через соединение запроса.
Первые две строки кода PHP отправляют запрос в базу данных. Можно предположить, что в результате отправления запроса обратно передается набор записей, который сохраняется в переменной $rs_regions. Но это не так. При отправлении запроса в базу данных MySQL при помощи функции PHP mysql_query() обратно передается не набор записей, а число, которое указывает на данные. Сами данные не возвращаются. Вместо этого они помещаются в нейтральную область, которая не относится ни к PHP, ни к MySQL. Чтобы получить эти данные, следует извлечь их при помощи функции mysql_fetch_assoc() (или одного из ее вариантов). Эта функция извлекает данные из нейтральной области и создает массив для их хранения. В данном случае этот массив назван $row_rs_regions. После размещения данных в этом массиве он начинает играть роль набора записей, как в ASP или ColdFusion. Для доступа к данным следует ссылаться на $row_rs_regions.
Этого кода достаточно для создания набора записей и помещения данных на страницу. На панели Bindings (Привязки) этот набор записей отображен не будет, поскольку Dreamweaver не осознает его наличие. К сожалению, это означает и то, что привязать набор записей к объектам формы невозможно. Придется делать это вручную.
- В режиме Code (Код) прокрутите страницу вниз, пока не обнаружите форму. Несколькими строками ниже внутри таблицы расположен элемент <select>, который и является списком. Несколько раз нажмите (Enter) или (Return), чтобы с помощью пробелов добавить больше свободного места между открывающим и закрывающим тегами.
Тег <select> создает раскрывающийся список. Для добавления опций для списка используется тег <option>. Каждый тег <option> соответствует одной опции списка. Для его добавления применяется следующий синтаксис:
<option value="данные">Label</option>
В этом примере Label (Надпись) –используется в качестве надписи к списку (она видна пользователям), а data (Данные) – это значения, которое передается после заполнения формы. В качестве надписи следует указать поле regionName, а в качестве значения – regionID.
- В пустые строки, расположенные между тегами <select> введите код, необходимый для того, чтобы прикрепить к тегу <option> данные, извлеченные из базы.
Для ASP:
<%
Response.Write("<option value=""" & rs_regions("regionID") & """>"
& rs_regions("regionName") & "</option>")
%>
Для ColdFusion:
<cfoutput>
<option value="#rs_regions.regionID#">#rs_regions.regionName#</option>
</cfoutput>
Для PHP:
<?php
echo "<option value=\"".$row_rs_regions['regionID']."\">".
$row_rs_regions ['regionName']."</option>";
?>
Значение поля regionID привязано к параметру value, а значение regionName выступает в качестве надписи к списку.
К блокам кода ASP и PHP, как обычно, требуются дополнительные пояснения. Как известно из предыдущих уроков, функции Response.Write() и echo позволяют ASP и PHP выводить текст в браузер. В этой строке сервер получает указание вывести строку HTML-кода для тега <option>. Для вывода строки текста в ASP или PHP этот текст заключается в кавычки. Сложность заключается в том, что строка кода ASP <option value="rs_regions("regionID")">rs_regions("regionName")</option> (или эквивалент на PHP) не должна выводиться в браузер буквально. Предварительно сервер должен вычислить значения элементов массива $row_rs_regions['regionID'] и $row_rs_regions['regionName']. После того, как значения получены, обработчик ASP или PHP должен вывести результаты ("6" и "Africa" соответственно) в браузер. Но если не убирать кавычки для этих участков кода, обработчик ASP или PHP вместо того, чтобы вычислить и вывести полученные значения, просто выведет на страницу указанный код.
Для решения этой проблемы используется прием, называемый конкатенацией, который сводится к созданию текстовых строк путем объединения нескольких отдельных участков кода. В данном случае участками являются строковые литералы, например, "<option value=" и выражения, такие как rs_regions("regionID") и $row_rs_regions['regionID']. Эти участки объединяются при помощи знака & в ASP и при помощи точки (.) в PHP. Таким образом, ASP и PHP предварительно вычисляют значения выражений, и только после этого прикрепляют их к строке. В ColdFusion для того, чтобы различить строковые литералы и выражения, используется знак #. Благодаря этому отпадает необходимость в объединении элементов. Итак, в итоге, вне зависимости от применяемой технологии (ASP, ColdFusion или PHP), на страницу будет добавлен код <option value="6">Africa</option>.
В коде ASP и PHP есть еще одна сложность: кавычки используются по двум разным причинам. Как в большинстве языков программирования, в ASP и PHP кавычки употребляются для отделения строк от выражений. Все, что заключено в кавычки, обработчик ASP и PHP игнорирует и выводит на страницу без изменений. К сожалению, в данном случае, в строке, которую требуется вывести на страницу, присутствуют кавычки, поскольку правильная синтаксическая конструкция для параметра HTML-тега выглядит так: <option value="XYZ">. То есть при выводе кода на страницу вычисленное значение переменной rs_regions("regionID") и $row_rs_regions['regionID'] должно быть заключено в кавычки, например, <option value="6">. Но, когда обработчик кода ASP и PHP обнаруживает кавычки, идущие после параметра value, он интерпретирует их как конец строки, хотя, на самом деле, это не так. Чтобы обработчик различал ситуацию, когда кавычки следует вывести, а не и нтерпретировать, используются два набора кавычек (ASP), либо перед кавычками ставится обратный слэш (\) (PHP). Таким образом, в участке кода для ASP "<option value=""" & из трех кавычек, следующих подряд, первые и вторые кавычки соответствуют кавычкам, которые следует добавить в HTML-код, а третьи кавычки обозначают конец строки. Точно так же в участке кода для PHP "<option value=\"". Здесь \" указывает обработчику на то, что следует вывести пару кавычек на страницу, а следующие кавычки (после которых сразу идет точка) указывают на конец строки.
Сохраните файл, загрузите его на сервер, откройте и обратите внимание на список. В списке появился пункт Africa. В списке стран, отсортированном в алфавитном порядке, Africa идет первой. Это хорошо, но есть одна проблема – в списке пока только один пункт. Необходимо, чтобы сценарий ASP, ColdFusion или PHP для каждой записи из базы данных создавал отдельный тег <option>. Для этого используется программная конструкция, называемая циклом. В цикле один и тот же участок кода выполняется до тех пор, пока не будет выполнено заданное условие. В данном случае требуется создать цикл, выводящий строку с тегом <option> до тех пор, пока в таблице не закончатся записи.
- В участок кода, написанный в предыдущем шаге, добавьте строки, необходимые для создания цикла.
Для ASP:
<%
Do Until rs_regions.EOF
Response.Write("<option value=""" & rs_regions("regionID") & """>"
& rs_regions("regionName") & "</option>")
rs_regions.MoveNext
Loop
%>
Для ColdFusion:
<cfoutput query="rs_regions">
<option value="#rs_regions.regionID#">#rs_regions.regionName#</option>
</cfoutput>
Для PHP:
<?php
do
{
echo "<option value=\"".$row_rs_regions['regionID']."\">".$row_rs_regions
['regionName']."</option>";
}
while ($row_rs_regions = mysql_fetch_assoc($rs_regions));
?>
Пользователям ColdFusion достаточно добавить в тег <cfoutput> атрибут query, после чего цикл будет создан автоматически.
Пользователям ASP и PHP как обычно будет несколько сложнее. Для создания циклов здесь применяются конструкции Do Until (ASP) и do…while (PHP). Каждая конструкция содержит единственный параметр, который служит условием прерывания цикла. В обоих случаях условием является достижение конца набора записей (метка EOF в ASP означает конец файла – End of File). Следующая строка, как и прежде, служит для выведения на страницу элемента <option>. В PHP код, который обрабатывается в процессе выполнения цикла, заключен в фигурные скобки {}. В ASP для перехода к следующей записи используется метод MoveNext. Последняя строка Loop в коде ASP отправляет обработчик обратно к строке Do Until, а последняя строка с оператором while в коде PHP включает условие, при выполнении которого обработчик снова переходит к началу цикла (оператор do).
Если снова протестировать файл в браузере и щелкнуть на списке, появится перечень всех стран (см. рис. вверху следующей страницы).
- Только пользователям ASP и PHP. В режиме Code (Код) перейдите в к нижней части страницы и после закрывающего тега </html> добавьте следующий сценарий, который закрывает и уничтожает набор записей.
Для ASP:
<%
rs_regions.Close()
Set rs_regions = Nothing
%>
Для PHP:
<?php
mysql_free_result($rs_regions);
?>
В верхней части документа размещается сценарий, открывающий соединение и создающий набор записей. Этот набор записей хранится в памяти сервера. Он остается в памяти до тех пор, пока не будет отдано распоряжение о его удалении. Если не удалять данные, которые больше не используются, то через некоторое время сервер может оказаться перегруженным. Участок кода для ASP удаляет все записи из набора (rs_regions.Close()), после чего уничтожает объект набора записей (Set rs_regions = Nothing). Сценарий для PHP просто очищает от данных массив $rs_regions. Поскольку сценарий добавляется в самый конец страницы, набор записей уничтожается только после того, как обработана вся страница. Если уничтожить набор записей до заполнения списка содержащимися в наборе данными, из этого не выйдет ничего хорошего.
ColdFusion уничтожает набор записей автоматически в процессе обработки кода, заключенного между тегами <cfquery>, поэтому пользователям ColdFusion выполнять этот шаг не требуется.
Создание сценария для добавления данных
Форма полностью готова. Вся проблема в том, что пока не существует сценария, который будет добавлять данные формы в базу данных. В этом упражнении такой сценарий будет создан. Он будет выполнять те же действия, что и модель поведения, но при этом окажется несколько меньше и на этот раз будет понятен.
- Откройте документ admin_cp_insert_processor.asp в режиме Code (Код).
Файл не должен содержать никакого кода. Если код присутствует, следует его удалить.
Прежде, чем добавить сценарий, нужно подумать, какие действия он должен выполнять. Он должен извлекать данные, введенные в форму и вставлять их в виде новой записи в таблицу tbl_country. После этого он должен перевести пользователя на страницу admin_cp_master.asp.
- Вставьте код, создающий подключение к базе данных.
Для ASP:
<%
Dim dbConn
set dbConn = server.CreateObject("adodb.connection")
dbConn.open("newland")
%>
Для ColdFusion:
<cfquery name="rs_insertCountry" datasource="newland">
</cfquery>
Для PHP:
<?php
// Set up connection to MySQL
$host = "localhost";
$user = "[введите имя пользователя]";
$pwd = "[введите пароль]";
$dbConn = mysql_connect($host,$user,$pwd);
// Connect to newland_tours database
$database = "newland_tours";
mysql_select_db($database);
?>
Это практически тот же код, что использовался в предыдущем упражнении для создания набора записей, заполняющего список формы. Разница состоит в том, что в данном случае извлекать набор записей не требуется. Напротив, данные добавляются в базу.
Совет. Поскольку при подключении страниц к базе данных постоянно применяется один и тот же код, многие разработчики хранят шаблон кода для присоединения к базе данных в отдельном файле, который и включают в каждый документ. Это может быть специальный подключаемый файл, например, Application.cfm или обычный подключаемый файл, доступ к которому осуществляется при помощи функции, например, require_once() (PHP). Фактически именно это делает Dreamweaver в случае с ASP и PHP при "регистрации соединения". Другими словами, подключение conn_newland, которое применялось разработчиками ASP и PHP в других разделах книги, является обычным подключаемым файлом, содержащим основную информацию, необходимую для подключения к базе данных newland_tours.
- В пустой строке, которая осталась на предыдущем шаге, добавьте код, который вставляет данные в таблицу.
Для ASP:
dbConn.Execute("INSERT INTO tbl_country (region, countryName, population,
country_currency, description, imageURL, imageALT) VALUES ('" &
Request.Form("region") & "', '" & Request.Form("countryName") & "', '
" & Request.Form("population") & "', '" & Request.Form("country_currency")
& "', '" & Request.Form("description") & "', '" & Request.Form("imageURL") &
"', '" & Request.Form("imageALT") & "');")
Для ColdFusion:
INSERT INTO tbl_country
(region, countryName, population, country_currency, description, imageURL, imageALT)
VALUES
('#form.region#', '#form.countryName#', '#form.population#','#form.country_currency#',
'#form.description#', '#form.imageURL#',
'#form.imageALT#')
Для PHP:
$query_rs_insertCountry = "INSERT INTO tbl_country (region, countryname,
population, country_currency, description, imageURL, imageALT) VALUES
('".$_POST['region']."', '".$_POST['countryName']."',
'".$_POST['population']."', '".$_POST['country_currency']."',
'".$_POST['description']."', '".$_POST['imageURL']."',
'".$_POST['imageALT']."');";
$rs_insertCountry = mysql_query($query_rs_insertCountry);
Понять этот код окажется проще, если вспомнить синтаксис SQL-оператора INSERT:
INSERT INTO tbl_table
(field1,field2,field3)
VALUES
('value1', 'value2', 'value3')
В сценариях для ASP, ColdFusion и PHP содержатся SQL-операторы, использующие этот синтаксис. Но поскольку переменным присваиваются действующие значения, требуется дать серверу указание извлекать значения из соответствующих выражений перед добавлением в базу данных. Для этого в код ColdFusion вставляется несколько знаков #, а в код ASP и PHP – много знаков конкатенации.
Совет. Пользователи ASP и PHP могут воспользоваться таким преимуществом, как выделение кода цветом. Если в коде есть ошибка, его цвет, как правило, меняется. Это помогает находить ошибки еще до тестирования страницы. В коде для ASP функция Request.Form всегда должна быть выделена фиолетовым цветом, а имена полей формы – зеленым. Знаки &, используемые для конкатенации, должны выделяться синим оттенком. В коде для PHP строковые литералы (в том числе, запятые и одинарные кавычки) всегда выделяются красным. $_POST всегда выделяется голубым, а точки и квадратные скобки – темно-синим цветом.
Примечание. В коде для ASP и PHP применяются как обычные ("), так и одинарные (') кавычки, что может показаться непонятным. Содержимое, заключенное в двойные кавычки относится к ASP или PHP, это, к примеру, строковые литералы, которые должны добавляться в код страницы в неизменном виде. Данные, заключенные в одинарные кавычки, относятся к SQL-запросу и представляют значения, которые добавляются в базу данных.
- Добавьте код для перевода пользователя на основную страницу после добавления данных в базу.
Для ASP перед закрывающим %>:
Response.Redirect("admin_cp_master.asp")
Для ColdFusion:
<cflocation url="admin_cp_master.cfm">
Для PHP перед закрывающим ?>:
header("Location: admin_cp_master.php");
Поскольку при возникновении проблем ASP, ColdFusion и PHP выдают сообщение об ошибке, код перевода на основную страницу будет выполнен, только если данные успешно добавлены в базу.
Чтобы убедиться в работоспособности страницы, необходимо протестировать ее (в форму можно ввести любые данные). После добавления данных загрузится страница admin_cp_master.asp, создание которой еще не завершено. Но кроме списка на основной странице есть и другой способ убедиться в успешности добавления данных. Для этого следует загрузить страницу с профилями стран. Поскольку приложение предназначено для отображения всей информации о странах, содержащейся в базе данных, добавленная страна тоже окажется здесь. Неважно, если данные профиля вымышлены, – чуть позже будет создано приложение для удаления данных и для его тестирования потребуется одна или две выдуманные страны, так что сейчас следует оставить добавленную страну в базе данных.
Примечание. При заполнении формы не следует использовать апострофы, так как в этом случае появится сообщение об ошибке. Эта проблема будет решена позже.
Примечание. Пока в папку images не будет загружено изображение с тем же именем, что и указанное в форме, ссылка на изображение не будет работать.
Создание основной страницы
Для обновления и удаления данных необходимы основная и детальная страницы, поскольку для удаления или обновления данных пользователи должны выбрать страну. В этом упражнении будет создана несложная основная страница, на которой будет отображаться таблица, в каждой строке которой присутствует название страны, ссылка для изменения информации о ней и ссылка для удаления страны. Как и прежде, каждая из этих ссылок содержит параметр URL-адреса, указывающий на то, какая именно страна была выбрана.
- Откройте документ admin_cp_master.asp и переключитесь в режим Code (Код).
Как обычно, перед тем, как вводить данные на странице, будет создан набор записей. Чтобы написать сценарий, формирующий набор записей, необходимо использовать режим Code (Код).
- Между кодом серверной модели поведения Restrict Access (Ограниченный доступ) и началом документа (непосредственно перед тегом <!DOCTYPE>), введите код, необходимый для создания набора записей ("rs_countries"), который извлекает из каждой записи в таблице tbl_country имя и идентификатор страны.
Для ASP:
<%
Dim dbConn
Dim rs_countries
set dbConn = Server.CreateObject("adodb.connection")
dbConn.open("newland")
Set rs_countries = dbConn.Execute("SELECT countryID, countryName FROM
tbl_country ORDER BY countryName ASC")
%>
Для ColdFusion:
<cfquery name="rs_countries" datasource="newland">
SELECT countryID, countryName FROM tbl_country ORDER BY countryName ASC
</cfquery>
Для PHP:
<?php
// Set up connection to MySQL
$host = "localhost";
$user = "[введите имя пользователя]";
$pwd = "[введите пароль]";
$dbConn = mysql_connect($host,$user,$pwd);
// Connect to newland_tours database
$database = "newland_tours";
mysql_select_db($database);
$query_rs_countries = "SELECT countryID, countryName FROM tbl_country ORDER
BY countryName ASC";
$rs_countries = mysql_query($query_rs_countries);
$row_rs_countries = mysql_fetch_assoc($rs_countries);
?>
За исключением деталей в операторе SQL, приведенный код абсолютно идентичен коду, использованному ранее, так что здесь все должно быть понятно. Смысл запроса понять тоже несложно: он извлекает из базы данные с названиями стран и их идентификаторами и сортирует их по алфавиту (по названия).
- Только пользователям ASP и ColdFusion. Добавьте в конец документа код, предназначенный для закрытия и уничтожения набора записей.
Для ASP:
<%
rs_countries.Close()
Set rs_countries = Nothing
%>
Для PHP:
<?php
mysql_free_result($rs_countries);
?>
Этот код, как и раньше, очищает память сервера от лишних данных.
- В режиме Design (Дизайн) введите на странице две строки текста:
Select a country to modify or delete. Выберите страну, которую нужно изменить или удалить.
Caution: Deleting is instant and permanent. Внимание! Удаление производится сразу же и отменить его невозможно.
Как и прежде, четкие рекомендации несомненно повышают эффективность использования приложений.
- В режиме Code (Код) под созданным на предыдущем шаге абзацем поместите код новой таблицы, состоящей из одной строки и трех столб-цов.
<table width="98%" border="1" cellpadding="3" cellspacing="0">
<tr>
<td>XX</td>
<td>XX</td>
<td>XX</td>
</tr>
</table>
Этот код формирует каркас таблицы. По завершении страницы данные в таблице будут генерироваться автоматически, и каждая запись будет помещена в отдельную строку. Поскольку точное количество строк определить невозможно, будет создан цикл, создающий отдельную строку для каждой записи.
- Введите код для создания цикла, внутри которого заключен тег <tr>. Участки кода должны располагаться перед открывающим тегом <tr> и после закрывающего тега </tr>.
Для ASP:
<%
Do Until rs_countries.EOF
%>
<tr>
<td>XX</td>
<td>XX</td>
<td>XX</td>
</tr>
<%
rs_countries.MoveNext()
Loop
%>
Для ColdFusion:
<cfoutput query="rs_countries">
<tr>
<td>XX</td>
<td>XX</td>
<td>XX</td>
</tr>
</cfoutput>
Для PHP:
<?php
do {
?>
<tr>
<td>XX</td>
<td>XX</td>
<td>XX</td>
</tr>
<?php
}
while ($row_rs_countries = mysql_fetch_assoc($rs_countries));
?>
На этом шаге без использования модели поведения Dreamweaver создается повторяющаяся область. Несмотря на незначительные различия в коде все три сценария выполняются по единой логике. В каждом сценарии перед повторяющимся участком и после него (область, ограниченная тегами <tr>) добавляется код. В каждом определяется набор записей и создается цикл, который прерывается только тогда, когда заканчиваются записи в наборе. В ASP для проверки этого условия применяется функция EOF, в ColdFusion цикл создается автоматически, когда внутри тега <cfoutput> определяется запрос (параметр query), а в PHP применяется функция mysql_fetch_assoc().
На следующем шаге в ячейки таблицы будет добавлено содержимое, состоящее из смешанного кода HTML и ASP, ColdFusion или PHP.
- Между тегами <td>, поместите приведенный ниже HTML-код.
<td>Country Name</td>
<td><a href="admin_cp_update.php?countryID=CountryID">Modify this country’s profile</a></td>
<td><a href="admin_cp_delete_processor.php?countryID=CountryID">Delete
</a></td>
Поскольку код представляет собой статический HTML, он подходит как для ASP, так и для ColdFusion и PHP (за исключением расширений файлов в атрибуте href — для ColdFusion и PHP соответственно .cfm и .php вместо .asp). Вместо динамического кода применяются заменители, что дает возможность проверить правильность написания HTML.
- Замените статический код во всех трех ячейках динамическими данными, как показано ниже.
Для ASP:
<td><%=rs_countries("countryName")%></td>
<td><a href="admin_cp_update.asp?countryID=<%=rs_countries("countryID")%>">
Modify this country’s profile</a></td>
<td><a href="admin_cp_delete_processor.asp?countryID=<
%=rs_countries("countryID")%>">Delete</a></td>
Для ColdFusion:
<td>#countryName#</td>
<td><a href="admin_cp_update.cfm?countryID=#countryID#">Modify this
country’s profile</a></td>
<td><a href="admin_cp_delete_processor.cfm?countryID=#countryID#">Delete</a></td>
Для PHP:
<td><?php echo $row_rs_countries['countryName']; ?></td>
<td><a href="admin_cp_update.php?countryID=<?php echo
$row_rs_countries['countryID']; ?>">Modify this country’s profile</a></td>
<td><a href="admin_cp_delete_processor.php?countryID=<?php echo
$row_rs_countries['countryID']; ?>">Delete</a></td>
В книге встречалось немало кода ASP, ColdFusion и PHP, выводящего данные на страницу, так что чтение приведенных сценариев не должно вызывать затруднений, особенно если вспомнить, что в ASP код <%= означает <%Response.Write().
- Сохраните файл, загрузите его на сервер и протестируйте в браузере.
На страницу выводится таблица, количество строк в которой равно количеству записей в наборе. Если навести указатель мыши на одну из ссылок, появится не только URL-адрес, но и прикрепленный к нему параметр countryID, соответствующий выбранной стране.
Закройте файл admin_cp_master.asp.
Создание детальной страницы для обновления записей
Итак, основная страница готова, осталось создать детальную страницу. В этом упражнении будет создана детальная страница, используемая для обновления записей. При удалении записей достаточно, не загружая дополнительной информации, выбрать страну, которую следует удалить. Поэтому для удаления записей детальная страница не нужна.
Страница для обновления окажется похожей на страницу для добавления новых стран. Все дело в том, что на новой странице будет использована измененная версия той же самой формы. Единственная разница заключается в том, что на странице для обновления поля формы содержат данные. И, конечно, после того, как пользователь внесет изменения в форму, вместо добавления новой записи будут модифицированы существующие.
- Откройте документ admin_cp_insert.asp. В меню File (Файл) выполните команду Save As (Сохранить как) и сохраните его как admin_cp_ update.asp (заменив исходный файл). Поменяйте заголовок на странице на Update a Country Profile, а заголовок документа (поле Title [Заголовок] на панели инструментов) – на Newland Tours Admin: Update a Country Profile.
Таким образом, готовая форма, а также набор записей rs_regions, извлекающий из базы все регионы и их идентификаторы и заполняющий раскрывающийся список Region (Регион), полностью скопированы вместе со страницей.
С помощью этого приема следует учитывать все изменения, которые требуется внести на страницу. В данном случае каждое из полей формы должно заполняться данными, извлеченными из записи для выбранной страны. Для реализации таких изменений требуется создать новый набор записей. Атрибут action тега <form> должен указывать на страницу admin_cp_update_processor.asp, а не на admin_cp_insert_processor.asp, которая добавляет запись в базу данных. Помимо этого, необходимо переименовать саму форму.
- В режиме Code (Код) найдите открывающий тег <form> и задайте для него следующие атрибуты.
action (ASP):
admin_cp_update_processor.asp?countryID=<%=Request.QueryString("countryID")%>
action (ColdFusion):
admin_cp_update_processor.cfm?countryID=<cfoutput>#url.countryID#</cfoutput>
action (PHP):
admin_cp_update_processor.php?countryID=<?php echo $_GET['countryID']; ?>
method: post (без изменений)
name: frm_updateProfile
id: frm_updateProfile
Об этих изменениях легко забыть, поэтому лучше всего внести их сразу.
Атрибут action требует пояснения. Как известно, при загрузке детальной страницы в состав URL-адреса добавляется переменная countryID, переданная с основной страницы. Ориентируясь на эту переменную, запрос извлекает данные той страны, которую выбрал пользователь. На этот раз, взаимодействующий с базой данных сценарий находится на другой странице: admin_cp_update_processor.asp. Однако и этому сценарию необходимо определить страну, данные которой требуется обновить. При помощи строки запроса или параметра URL-адреса, прикрепленного к атрибуту action формы, переменная передается на страницу со сценарием.
Совет. Другой способ передачи данных, предназначенных только для чтения, при помощи формы – это применение скрытых полей.
- Создайте новый набор записей rs_countryDetail, извлекающий из базы всю информацию о стране, выбранной пользователем на основной странице.
Для ASP внутри блока dbConn в новой строке, расположенной под строкой, начинающейся с кода Set rs_regions =, следует добавить следующий код:
Set rs_countryDetail = dbConn.Execute("SELECT * FROM tbl_country INNER JOIN
tbl_region ON tbl_region.regionID=tbl_country.region WHERE
tbl_country.countryID=" & Request.QueryString("countryID"))
Для ColdFusion:
<cfquery name="rs_countryDetail" datasource="newland">
SELECT *
FROM tbl_country
INNER JOIN tbl_region ON tbl_region.regionID=tbl_country.region
WHERE tbl_country.countryID=#url.countryID#
</cfquery>
Для PHP в конце блока запроса, созданного ранее, прямо перед закрывающим ?> следует ввести следующий код:
$query_rs_countryDetail = "SELECT * FROM tbl_country INNER JOIN tbl_region ON
tbl_region.regionID=tbl_country.region WHERE tbl_country.countryID=".$_GET['countryID'];
$rs_countryDetail = mysql_query($query_rs_countryDetail);
$row_rs_countryDetail = mysql_fetch_assoc($rs_countryDetail);
И снова основная часть кода окажется знакомой. Однако будет нелишним разобрать SQL-оператор. Как известно, в таблице tbl_country содержится большая часть информации о странах. Исключение составляют названия регионов, которые хранятся в отдельной таблице, которая, в свою очередь, связана с таблицей tbl_country. Поэтому для извлечения названия региона применяется ключевое слово JOIN. Также следует обратить внимание на то, что SQL-оператор извлекает не все профили стран, а только один, соответствующий идентификатору, сохраненному в переменной строки запроса (или URL-адреса) после того, как пользователь выбрал страну на основной странице.
Примечание. Пользователям ASP желательно также объявить переменную rs_countryDetail в верхней части документа при помощи оператора Dim. Код будет работать и без этого, но объявление всех переменных никогда не бывает лишним.
Итак, вся нужная информация о выбранной стране извлечена из базы данных. Осталось заполнить форму полученными данными. После того, как пользователь нажмет кнопку Submit, сценарий заменит существующую в базе запись данными, содержащимися в форме. Сейчас необходимо добавить данные в соответствующие элементы формы в качестве значений по умолчанию.
- Пользователям ASP и PHP. В нижней строке документа добавьте код, необходимый для закрытия и уничтожения набора записей.
Для ASP:
<%
rs_countryDetail.Close()
Set rs_countryDetail = Nothing
%>
Для PHP:
<?php
mysql_free_result($rs_countryDetail);
?>
Как и раньше, этот код освобождает память севера после того, как набор записей становится ненужным.
- В режиме Code (Код) найдите элемент формы countryName. Присвойте ему следующее значение:
value="XX"
Это статический HTML-код, поэтому он одинаков для ASP, ColdFusion и PHP. Если в этот момент протестировать страницу, в поле Country Name появятся буквыXX.
Примечание. При тестировании страницы во время урока следует помнить, что для ее корректной работы требуется параметр URL-адреса. Если его нет (например, при нажатии клавиши (F12) для проверки страницы параметру неоткуда взяться) появится сообщение об ошибке. Для решения этой проблемы следует после URL-адреса, содержащегося в адресной строке, добавить код ?countryID=3, после чего нажать (Enter)/(Return). С добавленным параметром на странице будет достаточно информации для выполнения запроса, и сообщение об ошибке пропадет.
- Вместо заменителя XX добавьте в код следующие динамические значения:
Для ASP:
<%=rs_countryDetail("countryName")%>
Для ColdFusion:
<cfoutput>#rs_countryDetail.countryName#</cfoutput>
Для PHP:
<?php echo $row_rs_countryDetail['countryName']; ?>
Благодаря этому коду при загрузке страницы в поле будет содержаться название выбранной страны. Если пользователь изменит его, название в базе данных будет обновлено. Если пользователь оставит его без изменений, значение в базе данных все равно будет заменено на значение поля, но поскольку они одинаковы, ничего не изменится.
- На основе приведенной ниже информации (в виде псевдокода), используя правильный синтаксис ASP, ColdFusion или PHP, повторите шаги 5 и 6 для каждого из оставшихся текстовых полей, предназначенных для вывода на странице численности населения, денежной единицы и URL для картинки.
Population: rs_countryDetail.population
Country Currency: rs_countryDetail.country_currency
Image URL: rs_countryDetail.imageURL
Настройка текстовых полей завершена. Осталось разобраться с текстовыми областями.
- Между двумя наборами открывающих и закрывающих тегов <textarea></textarea> (содержащих описание и альтернативный текст к изображению) поместите код, по умолчанию добавляющий в поля динамические значения.
Для ASP:
<%=rs_countryDetail("description")%>
<%=rs_countryDetail("imageALT")%>
Для ColdFusion:
<cfoutput>#rs_countryDetail.description#</cfoutput>
<cfoutput>#rs_countryDetail.imageALT#</cfoutput>
Для PHP:
<?php echo $row_rs_countryDetail['description']; ?>
<?php echo $row_rs_countryDetail['imageALT']; ?>
Синтаксис для текстового поля отличается от синтаксиса других элементов формы. Значение не присваивается атрибуту value, а помещается между открывающим и закрывающим тегами >textarea>. В ASP, ColdFusion и PHP применяется один и тот же синтаксис текстового поля.
После этого следует сохранить файл, загрузить его на сервер и протестировать.
- На панели Site (Сайт) выберите файл admin_cp_master.asp, введите данные доступа и выберите любую страну, кроме Африки.
Загрузится форма для обновления записи, наполненная значениями по умолчанию. Однако если была выбрана какая-либо страна (но не в Африке), возникнет одна проблема: в качестве региона страны будет указана Африка. Происходит это потому, что элементы в раскрывающемся списке формируются на основе другого набора записей (rs_regions), а Африка является первым элементом в списке и отображается по умолчанию. Можно изменить содержимое списка так, чтобы в нем отображались данные из набора записей rs_countryDetail, но поскольку в нем содержится только одна запись, список будет состоять из одного элемента, и изменение региона окажется невозможным. И хотя маловероятно, что Италия переместится в Южную Америку, следует сохранить возможность изменять регионы на случай, если кто-то в компании Newland Tours решит изменить принципы выделения регионов, к примеру, разделить Европу на две части – Северную и Южную Европу.
Можно оставить все как есть, и сотрудники должны будут выбирать в списке правильный регион при каждом обновлении записи, однако, это намного снижает эффективность и удобство приложения. Рано или поздно, сотрудник забудет изменить регион, и в результате, одна из стран, например, Мексика, окажется в Африке. Последствия этой ошибки могут оказаться довольно значительными. Поскольку на сайте есть возможность поиска путешествий по региону, посетители не смогут найти Мексику в Центральной Америке. К тому же, если на сайте будет сказано, что Мексика находится в Африке, уровень доверия к компании заметно снизится. Так что решить подобную проблему очень важно.
Но решение проблемы требует определенных действий. К моменту, когда код для отображения элементов списка в браузере (после выполнения обработчиком ASP, ColdFusion или PHP) выглядит так:
<select name="region" id="region">
<option value="6">Africa</option>
<option value="8">America, Central</option>
<option value="1">America, North</option>
<option value="2">America, South</option>
<option value="7"> Asia, Central</option>
<option value="4">Asia, East</option>
<option value="5">Asia, West</option>
<option value="3">Europe</option>
</select>
Не секрет, что у элемента <select> есть дополнительный атрибут selected, указывающий элемент, который выбран в списке по умолчанию. В част-ности, в приведенном ниже списке по умолчанию будет выбран элемент для Центральной Азии (Asia, Central) (полужирным шрифтом атрибут выделен для того, чтобы его легче было найти).
<select name="region" id="region">
<option value="6">Africa</option>
<option value="8">America, Central</option>
<option value="1">America, North</option>
<option value="2">America, South</option>
<option value="7" selected>Asia, Central</option>
<option value="4">Asia, East</option>
<option value="5">Asia, West</option>
<option value="3">Europe</option>
</select>
Таким образом, все, что требуется – это добавить атрибут selected в тег региона, соответствующего выбранной стране. Сложность заключается в том, что список не является статическим, а формируется при помощи цикла, который добавляет отдельную строку с тегом <option> для каждой записи из набора записей rs_regions.
Тем не менее, решение проблемы существует: при каждом повторе цикла, заполняющего список, сценарий будет проверять, соответствует ли текущее значение параметра regionID региону из набора записей rs_countryDetail. Если ответ положительный, сценарий добавит в код слово selected. В противном случае будет выполняться дальше. Так выглядит псевдокод сценария:
Выполнять приведенный ниже код до тех пор, пока в наборе rs_regions не
закончатся записи
Вывести тег <option>, в качестве значения параметра value используя
rs_regions.regionID, а в качестве надписи – значение
rs_regions.regionName
Если текущее значение rs_regions.regionID равно значению
Еrs_countryDetail.region
Вывести в код слово "selected"
Конец условия
Вернуться в начало цикла и начать следующую итерацию
Описание получилось довольно длинным, тем не менее, если понять принцип, создание кода окажется совсем не сложным.
- Внесите в код между открывающим и закрывающим тегами <select></select> следующие изменения.
Для ASP:
<%
Do Until rs_regions.EOF
%>
<option value="<%=rs_regions("regionID")%>"
<%
If rs_regions("regionID")=rs_countryDetail("region") Then
Response.Write("selected")
End If
%>
><%=rs_regions("regionName")%></option>
<%
rs_regions.MoveNext
Loop
%>
Для ColdFusion:
<cfoutput query="rs_regions">
<option value="#regionID#"<cfif (rs_regions.regionID EQ rs_countryDetail.region)>
selected</cfif>>#regionName#</option>
</cfoutput>
Для PHP:
<?php
do {
?>
<option value="<?php echo $row_rs_regions['regionID']; ?>"
<?php
if ($row_rs_regions['regionID'] == $row_rs_countryDetail['region']) {
echo " selected";
}
?>
><?php echo $row_rs_regions['regionName']; ?></option>
<?php
}
while ($row_rs_regions = mysql_fetch_assoc($rs_regions));
?>
Начало и конец тега <option> выделены для облегчения чтения кода. Особое внимание следует обратить на закрывающую тег угловую скобку, которая может показаться лишней в коде ASP, ColdFusion или PHP (кстати, эта угловая скобка во всех трех случаях должна быть выделена оранжевым цветом). Причина разбиения тега заключается в том, что слово selected должно выводиться перед закрывающей скобкой. Таким образом, она располагается справа от условной конструкции, а остальная часть тега расположена слева.
Важно уделить внимание расположению пробелов в коде: перед словом selected обязательно должен стоять пробел, чтобы оно не располагалось вплотную к атрибуту value="X", расположенному слева.
Пользователи ASP и PHP могут заметить, что в этот раз для вывода тега <option> применяется не тот синтаксис, что в начале урока при создании списка в форме для добавления стран. В данном случае вместо целого блока кода ASP или PHP, состоящего из нескольких элементов, из которых складывается строка с тегом <option>, используются несколько участков кода, разделенных разделителями ASP (<%…%>) или PHP (<?…?>). Это изменение не ухудшает выполнение кода. Главное отличие состоит в том, что отделение условной конструкции таким образом облегчает понимание кода.
- Сохраните файл и загрузите его на сервер. При тестировании страницы admin_cp_master.asp снова выберите любую страну, кроме Африки.
По умолчанию в списке отобразится правильный регион, и в то же время будут доступны все остальные.
Форма для обновления готова, и теперь все самое трудное позади.
Создание сценария для обновления записей
По сравнению с предыдущим упражнением последние два покажутся слишком легкими. Сначала будет создана страница, содержащая сценарий обновления записи.
- Откройте файл admin_cp_update_processor.asp и в режиме Code (Код) удалите все его содержимое.
Так же, как и в прошлый раз, страница создается с нуля, так как содержит только сценарий.
- Введите код, создающий соединение с базой данных.
Для ASP:
<%
Dim dbConn
set dbConn = server.CreateObject("adodb.connection")
dbConn.open("newland")
%>
Для ColdFusion:
<cfquery name="update_cp" datasource="newland">
</cfquery>
Для PHP:
<?php
// Set up connection to MySQL
$host = "localhost";
$user = "[введите имя пользователя]";
$pwd = "[введите пароль]";
$dbConn = mysql_connect($host,$user,$pwd);
// Connect to newland_tours database
$database = "newland_tours";
mysql_select_db($database);
?>
После создания соединения можно сформировать SQL-запрос.
- В пустой строке, которая осталась на предыдущем шаге, введите код, необходимый для обновления базы данных.
Для ASP (весь код в одной строке):
dbConn.Execute("UPDATE tbl_country SET region='" & Request.Form("region") &
"', countryName='" &
Request.Form("countryName") & "', population='" &
Request.Form("population") & "', country_currency='" &
Request.Form("country_currency") & "', description='" &
Request.Form("description") & "', imageURL='" & Request.Form("imageURL")
& "', imageALT='" & Request.Form("imageALT") & "' WHERE countryID=" &
Request.QueryString("countryID"))
Для ColdFusion (не запрещается разбивать код на строки):
UPDATE tbl_country
SET region='#form.region#',
countryName='#form.countryName#',
population='#form.population#',
country_currency='#form.country_currency#',
description='#form.description#',
imageURL='#form.imageURL#',
imageALT='#form.imageALT#'
WHERE countryID=#URL.countryID#
Для PHP:
//Update database
$query_updateCountry = "UPDATE tbl_country SET region='".$_POST['region']."',
countryName='".$_POST['countryName']."', population='".$_POST['population']."',
country_currency='".$_POST['country_currency']."',
description='".$_POST['description']."', imageURL='".$_POST['imageURL']."
', imageALT='".$_POST['imageALT']."' WHERE countryID=".$_GET['countryID'];
$updateCountry = mysql_query($query_updateCountry);
И вновь выделение цветом облегчает работу с кодом, особенно при использовании ASP или PHP. Важно убедиться в том, чтобы в конце кода перед предложением WHERE случайно не была добавлена запятая.
- Добавьте на страницу код, необходимый для перемещения пользователя на основную страницу.
Для ASP (строка над закрывающим элементом %>):
Response.Redirect("admin_cp_master.asp")
Для ColdFusion (строка после закрывающего тега </cfquery>):
<cflocation url="admin_cp_master.cfm">
Для PHP (перед закрывающим тегом ?>):
header("Location: admin_cp_master.php");
Код переводит пользователя на основную страницу, где он может убедиться в том, что изменения успешно сохранены.
- Сохраните файл и загрузите его на сервер. Запустите основную страницу (F12), выберите страну, измените информацию о ней и нажмите кнопку Submit. Снова запустите страницу для обновления той же страны, чтобы восстановить первоначальное значение.
В результате создание сценария для обновления завершено. Следует отметить, что он замечательно работает, – по крайней мере, для некото рых стран. Но если с помощью ASP попытаться изменить данные для Аргентины, Таиланда, Индии и некоторых других стран, появится сообщение об ошибке. Причина ее возникновения состоит в том, что в тексте описаний (description) или в альтернативном тексте к изображению (imageALT) могут содержаться знаки апострофа, которые непонятны обработчику кода SQL (PHP и ColdFusion автоматически пропускают этот символ, поэтому в случае с ColdFusion и PHP ошибки не возникнет).
Для решения этой проблемы следует удалить из текста все апострофы. Но это решение не самое лучшее, поскольку синтаксическая конструкция для представления текста будет неверной.
В последующих шагах на страницу будет добавлен код, который перед добавлением измененного текста в базу данных автоматически заменяет знаки апострофа соответствующей последовательностью символов ('). SQL проигнорирует последовательность символов (что и требуется), а при выведении данных на странице браузер преобразует код последовательности обратно в знак апострофа. Ни конечный пользователь, ни сотрудник компании, управляющий контентом сайта Newland Tours, не будут даже знать о том, что происходит в коде. Единственное заметное изменение (только при использовании ASP) заключается в том, что в базе данных вместо апострофов появятся последовательности символов '.
- Только пользователям ASP. Снова откройте страницу admin_cp_update_processor.asp.
Сценарий, предназначенный для поиска и замены, будет размещаться в самом начале страницы, а, следовательно, будет выполняться до обновления.
- Только пользователям ASP. В верхней части страницы между открывающим элементом <% и строкой Dim dbConn добавьте следующий сценарий:
Dim description_fixed, imageALT_fixed
description_fixed = Replace(Request.Form("description"),"'","'")
imageALT_fixed = Replace(Request.Form("imageALT"),"'","'")
ASP содержит встроенную функцию Replace(), в которой указывается:
- переменная, в которой следует вести поиск,
- строка, которую нужно найти, и строка, на которую следует заменить найденную.
Если сейчас протестировать файл, то сообщение об ошибке появится все равно, поскольку, несмотря на наличие переменных, в которых хранятся значения двух текстовых областей, содержимое этих переменныхне вставлено в форму. Для этого следует внести изменения в SQL код.
- Только пользователям ASP. Замените две переменные в SQL-запросе, так, чтобы оператором UPDATE использовались их исправленные версии.
Следует заменить код description='" & Request.Form("description") & "' на description='" & description_fixed & "', а imageALT='" & Request.Form("imageALT") & "' на imageALT='" & imageALT_fixed & "'.
После завершения этого шага нужно обратить внимание на то, что после участка кода с переменной description стоит запятая, а после участка кода imageALT (который является последним) запятой нет.
- Только пользователям ASP. Сохраните страницу, загрузите ее на сервер и протестируйте.
На этот раз обновляются все записи даже для стран, в описаниях и альтернативных текстах которых содержатся апострофы.
Поскольку способ решения проблемы апострофов теперь известен, следует устранить ее и на странице для добавления стран.
- Только пользователям ASP. Откройте страницу admin_cp_insert_ processor.asp и устраните описанную выше проблему.
В код требуется внести те же изменения, что и на страницу admin_cp_update_processor.asp. SQL запросы страниц различаются, однако код, который необходимо заменить, остался прежним.
Создание сценария для удаления записей
Написать сценарий, удаляющий профили стран, гораздо проще, чем сценарий для обновления. Как и прежде, доступ к сценарию пользователи получают с основной страницы, создание которой уже завершено, поэтому осталось только добавить сценарий, удаляющий записи из базы данных.
- Откройте файл admin_cp_delete_processor.asp и в режиме Code (Код) удалите все его содержимое.
Теперь страница будет содержать только короткий сценарий и код, переводящий пользователя на основную страницу, так что HTML кода на ней быть не должно.
- Добавьте на страницу код, предназначенный для соединения с базой данных.
Для ASP:
<%
Dim dbConn
set dbConn = server.CreateObject("adodb.connection")
dbConn.open("newland")
%>
Для ColdFusion:
<cfquery name="delete_country" datasource="newland">
</cfquery>
Для PHP:
<?php
// Set up connection to MySQL
$host = "localhost";
$user = "[введите имя пользователя]";
$pwd = "[введите пароль]";
$dbConn = mysql_connect($host,$user,$pwd);
// Connect to newland_tours database
$database = "newland_tours";
mysql_select_db($database);
?>
Далее следует добавить код, отправляющий SQL запрос.
- В пустой строке, оставленной в предыдущем шаге, добавьте код, удаляющий выбранную запись, на которую указывает параметр URL - адреса.
Для ASP (весь код в одну строку):
dbConn.Execute("DELETE FROM tbl_country WHERE countryID=" &
Request.QueryString("countryID"))
Для ColdFusion (разрешено разбивать код на строки):
DELETE FROM tbl_country
WHERE countryID=#URL.countryID#
Для PHP:
$query_deleteCountry = "DELETE FROM tbl_country WHERE
countryID=".$_GET['countryID'];
$deleteCountry = mysql_query($query_deleteCountry);
При использовании оператора DELETE не требуется указывать каждое поле, которое необходимо удалить, поскольку удаляются все поля записи. Это облегчает процесс написания кода. Но если при этом случайно забыть о предложении WHERE и не добавить его в код, то будет удалена вся таблица.
- Добавьте на страницу код, необходимый для перехода пользователя на основную страницу.
Для ASP (строка над закрывающим элементом %>):
Response.Redirect("admin_cp_master.asp")
Для ColdFusion (строка после закрывающего тега </cfquery>):
<cflocation url="admin_cp_master.cfm">
Для PHP (перед закрывающим тегом ?>):
header("Location: admin_cp_master.php");
Этот код переводит пользователя на основную страницу, где он может убедиться в том, что удаление прошло успешно.
- Сохраните файл и загрузите его на сервер. Нажмите клавишу (F12), чтобы открыть страницу admin_cp_master.asp в браузере и удалите страну, добавленную в одном из предыдущих упражнений урока.
Как и написано в инструкции, удаление производится сразу же, и отменить его невозможно – не поможет даже кнопка Back (Назад).
Что дальше
После создания системы управления контентом CMS завершается и обучающий курс этой книги. Обучение программированию и разработке динамичных веб-сайтов представляет собой не слишком тривиальную задачу, которую трудно реализовать в полной мере в рамках одного пособия. Однако эта книга дает представление об основах разработки динамических приложений, достаточных для самостоятельной разработки сайтов, управляемых базами данных.
Поскольку сайт и база данных Newland Tours создавались специально в учебных целях, их рекомендуется использовать для дополнительной практики. Например, для улучшения навыков создания CMS можно создать приложение для управления описаниями путешествий.
Для перехода к практической деятельности целесообразно просмотреть сайты, поддержкой которых вы занимаетесь, и попытаться определить способы повышения их эффективности и облегчения управления при добавлении динамических сценариев. Во время выполнения упражнений книги было написано немало кода ASP, ColdFusion и PHP, и, скорее всего, полученного опыта вполне достаточно для успешного устранения проблем. Решение более сложных задач описано в других книгах или учебных курсах по ASP, ColdFusion или PHP, которые можно найти в книжных магазинах или в сети. Нельзя не отметить, что после создания сайта Newland Tours работать с другими учебными материалами окажется намного проще. |