Сайт разработчика Александра Климова

/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000

Знакомство с формами

Вместо предисловия

Среди бела дня (впрочем и тёмной ночью тоже) стали воровать котов! Совсем обнаглели похитители.

Воруют котика

Вот душераздирающая история в сокращении, взятая отсюда.

Рано утром в своем частном доме на West Side (Нью-Йорк) молодая женщина услышала дикий птичий крик. Когда она прибежала, то увидела на небольшой террасе только несколько перьев и клочки меха ее любимого кота Эдди. Было ясно, что большая дикая птица утащила её кота, который любил поваляться утром на свежем воздухе. По перьям специалисты сказали, что тут поработал краснохвостый ястреб. Женщина была просто убита горем.

-Я шла несколько часов по Riverside Drive и рыдала, глядя на его фотографию. Я осмотрела все известные ястребиные гнезда в округа, искала следы присутствия Эдди. Четыре года Эдди был ее единственным компаньоном и другом...

Женщина уже решила, что ее любимый питомец погиб, но все равно расклеила объявления о поиске кота. И вскоре ей позвонил сосед и рассказал, что в его саду, который находиться недалеко от дома владелицы, оказался похожий кот. Это и правда был Эдди. Сосед рассказал, что в то утро его разбудил громкий стук и кошачье мяуканье. В саду был опрокинут большой зонт от солнца, а на земле сидел испуганный кот. Дело в том, что Эдди довольно толстый кот, если не сказать больше, и ястреб видимо просто не смог его далеко унести и уронил. Отделался Эдди всего парой царапин.

Теперь вы понимаете, почему они постоянно просят жрать. Это делается в целях личной безопасности. Тяжелого кота трудно украсть.

А что делать тем, кто пока не нашёл своего кота? Нужно создать сайт и разместить страницу с веб-формой. С помощью данной формы посетители сайта смогут проинформировать вас о деталях похищения. Ваш котик найдётся!

Создание веб-формы средствами HTML

Для создания формы можно использовать обычные HTML-теги. Никакого программирования пока не требуется. Давайте попробуем:

report.html


<p>Представьтесь, пожалуйста, и сообщите о моём коте</p>
<form method="post" action="mailto:chuck@norris.com">
    <label for="firstname">Имя:</label>
	<input type="text" name="firstname" id="firstname"><br>
	<label for="lastname">Фамилия:</label>
	<input type="text" name="lastname" id="lastname"><br>
	<label for="email">Ваша электронная почта:</label>
	<input type="text" name="email" id="email"><br>
	<label for="when">Когда это произошло?</label>
	<input type="text" name="when" id="when"><br>
	<label for="description">Опишите похитителей</label>
	<input type="text" name="description" id="description" size="32"><br>
	<label for="love">Вы любите котов?</label>
	Да <input type="radio" name="love" id="love" value="yes">
	Нет <input type="radio" name="love" id="love" value="no"><br>
	<label for="other">Дополнительная информация</label><br>
	<textarea name="other" id="other" cols="30" rows="3"></textarea><br>
	<input type="submit" value="Отправить сообщение" name="submit">
</form>

Посмотреть на пример.

В принципе, созданная форма выглядит вполне работоспособной. Введите теперь в неё какие-нибудь данные и нажмите кнопку Отправить сообщение. Что при этом произойдёт? Вот тут начинаются проблемы. Результат будет непредсказуем. У кого-то запустится Outlook или другая почтовая программа, у кого-то может вообще ничего не запуститься. Даже у тех, у кого программа запустилась, письмо будет выглядеть по разному. У некоторых будет пустое письмо, у других - введённые ранее данные будут нечитаемыми или смешаны в одну кучу. В любом случае у нас проблема. А связана она с тем, что мы указали для атрибута action формат mailto, который отвечает за отправку писем. На разных компьютерах данный формат может вести себя по разному.

Поэтому, нам нужно научиться управлять процессом передачи данных, введённых в веб-форму. Одним из таких вариантов является PHP.

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

Нам достаточно заменить выражение action="mailto:chuck@norris.com" на action="report.php", чтобы сценарий стал обрабатываться на сервере. Когда пользователь нажмёт кнопку отправки сообщения, то запустится наш сценарий.

Формы создаются при помощи тега form. У каждой формы есть атрибут action, с помощью которого можно связать форму с php-сценарием.

Создадим новый файл с сценарием:

report.php

<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
<title>Поиск пропавших котов - сценарий</title>
</head>
<body>

<h2>Сообщения о поиске моего кота</h2>

<?php

    $when = $_POST['when'];
    $description = $_POST['description'];
    $email = $_POST['email'];
    
    echo 'Спасибо за заполнение формы.<br>';
    echo 'Кота похитили ' . $when . '<br>';
    echo 'Похитители: ' . $description . '<br>';
    echo 'Ваш email: ' . $email;

?>

</body>
</html>

Теперь нужно внести изменения в форму. Откроем файл report.html и измените атрибут формы action с mailto на report.php:

<form method="post" action="report.php">

Посмотреть на пример.

Введите какие-нибудь данные и нажмите кнопку Отправить сообщение. На этот раз вы увидите страницу report.php, в которой отобразится часть данных, введённых вами.

Разберём пример. Сначала идёт стандартный HTML-код. Затем мы прерываем HTML-код и вставляем теги <?php ?> для PHP-сценария.

Код читает данные формы и присваивает их значения переменным. Эти значения можно вывести при помощи команды echo, который выводит динамически генерируемый HTML-код.

Несколько правил для переменных

  • Имена переменных должны начинаться со знака доллара $.
  • Имя переменной должно состоять хотя бы из одного символа.
  • Символ после знака доллара должен быть буквой английского алфавита или символом подчёркивания, далее можно использовать буквы, цифры и символы подчёркивания.
  • Пробелы и специальные символы (тире и т.п.) не допустимы.

$_POST

$_POST - это специальная суперглобальная переменная, встроенная в PHP и доступная из любого места сценария. Её не нужно создавать, она всегда существует. Она непосредственно связана с методом submit, когда пользователь нажимает на кнопку отправки данных формы. При этом у тега <form> в атрибуте должно быть прописано method="post".

$_POST является массивом. Чтобы получить доступ к данным, введёным в форме, необходимо использовать имя поля как указатель в массиве $_POST. Например, мы присвоили текстовому полю имя lastname:

<input type="text" name="lastname" id="lastname">

Чтобы узнать, какой текст содержится в этом поле, нужно обратиться к элементу массива как $_POST['lastname'].

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

Все элементы формы

Напишем пример с использованием всех возможных вариантов, которые могут встретиться в формах.


<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
<title>Поиск пропавших котов</title>
</head>
<body>

<h3>Пропал кот</h3>

<p>Представьтесь, пожалуйста, и сообщите о моём коте</p>

<form name="form1" method="post" action="report3.php">

<label for="textfield">Текстовое поле:</label>
<input type="text" name="textfield"><br>
<br>
<label for="pass">Поле ввода пароля:</label>
<input type="password" name="pass"><br>
<br>
<label for="hidden">Скрытое поле hidden</label>
<input name="hidden" type="hidden" id="hidden" value="Скрытое_значение: Meow">

<hr>
<p>Флажки(checkbox):</p>
<input type="checkbox" name="checkbox1" value="1">
Вариант первый
<input type="checkbox" name="checkbox2" value="1">
Вариант второй
<input type="checkbox" name="checkbox3" value="1" checked>
Вариант третий (по умолчанию)</p>

<hr>
<label for="radiobutton">Переключатели (radiobutton):</label>
<p>
<input name="radiobutton" type="radio" value="yes"> 
Да 
<input name="radiobutton" type="radio" value="no"> 
Нет</p>
<hr>
<label for="textarea">Многострочное текстовое поле (textarea):</label><br>
<textarea name="textarea" cols="30" rows="3">Текст по умолчанию</textarea>

<hr>
<p>Список с единственным выбором:</p>

<select name="days" size=1>
<option value=1>Понедельник</option>
<option value=2>Вторник</option>
<option value=3>Среда</option>
<option value=4>Четверг</option>
<option value=5>Пятница</option>
<option value=6 selected>Субкота</option>
<option value=7>Воскресенье</option>
</select>

<p>Список с множественным выбором (multiple):</p>

<select name="days_m[]" size=7 multiple>
<option value=1 selected>Понедельник</option>
<option value=2>Вторник</option>
<option value=3>Среда</option>
<option value=4>Четверг</option>
<option value=5>Пятница</option>
<option value=6>Суббота</option>
<option value=7>Воскресенье</option>
</select> 

<hr>

<input type="submit" value="Отправить"><br>
<br>
<input type="reset" value="Очистить форму">

</form>

</body>
</html>

Посмотреть на пример.

Когда пользователь отправит форму, то браузер передаст следующие данные:

  • textfield - значение текстового поля;
  • pass - значение поля ввода пароля;
  • hidden - значение скрытого поля;
  • параметры checkbox: checkbox1, checkbox2 и checkbox3 будут переданы только в том случае, если соответствующие им переключатели активны;
  • radiobutton - значение группы radio (будет передано одно из значений: Yes или No);
  • textarea - содержимое многострочной текстовой области;
  • days - значение списка с единственным выбором;
  • days_m - значения списка с множественным выбором.

Параметры textfield, pass и textarea обрабатываются просто, мы уже рассматривали этот пример.

С параметрами checkbox1, checkbox2, checkbox3, и radiobutton дело обстоит несколько сложнее. Если переключатель не активен, то перечисленные параметры вообще не будут переданы на сервер, как будто их вообще не было. Следовательно, при попытке обратиться в сценарии к этим параметрам, мы получим сообщение, что переменная не существует. Поэтому просто написать echo $_POST['checkbox1']; мы не можем, нам необходимо сначала проверить существование этих параметров в запросе. Проверка существования параметра осуществляется с помощью функции isset(), которая служит для проверки существования переменных.

Сложнее обрабатывать параметры списка с множественным выбором, так как в этом случае параметры передаются так:


days_m=01&days_m=03&days_m=07...

Один параметр имеет несколько значений. Это напоминает нам массив данных. Действительно, множественный список можно представить в виде массива, а обработать его элементы с помощью цикла foreach.

Квадратные скобки []- это признак массива. Циклическая обработка массива осуществляется так:


foreach ($_POST['days_m'] as $key=>$value) echo "$key = $value <br>";

Полностью код report3.php


<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
<title>Поиск пропавших котов - сценарий</title>
</head>
<body>

<h2>Сообщения о поиске моего кота</h2>

<?php
    echo 'Спасибо за заполнение формы.<br>';
    echo "<p>Переданное значение текстового поля: <b>".$_POST['textfield']."</b></p>";
    echo "<p>Переданное значение поля пароля: <b>".$_POST['pass']."</b></p>";
    echo "<p>Переданное значение скрытого поля hidden: <b>".$_POST['hidden']."</b></p>";
    echo '<hr>';
    echo '<p>Были включены следующие флажки: </p>';
    
    if (isset($_POST['checkbox1'])) echo "<p><b>Первый</b></p>";
    if (isset($_POST['checkbox2'])) echo "<p><b>Второй</b></p>";
    if (isset($_POST['checkbox3'])) echo "<p><b>Третий</b></p>";
    
    echo '<hr>';

    if (isset($_POST['radiobutton']))
    {
        echo '<p>Был выбран переключатель со значением: ';
        if ($_POST['radiobutton']==="yes") echo "<b>Yes</b>";
        if ($_POST['radiobutton']==="no") echo "<b>No</b>";
        echo '</p>';
    }
    else echo '<p>Ни один из переключателей не был выбран</p>';
    
    echo '<hr>';
    echo '<p>Значение многострочного текстового поля :</p>';
    echo "<p><b>".$_POST['textarea']."</b></p>";
    
    echo '<hr>';
    echo "<p>Значение списка с единственным выбором: <b>".$_POST['days']."</b></p>";

    echo '<hr>';
    echo '<p>Значения списка с множественным выбором: </p>';
    foreach ($_POST['days_m'] as $keys=>$values) echo "<b>$values</b><br>";
?>

</body>
</html>

Проверка данных

Нельзя полагаться на пользователя. Например, он может не заполнить некоторые поля, которые для нас являются обязательными и нажать кнопку Отправить. В результате мы получим пустое письмо с пустым содержанием. Всегда следует проверять входящие данные. В одном месте мы проверяли существование переменной с помощью функции isset(). Но также надо проверять на пустую строку, это можно сделать с помощью функции empty(). При этом функцию isset() использовать не обязательно.

Дело в том, что переменные суперглобального массива $_POST всегда будут возвращать вам значение true независимо от того, содержат они какие-либо данные или нет. Иначе говоря, функция isset() не покажет вам разницы между пустым полем ввода и полем, в которое введены какие-либо данные. Функция empty() проверяет, действительно ли поле ввода пусто или нет, что как раз нам и нужно для контроля достоверности.

Добавим проверку одного поля из первого примера report.php.


...
$when = $_POST['when'];

// Проверка на пустую строку
if(empty($when)) {
    echo 'Вы забыли заполнить поле Когда это произошло';
    exit();
}


// Остальной код без изменения
echo 'Спасибо за заполнение формы.<br>';

Естественно, следует проверить все поля.

Иногда делают проверку наоборот, то есть нужно убедиться, что строка не пуста и можно продолжать работу.


if(!empty($when)){
    // можно соединяться с базой данных или другой код
}

Чтобы не проверять каждое поле в отдельных условиях if, проверку объединяют.


if((!empty($when)) && (!empty($email))){
    // можно соединяться с базой данных или другой код
}

Это условное выражение будет иметь значение true, когда обе переменных имеют непустые значения.

Данный логический оператор && соответствует AND, есть еще OR, выражаемый через ||, который вернёт true, когда любая из рассматриваемых величин имеет значение true.

Вам следует переписать примеры выше.

Также следует добавить блок else с выводом ошибки, чтобы пользователь понимал, в чем дело.


if(){
    ...
}
else {
    echo 'Вы забыли заполнить поле с электронным адресом и другие поля.';
}
Реклама