Внимание! Для работы с этим курсом необходимы учебные файлы, которые Вы можете загрузить здесь.
В уроке 7 была создана большая часть приложения для расчета стоимости турпоездки. Для проверки работоспособности приложения осталось только ввести реальные данные. Эти данные хранятся в базе данных newland_tours (которая обрабатывается программой Access или MySQL – в зависимости от выбранной серверной модели). В этом уроке будут продемонстрированы способы извлечения, обработки и отображения данных из базы, и на этом работу над приложением можно считать завершенной.
Помимо ручного кодирования при работе с базой данных в уроке применяются некоторые визуальные функции Dreamweaver. Например, для заполнения раскрывающегося списка формы на странице tourprice.asp динамическими данными используется простое диалоговое окно.
Часть времени, необходимая для выполнения урока, уделяется работе с SQL и созданию запросов. В частности, демонстрируется фильтрация SQL-запросов при помощи динамических данных, что позволяет использовать по-настоящему индивидуальный подход к каждому пользователю.
К концу урока на страницах tourprice.asp и tourprice_processor.asp будет такое количество серверного кода, что его будет трудно читать. Для облегчения работы со сценариями (и документами в целом) будут использованы комментарии, поясняющие те или иные строки кода.
Рис. 1.1.
К концу этого урока приложение для расчета стоимости путешествий будет использовать данные, динамически извлекаемые из базы данных
Создание динамически наполняемого списка
Как известно из урока 7, после заполнения формы на странице tourprice.asp серверу пересылаются три значения: число взрослых и детей, а также виртуальная стоимость турпоездки. После этого сценарий ASP, ColdFusion или PHP перемножает ее на количество взрослых и детей, а затем складывает полученные значения и помещает итоговую сумму в HTML-код.
Для замены умозрительных значений реальными потребуется кое-что сделать. Для начала следует заполнить раскрывающийся список формы реальными данными. Как известно, раскрывающийся список может пересылать только одно значение, в то время как требуется два: стоимость турпоездки для взрослых и для детей. Таким образом, вместо стоимости будет отправляться уникальный идентификатор путешествия. На странице tourprice_processor.asp по этому идентификатору формируется запрос на получение стоимости тура для взрослых и для детей, после чего он направляется в базу данных. На основе полученных данных рассчитывается итоговая стоимость, которая и выводится на странице.
Теперь следует более детально рассмотреть раскрывающийся список формы. Очевидно, что каждая опция в списке должна иметь два атрибута: надпись (label) (предназначена для просмотра посетителями и не пересылаемая после заполнения формы) и данные (data) (информация, которая пересылается в виде значения переменной формы). Несложно догадаться, что надпись должна включать название тура. Поскольку в базе данных названиям туров выделено отдельное поле, с их извлечением проблем не возникнет. В качестве пересылаемого значения, как говорилось ранее, должен выступать уникальный идентификатор путешествия. В данном случае это будет первичный ключ таблицы tbl_tours. Из предыдущего урока известно, что почти каждая таблица в базе данных содержит поле для первичного ключа, в каждой строке которого содержится уникальное значение (как правило, оно автоматически увеличивается на единицу при добавлении новой строки). Итак, в качестве названия для опции списка должно быть название тура, а в качестве данных – первич ный ключ tourID. Оба значения содержатся в таблице tbl_tours.
- Откройте страницу tourprice.asp. На панели Bindings (Привязки) щелкните на кнопке New Binding (Создать привязку) ("+") и выберите в списке пункт Recordset (Query) (Набор записей [Запрос]).
Прежде чем настроить опции списка, следует сформировать набор записей, позволяющий прикрепить к форме нужные данные. В первую очередь, при работе с данными из базы данных всегда создается набор записей.
- В поле Name (Имя) диалогового окна Recordset (Набор записей) введите имя "rs_tourprices". В раскрывающемся списке Connection (Соединение) выберите опцию conn_newland, а в списке Table (Таблица) – опцию tbl_tours. В разделе Columns (Столбцы) активируйте переключатель Selected (Выделенные), а затем, удерживая нажатой клавишу (Ctrl) (Windows) или (Control) (Macintosh), выделите пункты tourID и tourName.
Примечание. Пользователям ColdFusion в поле со списком Connection (Соединение) следует выбрать вариант newland. Для подключения к базе данных ColdFusion не использует файл соединения conn_newland, подобно ASP или PHP. Другими словами, в то время как ASP и PHP для соединения с DSN newland сначала ссылаются на файл conn_newland.asp/php, ColdFusion подключается напрямую к DSN.
Теперь в диалоговом окне указана большая часть информации, необходимая для заполнения списка. После подтверждения выполненных настроек будет сгенерирован сценарий, по которому через соединение conn_newland производится поиск нужной базы данных, в которой отыскивается таблица tbl_tours. Из нее извлекаются все значения, содержащиеся в полях tourID и tourName, и записываются в набор записей rs_newland. Значения tourName будут использоваться в качестве надписей к элементам соответствующего списка, а значения tourID — в качестве данных.
- В списке Sort (Сортировать) выберите пункт tourName, а в списке справа, — пункт Ascending (По возрастанию).
Если не указан другой вариант, данные выводятся в том порядке, в котором содержатся в базе данных. Сортировка поля tourName по возрастанию позволяет упорядочивать все туры в алфавитном порядке, что, безусловно, облегчит посетителям поиск нужных записей.
- Нажмите кнопку Test (Проверить).
При нажатии отобразится содержимое набора записей в указанном порядке. При создании запросов нередко возникает необходимость проверить их на практике. На рисунке показано, что созданный запрос извлекает все 19 поездок и располагает их в алфавитном порядке (в поле tourName).
- Нажмите OK, чтобы вернуться в диалоговое окно, и снова нажмите OK.
Внешний вид документа не изменится, но в коде появится новый фрагмент, содержащий сценарий для создания запроса. Он находится в верхней части документа. В дальнейшем этот сценарий будет рассмотрен более подробно. На рисунке приведен код для ASP. При использовании ColdFusion код будет более понятным и компактным.
- В режиме Design (Дизайн) щелкните в форме на списке, чтобы выделить его. После этого на панели Property Inspector (Инспектор свойств) щелкните на кнопке List Values (Значения списка). Откроется диалоговое окно одноименного списка List Values. Поочередно выделите каждый элемент и нажмите кнопку Remove Value (Удалить значение) ("-").
В итоге, диалоговое окно не должно содержать элементов.
Виртуальные данные для тестирования работы калькулятора были добавлены в список в уроке 7. На этом шаге выдуманные значения будут удалены. На их место будут помещены реальные данные, содержащиеся в наборе записей rs_tourprices.
- Не снимая выделения со списка, на панели Property Inspector (Инспектор свойств) нажмите кнопку Dynamic (Динамический).
В результате, будет открыто диалоговое окно Dynamic List/Menu (Динамический список/меню), в котором к списку формы будут прикреплены динамические данные.
- В раскрывающемся списке Options from recordset (Опции из набора записей) выберите пункт rs_tourprices. В списке Values (Значения) укажите пункт tourID, а в списке Labels (Надписи) – пункт tourName. Нажмите OK.
На страницу будет добавлен код, формирующий элементы меню. Важно заметить, что полученный сценарий ASP, ColdFusion или PHP поочередно перебирает все значения, извлеченные из базы данных. Другими словами, подобно тому, как в уроке 7 для каждого элемента требовалось задавать поочередно надпись и значение, так и сценарий за один прием загружает в список одну из 19 пар "надпись-значение". С помощью обычной циклической структуры сценарий ASP, ColdFusion или PHP проходит через каждую пару tourName-tourID в наборе записей и добавляет ее к элементу списка.
Описанная выше процедура не требует вводить вручную 19 пар надписей и значений, что существенно ускоряет процесс разработки. Кроме того, при внесении изменений в базу данных они сразу же отобразятся и в списке. Это значит, что поддержка веб-страницы будет осуществляться автоматически – достаточно заниматься базой.
- Сохраните страницу, загрузите ее на сервер и протестируйте.
Если раскрыть список, то отобразятся 19 поездок, отсортированных по алфавиту в порядке возрастания.
- Пользователям PHP. Если при тестировании страницы появляется сообщение об ошибке "undefined index" ("неопределенный индекс") (cм. рис.), следует исправить код, как показано ниже.
Теперь попробуйте найти на странице tourprice.php следующий участок кода:
<?php
if ($_GET['error'] == "notnumeric")
{
echo "<p class=\"error\">*** Error! One or more fields was left blank or
contained a non-numeric character.</p>";
}
?>
Замените его на указанный код:
<?php
if (isset($_GET['error']))
{
if ($_GET['error'] == "notnumeric")
{
echo "<p class=\"error\">*** Error! One or more fields was left blank or
contained a non-numeric character.</p>";
}
}
?>
Эта ошибка появляется только в некоторых реализациях PHP. Ее причина заключается в том, что проверка переменной ($_GET['error']) на соответствие определенному значению notnumeric выполняется без первоначального контроля существования переменной.
Решение заключается в применении структуры вложенных условных операторов if. Внешнее условие проверяет, существует ли в запросе переменная error. Если существует, то производится проверка равенства переменной значению notnumeric. Но если переменной error в запросе нет, выполнение операции прекращается, что позволяет не учитывать источник возникновения проблемы.
- Заполните форму и подтвердите корректность выполнения этой процедуры.
Загрузится страница tourprice_processor.asp с учетом введенных сведений и рассчитанных на их основе данных. Причем стоимость поездки будет неожиданно низкой. Причина заключается в том, что при расчете стоимости тура используются значения в поле tourID, каждое из которых меньше 20.
Фильтрация наборов записей
В этом и предшествующем уроках уже дважды использовались наборы записей. В обоих случаях из базы данных извлекалась вся информация и выводилась на страницу. С этим связана одна проблема. Для правильной работы калькулятора требуется извлечь стоимость (для взрослых и детей) не на все путешествия и не на первое в списке, а на то, которое выбрал посетитель.
Что для этого нужно? Пользователь выбирает в списке тур и подтверждает корректность заполнения формы. Значение tourID, соответствующее этому путешествию, добавляется на страницу tourprice_processor.asp в качестве переменной формы. Таким образом, при отправлении запроса в базу данных следует составить приблизительно такую конструкцию (псевдокод):
Извлечь цену_для_взрослых (basePriceAdult) и цену_для_детей (basePriceChild) из tbl_tours,
где tourID равно tourID, выбранному посетителем в форме.
Прежде чем приступить к созданию кода на каком-либо языке, полезно четко сформулировать действия, даже если программирование (в данном случае – создание SQL-кода) скрыто за графическим интерфейсом и, в частности, за диалоговым окном Recordset (Набор записей).
- Откройте страницу tourprice_processor.asp. С помощью панели Bindings (Привязки) откройте диалоговое окно Recordset.
Набор записей, создаваемый в Dreamweaver, действует только в рамках одной страницы.
- В поле Name (Имя) введите имя "rs_tourprices_filtered". В списке Connection (Соединение) выберите пункт conn_newland, а в списке Table (Таблица) – пункт tbl_tours. В разделе Columns (Столбцы) укажите вариант Selected (Выделенные) и подсветите следующие поля для идентификатора и названия тура, базовой стоимости тура для взрослых и детей: tourID, tourName, basePriceAdult и basePriceChild.
Запрос возвращает значения четырех указанных полей из всех 19 записей таблицы tbl_tours (чтобы это проверить, следует нажать кнопку Test [Проверить]). Но от запроса требуется, чтобы он возвращал только данные путешествия, выбранного посетителем в форме.
- В разделе Filter (Фильтр) введите следующую формулу: tourID = Form Variable tourName, выбрав соответствующие значения для каждого из четырех полей.
На этом шаге к запросу добавляется дополнительный критерий для отбора данных. Введенная формула означает, что необходимо извлечь всю указанную информацию, но только из записи, соответствующей значению, указанному посетителем в форме.
- Нажмите кнопку Test (Проверить). Введите число "9" в диалоговое окно Please Provide a Test Value (Пожалуйста, обеспечьте контрольное значение) и нажмите OK.
Тест будет выполняться иначе, чем в предыдущий раз. На этот раз требуется указать контрольное значение для проверки. Причина состоит в том, что для выполнения запроса требуется значение, полученное из формы, но в среде разработки этого значения не существует. Поэтому и появляется диалоговое окно, в которое вводится значение.
Полученный в итоге список будет состоять из одного пункта – Machu Picchu (если указано число 9). Если вернуться и указать другие контрольные значения для проверки, то из базы данных будет извлечена информация о других турах.
- Нажмите OK, чтобы завершить работу с диалоговым окном после получения результатов проверки, затем снова вновь нажмите OK, чтобы сохранить набор записей.
И снова внешний вид и функции страницы не изменились, поскольку набор записей только извлекает данные и сохраняет их в памяти сервера. Однако эти данные пока не используются.
Добавление динамических данных в сценарий расчета
До этого момента (дважды), данные из базы помещались напрямую в HTML-код. В первый раз на главную страницу index.asp выводилась запись "Traveler’s Journal", а во второй — в качестве элементов списка формы были указаны пары значений tourName-tourID. Стоимость туров для взрослых и для детей следует не отображать на странице, а вставлять в сценарий расчета. В код сценария данные добавляются тем же способом, что и в XHTML.
Но вначале необходимо добавить на страницу еще код для вывода названия путешествия, для которого рассчитывалась стоимость – на случай, если посетитель забудет о сделанном выборе или, напротив, пожелает выбрать другой тур.
- В документе tourprice_processor.asp переключитесь в режим Design (Дизайн). После слова "tour" в первом предложении введите следующие символы: ", XX,". На панели Property Inspector (Инспектор свойств) выделите знаки XX с помощью полужирного начертания.
Снова символ "X" применяется для замены текста. Достоинство использования заменителя текста заключается в возможности форматировать его так, как должно выглядеть динамическое содержимое (в данном случае – выделение посредством полужирного начертания).
- Выделите знаки XX. В категории Application (Приложение) на панели Insert (Вставка) щелкните на кнопке Dynamic Data (Динамические данные) и в раскрывающемся списке выберите опцию Dynamic Text (Динамический текст).
Вкладка Application (Приложение) применяется для добавления общих динамических элементов, например, динамического текста.
- В диалоговом окне Dynamic Text (Динамический текст) разверните список Recordset (rs_tourprices_filtered) и выберите пункт tourName. Нажмите OK.
Выполненное действие аналогично перетаскиванию переменной из панели Bindings (Привязки) на страницу. В область кода будет добавлен еще один фрагмент кода.
При использовании ASP вместо символов XX будет добавлен следующий код:
<%=(rs_tourprices_filtered.Fields.Item("tourName").Value)%>.
Как известно из предыдущих уроков, <%= (в отличие от <%) означает <% Response.Write, – теперь код предназначен для вывода данных. Остальной код позволяет догадаться, что выводится значение поля tourName из набора отфильтрованных записей rs_tourprices_filtered.
При использовании ColdFusion появится такой код:
<cfoutput>#rs_tourprices_filtered.tourName#</cfoutput>
Тег <cfoutput> эквивалентен функции ASP Response.Write(), а выводит он определенное значение в поле tourName, хранящееся в отфильтрованном наборе записей rs_tourprices_filtered.
При использовании PHP код будет следующим:
<?php echo $row_rs_tourprices_filtered['tourName']; ?>
Команда echo выполняет те же действия, что и Response.Write() (ASP) или <cfoutput> (ColdFusion). Так же, как в случае ASP и ColdFusion, этот код выводит значение в поле tourName, хранящееся в наборе записей rs_tourprices_filtered.
Важно просмотреть и понять этот код, поскольку на следующем шаге придется создать код вручную.
- В режиме Code (Код) найдите сценарий расчета. Удалите строку, устанавливающую значение переменной basePrice равным значению переменной tourName.
В ASP код, который следует удалить, выглядит следующим образом: basePrice=Request.Form("tourName"). Находится он в строке 34.
В ColdFusion код выглядит так: <cfset basePrice = form.tourName>. Он размещен в строке 14.
В PHP код выглядит таким образом: $basePrice = $_POST['tourName']; и расположен в строке 12.
Эта строка больше не нужна, поскольку теперь стоимость тура передается не из формы, а из базы данных. Вдобавок требуется использовать два вида цен: для взрослых и для детей.
- Добавьте две новые строки кода, в которых задается значение двух новых переменных: basePriceAdult и basePriceChild.
Для ASP:
basePriceAdult=rs_tourprices_filtered.Fields.Item("basePriceAdult").Value
basePriceChild=rs_tourprices_filtered.Fields.Item("basePriceChild").Value
Для ColdFusion:
<cfset basePriceAdult = rs_tourprices_filtered.basePriceAdult>
<cfset basePriceChild = rs_tourprices_filtered.basePriceChild>
Для PHP:
$basePriceAdult = $row_rs_tourprices_filtered['basePriceAdult'];
$basePriceChild = $row_rs_tourprices_filtered['basePriceChild'];
Все три участка кода создают две новые переменные и устанавливают их значения равными соответствующей стоимости тура (извлеченной из базы данных) для взрослых и для детей.
- Только пользователям ASP. Удалите из строки с объявлением переменных (начинается с ключевого слова Dim) переменную basePrice и добавьте новые переменные basePriceAdult и basePriceChild.
Поскольку в ASP требуется явно объявлять любую переменную, важно обновлять этот список при каждом создании или удалении переменных.
- В строке, содержащей выражение для расчета стоимости тура, замените переменные basePrice на новые.
Для ASP:
tourPrice = (numAdult * basePriceAdult) + (numChild * basePriceChild)
Для ColdFusion:
<cfset tourPrice = (numAdult * basePriceAdult) + (numChild * basePriceChild)>
Для PHP:
$tourPrice = ($numAdult * $basePriceAdult) + ($numChild * $basePriceChild);
Теперь выражение для расчета стоимости туров включает значения, извлекаемые из базы данных.
- Сохраните страницу tourprice_processor.asp и загрузите ее на сервер. На панели Site (Сайт) выберите файл tourprice.asp и нажмите клавишу (F12) для тестирования приложения.
Приложение работает как запланировано. На основе введенной пользователем информации выводится правильная стоимость. Самое лучшее, что для поддержки приложения достаточно обновлять данные в базе данных. Если будет повышена стоимость туров и в базу будет добавлено новое значение, то это немедленно будет учтено и в сценарии расчета. Точно так же приложение будет корректно работать и при удалении существующих или добавлении новых туров.
Добавление к коду комментариев
Чтобы приложения для расчета стоимости заработало должным образом, было добавлено совсем немного кода. Результаты проведенной работы отображаются на всех веб-страницах. Например, в моем варианте страницы tourprice_processor.asp содержимое XHTML-документа начинается только на строке 39, а остальное место занимают ASP-сценарии. При использовании ColdFusion XHTML-документ начинается в строке 18. По большей части в этом коде содержатся те же сценарии, выполняющие те же функции, – просто код ColdFusion занимает гораздо меньше места. PHP располагается где-то между ними, – контент XHTML-документа начинается со строки 28.
Если просмотреть код страниц tourprice.asp и tourprice_processor.asp до верхней строки, можно объяснить все сценарии, расположенные в нем (в случае с ASP и PHP существует одно исключение, о котором позже будет рассказано). Сценарии будут понятными не только потому, что вы приобрели опыт их написания, но и потому, что упражнения выполнялись недавно, и в голове остались свежие воспоминания о сценариях. Но если вернуться к ним хотя бы через несколько месяцев или показать кому-нибудь в первый раз, то понять, для чего нужен тот или иной участок кода, будет не очень просто.
Это довольно серьезная проблема, поскольку подобные документы нередко используются в течение нескольких лет, и разработчики успевают позабыть об их содержимом. Именно поэтому важно документировать код сценариев, чтобы он был понятен – как для вас, так и для тех, кто будет заниматься сайтом впоследствии.
Код документируется при помощи комментария – поясняющего текста, который добавляется в код и позволяет понять его назначение. Интерпретаторами, обрабатывающими код, комментарии игнорируются. В этом упражнении в коде страниц tourprice.asp и tourprice_processor.asp будут добавлены комментарии.
- Откройте документ tourprice.asp. Добавьте комментарий над кодом запроса.
Для ASP следует добавить строку ниже открывающего тега <% в самом начале кода (до объявления переменной Dim rs_tourprices) и ввести в нее следующий комментарий, поясняющий, что создается набор записей на основе названий и идентификаторов туров из таблицы tbl_tours в базе данных. Кроме того, в этом комментарии объясняется, что данные используются в дальнейшем для заполнения раскрывающегося списка в форме:
' Creates a recordset of all the tour names and IDs from the tbl_tours table in the
database/ the data is used later to populate the form drop-down menu.
Для ColdFusion вверху документа следует ввести следующее:
<!--- Creates a recordset of all the tour names and IDs from the tbl_tours table in
the database/ the data is used later to populate the form drop-down menu. - -->
Для PHP перед строкой, расположенной строке 3 и начинающейся с кода my_sql_select_db, следует ввести комментарий:
// Creates a recordset of all the tour names and IDs from the tbl_tours table in the
database/ the data is used later to populate the form drop-down menu.
Во всех трех языках комментарии обозначаются особым образом. В языке VBScript (ASP) применяется одинарная кавычка (‘). Все, что расположено между этой кавычкой и концом строки, считается комментарием и игнорируется интерпретатором. В ColdFusion комментарий заключается в специальные теги. Они подобны тегам комментариев в HTML, за исключением того, что в HTML используются два дефиса, а в ColdFusion – три. Комментарий ColdFusion может включать несколько строк. В PHP однострочные комментарии могут обозначаться двумя косыми чертами (//) или знаком # в начале строки. Для создания многострочных комментариев в PHP применяется следующая синтаксическая конструкция: /* комментарий */.
Поскольку комментарии пишутся с учетом синтаксиса языка, используемого на сервере (VBScript, ColdFusion Markup Language или PHP), а не по правилам синтаксиса HTML, они удаляются из документа перед отправкой страницы клиенту. Это означает, что документировать код можно произвольным образом и при этом не волноваться, что комментарии увидят посетители.
- Сохраните и закройте tourprice.asp, а потом откройте tourprice_ processor.asp.
Большинство сценариев, используемых при работе приложения, содержатся в документе tourprice_processor.
- Только пользователям ASP и PHP. К первому участку кода после объявления <%LANGUAGE (только ASP) и к участкам <!—include (ASP) или require_once (PHP) добавьте приведенный ниже комментарий, не упуская одиночной кавычки ' (ASP) или двойного слэша // (PHP) в начале строки. В этом комментарии указывается, что созданный небольшой сценарий, сгенерированный Dreamweaver, предназначен для облегчения работы с динамическим запросом:
A small script generated by Dreamweaver to help with the dynamic query
Комментарии ASP и PHP всегда должны находиться, соответственно внутри тегов <% %> и <?php ?>.
Этот сценарий не упоминался в упражнениях, поскольку Dream-weaver автоматически добавил его при создании динамического запроса (а точнее, в момент создания критерия для фильтрации данных: tourID = form variable tourName). Этот комментарий поясняет, для чего предназначен участок кода и каким образом он попал на страницу.
В ColdFusion этот сценарий отсутствует, поскольку он реализован несколько иным (и более простым) способом.
- Отыщите сценарий, создающий набор записей, и добавьте к нему следующий комментарий "Queries the database for the tour name, adult price, and child price; data is filtered so that the only record retrieved corresponds to what the user entered the form". (В этом комментарии поясняется, что в базу данных направлен запрос на поиск названия тура, а также его стоимости для взрослых и для детей. Данные фильтруются таким образом, чтобы только одна извлеченная запись соответствовала значению, указанному пользователем в форме.)
В ASP сценарий запроса начинается с объявления используемых в нем переменных: Dim rs_tourprices_filtered.
В ColdFusion сценарий запроса найти довольно легко, поскольку он размещен внутри тегов <cfquery>.
В PHP сценарий начинается со строки mysql_select_db.
Следует помнить о применении правильного синтаксиса при вставке комментариев.
- Найдите сценарий для проверки правильности заполнения формы и добавьте следующий комментарий "Form validation script; redirects user back to tourprice.asp if form fields do not have numeric values". (В комментарии поясняется, что данный участок кода является сценарием, проверяющим правильность заполнения формы. Помимо этого указывается, что после выполнения сценария посетитель вернется обратно на страницу tourprice.asp, если поля формы не будут содержать числовых значений)
В ASP этот сценарий начинается с кода If Not IsNumeric. В ColdFusion – с кода <cfif Not IsNumeric. В PHP – с кода if (is_numeric.
- Найдите сценарий для расчета стоимости путешествий и добавьте следующий комментарий "Collects data for number of adults and children, and the prices for both adults and children; multiplies data to calculate total". (В комментарии указывается, что после выполнения сценария будут получены данные о количестве взрослых и детей, а также стоимость выбранного тура для взрослых и детей. Помимо этого, уточняется, что для получения итоговой стоимости будут проведены соответствующие расчеты.)
После такой интенсивной работы над этим сценарием в предыдущих упражнениях найти его самостоятельно не составит особого труда.
Теперь, после завершения полного цикла по созданию указанного сценария, следует лишь сохранить файлы и загрузить их на сервер.
|