|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Основы web-программирования для школьного "сайтостроительства". Лекция 3.Формы приятные и полезные: обработка форм на стороне сервераЗдравствуйте, уважаемые коллеги! Третья лекция нашего курса посвящена формам — основному инструменту взаимодействия двух сторон переговорного процесса — клиентской и серверной. Форма на языке HTML кодируется тегом form. Этот тег сам по себе имеет ряд важных параметров, которые мы рассмотрим ниже, но основное его назначение — быть контейнером для разнообразных элементов управления — текстовых полей ввода (однострочного и многострочного), радиокнопок, флажков (чекбоксов), списков. (Мы перечислили не все элементы управления, некоторые в силу ограниченности объема нашего курса рассмотрены не будут.) Быстрый стартДавайте начнем с того, что на небольшом примере попробуем разобраться с самой сутью вопроса — механизмом взаимодействия клиента и сервера посредством форм. Я постарался даже этот небольшой пример сделать относительно содержательным, но, насколько это возможно, не загромождал его никакими лишними техническими деталями. Учебный план
Итак, суть задачи: от пользователя требуется закончить известную фразу. Введенная пользователем строка отправляется на сервер, где и производится проверка, по результатам которой выводится соответствующее сообщение. На рис. 1 и 2 показаны примеры правильного и неправильного ввода.
а) б) Рис. 1 а) б) Рис. 2 Как все это работает? Так это же самое интересное! Организуем отдельный каталог, в котором будем размещать все примеры этого занятия. Вы еще не запустили Denwer? Нет? Ну и хорошо! Если уже запустили, остановите его, пожалуйста, потому что мы собираемся создать новый каталог в home. Назовем этот каталог forms. (Не забудьте внутри каталога forms создать каталог www.) Теперь можно запустить Denwer и поместить в каталог home/forms/www файл test.htm: 1. <html> 2. <head> 3. <meta http-equiv="content-type" content="text/html; charset=windows-1251"> 4. <title>О сколько нам открытий чудных готовит...</title> 5. </head> 6. <body> 7. <h1>Тестируем простейшую форму</h1> 8. <form name="test" action="check.php"> 9. <pre> 10. О сколько нам открытий чудных 11. Готовит <input type="text" name="spirit" size="30"> 12. </pre> 13. <p><input type="submit" value="Проверить!"> 14. </form> 15. </body> 16. </html> Я пронумеровал строки этого примера только для того, чтобы на них было легче ссылаться! Разумеется, в самом HTML-файле никаких номеров нет. Контейнер form открывается в строке 8 (закрывается он в строке 14). В этом контейнере имеются два элемента управления — однострочное текстовое поле ввода (тег input с параметром type="text", строка 11) и кнопка (тег input с параметром type="submit", строка 13). Рассмотрим существенные параметры этих тегов. У тега input в строке 11, помимо параметра type, который как раз и кодирует однострочное текстовое поле ввода, есть параметры name и siz. Смысл второго очень простой — он задает размер поля (в символах). Это существенный параметр, но он имеет отношение лишь к визуализации поля ввода в браузере. А вот параметр name куда важнее! Он задает имя переменной, которая будет хранить значение этого поля при передаче данных на сервер. У тега input в строке 13 в параметре value определяется значение надписи на кнопке. Но в данном случае как раз важнее значение параметра type. Заданное здесь значение submit информирует браузер о том, что при нажатии на данную кнопку необходимо передать данные формы на сервер. Этим кнопки submit отличаются от обычных кнопок button, у которых такой функции нет. А как это “передать на сервер”? — спросите вы. Кому передать? А вот это-то и написано в самом теге form. Посмотрим теперь на него. Параметр name у нашей формы задан “для порядку”. В данном случае он никак не используется. Наиважнейшим из всех параметров form для нас является action. В этом параметре задается имя скрипта-обработчика, в нашем случае — программы на PHP, которой будут переданы данные формы для обработки. Посмотрим на содержимое файла check.php: <html> <head> <meta http-equiv="content-type" content="text/html; charset=windows-1251"> <title>Проверка теста "О сколько нам открытий чудных готовит..."</title> </head> <body> <h1>Результат теста</h1> <p> <?php $result=($spirit=="просвещенья дух")?"Правильно!":"Неправильно :-("; echo "Вы ввели <b>$spirit</b>. Это <font color=red>$result</font>"; ?> </body> </html> Наш скрипт в выделенной строке анализирует значение переменной $spirit и в зависимости от него присваивает то или иное значение переменной $result. Использованная здесь конструкция, разумеется, может быть заменена условным оператором, но я написал именно так специально. Условная тернарная операция ?: часто применяется при программировании на Си-подобных языках. Она имеет следующий вид: (условие)?значение1:значение0 В зависимости от значения условия значение всей операции равно либо значению1 (если условие истинно), либо значению0. Итак, обработка формы происходит следующим образом: 1. Пользователь задает некоторые значения элементам управления формы (в данном случае — вводит значение в текстовое поле ввода). 2. Затем пользователь нажимает кнопку отправки данных (submit). 3. По нажатию этой кнопки браузер смотрит на значение параметра action тега form и загружает соответствующий файл, передавая ему значения полей формы в качестве параметров. 4. Ну а уж дело этого файла — сделать со своими параметрами то, что он считает нужным. Далее мы рассмотрим ряд небольших, но содержательных примеров с использованием различных элементов управления, но сначала кратко вспомним основные элементы управления HTML, которые можно использовать в формах. Основные элементы управления HTMLВ следующей таблице представлены основные элементы управления HTML, с которыми нам придется иметь дело. Данная таблица носит конспективный характер, в ней отмечены лишь самые существенные параметры рассматриваемых элементов.
Мини-тест: таблицы истинностиВ этом разделе мы реализуем несколько вариантов небольшого теста, предназначенного для проверки знаний таблиц истинности. Пользователь должен будет заполнить таблицу, а мы проверить, как он ее заполнил. Реализация теста посредством текстовых полей ввода Пусть, к примеру, требуется проверить знание таблицы истинности операции конъюнкции. Предложим пользователю задание, подобное представленному на рис. 3. Рис. 3 Код этой страницы разметим в файле testANDtext.htm: <html> <head> <meta http-equiv="content-type" content="text/html; charset=windows-1251"> <title>Таблица истинности логической операции операции "И"</title> </head> <body> <h1>Таблица истинности логической операции операции "И"</h1> <form name="test" action="testANDtext.php"> <table border="1"> <tr> <td> </td> <th>0</th> <th>1</th> </tr> <tr> <th>0</th> <td><input type="text" name="t00" size="1"> <td><input type="text" name="t01" size="1"> </tr> <tr> <th>1</th> <td><input type="text" name="t10" size="1"> <td><input type="text" name="t11" size="1"> </tr> </table> <p><input type="submit" value="Проверить!"> </body> </html> Как вы уже видите, обработчиком будет скрипт testANDtext.php. Правда, здесь и далее, в обработчике, я буду лишь печатать ввод пользователя. А проверить его вам предстоит самостоятельно, выполняя задания к этой лекции. Вот код обработчика (он мало отличается от рассмотренного выше примера): <html> <head> <meta http-equiv="content-type" content="text/html; charset=windows-1251"> <title>Проверка теста "Таблица истинности логической операции операции "И"</title> </head> <body> <h1>Результат теста</h1> <p>Вы заполнили таблицу следующим образом: <p> <table border="1"> <tr> <td> </td> <th>0</th> <th>1</th> </tr> <tr> <th>0</th> <td><?php echo $t00; ?> <td><?php echo $t01; ?> </tr> <tr> <th>1</th> <td><?php echo $t10; ?> <td><?php echo $t11; ?> </tr> </table> </body> </html> Здесь просто печатаются значения четырех переменных, полученных из полей ввода формы. В браузере это выглядит так (см. рис. 4): Рис. 4 Зачем “городить огород”? А действительно, зачем? Почему нельзя все быстро и просто проверить на стороне пользователя? Зачем нужны серверные скрипты, зачем что-то (данные) куда-то (на сервер) отправлять? Конечно, можно проверить все и на стороне клиента, посредством Javascript. И проблем никаких нет, и работать все будет быстрее. Вот так, например: <html> <head> <meta http-equiv="content-type" content="text/html; charset=windows-1251"> <title>Таблица истинности логической операции операции "И"</title> <script type="text/javascript"> function check() { //Переменная myform нужна только для сокращения записи при вычислении //значения result myform=document.forms.test; result=(myform.t00.value=="0")&&(myform.t01.value=="0")&& (myform.t10.value=="0")&&(myform.t11.value=="1")? "Правильно!":"Неправильно :-("; alert("Результат проверки: "+result); } </script> </head> <body> <h1>Таблица истинности логической операции операции "И"</h1> <form name="test"> <table border="1"> <tr> <td> </td> <th>0</th> <th>1</th> </tr> <tr> <th>0</th> <td><input type="text" name="t00" size="1"> <td><input type="text" name="t01" size="1"> </tr> <tr> <th>1</th> <td><input type="text" name="t10" size="1"> <td><input type="text" name="t11" size="1"> </tr> </table> <p><input type="button" value="Проверить!" onclick="check()"> </body> </html> Результат работы этого скрипта показан на рис. 5. Рис. 5 Как видите, все работает. Но! Взгляните-ка на рис. 6. Для пользователя не составляет никакого труда добраться до исходного кода скрипта! Рис. 6 Конечно, можно применять массу ухищрений, прятать код и т.п. Но в любом случае, если речь идет не об “игрушечных”, а о серьезных тестах, проверять их нужно именно на стороне сервера, поскольку только в этом случае у пользователя нет возможности ни добраться до исходного кода/правильных ответов, ни вмешаться в работу проверяющей программы. Реализация теста посредством радиокнопок Таблица истинности конъюнкции хороша тем, что ее можно просто реализовать и посредством радиокнопок. Пользователь должен будет просто отметить единственное истинное значение в таблице (хотя это, конечно, уже серьезная подсказка :).
Рис. 7 Сам тест на радиокнопках разместим в файле testANDradio.htm, а обработчик — в файле testANDradio.php. Код теста: <html> <head> <meta http-equiv="content-type" content="text/html; charset=windows-1251"> <title>Таблица истинности логической операции операции "И"</title> </head> <body> <h1>Таблица истинности логической операции операции "И"</h1> <form name="test" action="testANDradio.php"> <table border="1"> <tr> <td> </td> <th>0</th> <th>1</th> </tr> <tr> <th>0</th> <td><input type="radio" name="AND" value="00"> <td><input type="radio" name="AND" value="01"> </tr> <tr> <th>1</th> <td><input type="radio" name="AND" value="10"> <td><input type="radio" name="AND" value="11"> </tr> </table> <p><input type="submit" value="Проверить!"> </body> </html> Код обработчика: <html> <head> <meta http-equiv="content-type" content="text/html; charset=windows-1251"> <title>Проверка теста "Таблица истинности логической операции операции "И"</title> </head> <body> <h1>Результат теста</h1> <p>Вы заполнили таблицу следующим образом: <p> <table border="1"> <tr> <td> </td> <th>0</th> <th>1</th> </tr> <tr> <th>0</th> <td><?php echo ($AND=="00")?"1":"0"; ?> <td><?php echo ($AND=="01")?"1":"0"; ?> </tr> <tr> <th>1</th> <td><?php echo ($AND=="10")?"1":"0"; ?> <td><?php echo ($AND=="11")?"1":"0"; ?> </tr> </table> </body> </html> Как видите, здесь снова используется условная операция. В переменной $AND (напомним, что PHP-язык регистрово-зависимый, поэтому можно не опасаться такого названия переменной) передается значение value выбранной кнопки группы. Скрипт анализирует это значение и помещает его в таблицу. (Внимание! Если ни одна из кнопок не будет выбрана, возникнет ошибка. От нее вам предстоит избавиться самостоятельно, выполняя задания к лекции.) А как же… Реализация теста посредством чекбоксов “в лоб” Мы ловко реализовали таблицу истинности конъюнкции на радиокнопках, но это, конечно, несколько искусственный вариант. Реализовывать на радиокнопках дизъюнкцию уже очень неудобно (попробуйте :). Ну, можно, конечно, отмечать ложное значение, но это как-то… “криво”. Естественный вариант — флажки. Например, так (см. рис. 8): Рис. 8 Однако с флажками не все так просто. Впрочем, сначала реализуем этот вариант “в лоб”. В файле testORcheckbox.htm разместим тест, а в файле testORcheckbox.php — обработчик. Тест: <html> <head> <meta http-equiv="content-type" content="text/html; charset=windows-1251"> <title>Таблица истинности логической операции операции "ИЛИ"</title> </head> <body> <h1>Таблица истинности логической операции операции "ИЛИ"</h1> <form name="test" action="testORcheckbox.php"> <table border="1"> <tr> <td> </td> <th>0</th> <th>1</th> </tr> <tr> <th>0</th> <td><input type="checkbox" name="OR00"> <td><input type="checkbox" name="OR01"> </tr> <tr> <th>1</th> <td><input type="checkbox" name="OR10"> <td><input type="checkbox" name="OR11"> </tr> </table> <p><input type="submit" value="Проверить!"> </body> </html> Обработчик: <html> <head> <meta http-equiv="content-type" content="text/html; charset=windows-1251"> <title>Проверка теста "Таблица истинности логической операции операции "ИЛИ"</title> </head> <body> <h1>Результат теста</h1> <p>Вы заполнили таблицу следующим образом: <p> <table border="1"> <tr> <td> </td> <th>0</th> <th>1</th> </tr> <tr> <th>0</th> <td><?php echo (isset($OR00))?"1":"0"; ?> <td><?php echo (isset($OR01))?"1":"0"; ?> </tr> <tr> <th>1</th> <td><?php echo (isset($OR10))?"1":"0"; ?> <td><?php echo (isset($OR11))?"1":"0"; ?> </tr> </table> </body> </html> Как видите, каждому флажку соответствует своя переменная. Но особенность передачи значений флажков в том, что передаются только отмеченные флажки. Этим флажки принципиально отличаются, например, от текстовых полей ввода. Если пользователь ничего не введет в текстовое поле, то будет передана пустая строка. Если же пользователь не отметит флажок, то соответствующая переменная просто не будет передана. Поэтому нам пришлось использовать специальную функцию isset. Она проверяет, определена ли переменная с данным именем. В данном случае этого достаточно, значение переменной можно уже не проверять. Хороший вариант? Ужасный! Хуже не бывает! Я с большим трудом заставил себя написать его, так мне было противно :)! Почему? А представьте, что флажков не четыре, а двадцать четыре. Или сто. В реальном тесте — вполне мыслимый вариант. И что же, каждый раз заводить отдельную переменную :(? Конечно, нет. Для решения этой и подобных задач в PHP применяют стандартный, но довольно хитрый прием, требующий использования массивов. Так что придется с ними (с массивами) познакомиться. Вы, конечно, заметили, что я, в силу ограничений объема публикации нашего курса, практически не углубляюсь в технические подробности программирования на PHP. Но массивы на PHP могут вызвать удивление даже у бывалых программистов, поэтому на них я остановлюсь подробнее. Массивы в PHP Массивы в PHP — это не вполне то, к чему привыкли программисты, использующие, например, Паскаль или Си. Массивы в традиционном стиле (как упорядоченные нумерованные последовательности элементов) на PHP тоже можно использовать, но они лишь являются частным случаем “настоящих” PHP-массивов. Что же такое истинные PHP-массивы? Массив в PHP представляет собой набор пар ключ/значение. Ключи могут быть представлены лишь целым или строковым типом, значения могут быть любыми. Типы ключей и значений в пределах одного массива не обязаны совпадать. Понятно? Уверен, что нет. Я и сам лет… много… назад был озадачен таким представлением о массивах. Я разобрался с массивами в PHP до конца лишь поставив довольно много экспериментов. Что предлагаю проделать и вам. Результаты основных экспериментов с массивами я собрал в таблицу. В первом столбце находится исходный код на PHP, во втором — результат его выполнения. В третьем — мои комментарии. Уверен, что если вы уясните каждый из приведенных примеров, то поймете практически все.
Се. Ль. Островский | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||