Конечно, проверка данных, введенных пользователем в форму и переданных PHP-скрипту
безусловно должна иметь место непосредственно в самом PHP-скрипте, дабы пользователь
по ошибке не ввел некорректные данные, либо не сделал этого намеренно для
провокации ошибки исполнения скрипта. Но, давайте представим, что у нас сайт
с очень высокой посещаемостью, допустим, 10000 визитов в сутки и каждый пользователь
вводит данные в форму и отправляет ее на сервер. Допустим, 50% пользователей
не заполняют часть полей или заполняют их некорректно. Данные передаются скрипту,
проверяются, и форма возвращается пользователю для исправления ошибок. В нашем
случае, при большом количестве пользователей это создаст лишнюю нагрузку на
сервер и лишний трафик как для сервера, так и для пользователей.
Чтобы избежать указанных выше проблем - целесообразнее использовать Java Script
для проверки корректности заполнения полей формы. По статистике более 95%
пользователей для серфинга по Интернету пользуются браузерами, поддерживающими
Java Script. Пользователей, обладающих старыми версиями браузеров, либо браузерами
не поддерживающими Java Script, либо сознательно отключивших Java Script по
статистике менее 5%.
Итак, возьмем для примера следующую форму (обязательными для заполнения мы
определим имя пользователя (sender) и текст сообщения (msg), т.к. E-mail либо
ICQ у пользователя может попросту не быть):
<form name='myform' method='post' action='test.php'>
<input type='text' name='sender' value='' maxlength=20>
<input type='text' name='email' value=''>
<input type='text' name='icq' value='' maxlength=9 >
<textarea name='msg' cols=35 rows=10></textarea>
<input type='submit' name='Submit' value='Послать'>
</form>
Теперь будем определять правила, по которым будут проверяться отдельные поля.
Имя отправителя (sender) - не пустое, не короче, допустим, 3-х символов,
не длиннее 20.
p_sender = document.myform.sender.value.toString();
if(p_sender != "") {
if(p_sender.length<3 || p_sender.length>20) {
alert ("Укажите ваше имя (3-20 символов)!");
document.myform.sender.focus();
return false;
}
} else {
alert("Необходимо ввести имя!");
document.myform.sender.focus();
return false;
}
Электронная почта (e-mail) - если указано, то проверяем корректность
p_email = document.myform.email.value.toString();
if (p_email != "") {
t = p_email.indexOf("@");
if((p_email.indexOf(".") == -1) || (t == -1) || (t < 1) || (t
> p_email.length - 5) || (p_email.charAt(t - 1) == '.') || (p_email.charAt(t
+ 1) == '.')) {
alert("Некорректно указан E-mail !");
document.myform.email.focus();
return false;
}
}
Номер аськи (icq) - если указан, то состоит только из цифр, не короче
5 и не длиннее 9 знаков.
Разместим часть ява-скрипта прямо в теге поля для ввода номера ICQ - такое
ограничение позволит пользователю вводить в это поле только цифры
<input type='text' name='icq' value='' maxlength=9
onKeyPress ='if ((event.keyCode < 48) || (event.keyCode
> 57)) event.returnValue = false;'>
Далее необходимо проверить длину введенного номера
p_icq = document.myform.icq.value.toString();
if(p_icq != "") {
if(p_icq.length<5 || p_icq.length>9) {
alert ("Длина номера ICQ 5-9 символов!");
document.myform.icq.focus();
return false;
}
}
Текст сообщения (msg) - не пустое и, допустим, не менее 10 символов
p_msg = document.myform.msg.value.toString();
if (p_msg.length < 10) {
alert ("Необходимо ввести текст сообщения (не менее 10 символов) !");
document.myform.msg.focus();
return false;
}
Еще один способ "защиты" форм - это "отключение" кнопки
submit и включение ее только тогда, когда будут заполнены необходимые
поля (работает не во всех браузерах, только поддерживающих JavaScript 1.2).
"Отключается" кнопка просто. Для этого достаточно указать:
<input type='submit' name='Submit' value='Послать'
disabled>
Теперь к полям обязательным для заполнения добавляем:
onkeypress='checkreq()' onkeyup='checkreq()' onblur='checkreq()'
и получаем
<input type='text' name='sender' value='' maxlength=20
onkeypress='checkreq()' onkeyup='checkreq()' onblur='checkreq()'>
<textarea name=msg cols=35 rows=10 onkeypress='checkreq()'
onkeyup='checkreq()' onblur='checkreq()'></textarea>
Теперь определим функцию checkreq()
function checkreq() {
path = document.myform;
tmp = (path.sender.value == "");
if (!tmp && (path.sender.value.length < 3)) tmp = true;
path.Submit.disabled = tmp;
if (tmp) return;
tmp = (path.msg.value == "");
if (!tmp && (path.msg.value.length < 10)) tmp = true;
path.Submit.disabled = tmp;
}
Теперь "соберем" отдельные блоки, предназначенные для проверки
конкретных полей в одну функцию, а к форме добавим процедуру, которая будет
вызывать эту функцию перед отправкой формы PHP-скрипту.
<script>
// Проверка введенного имени и сообщения и "включение"
кнопки submit
function checkreq() {
path = document.myform;
tmp = (path.sender.value == "");
if (!tmp && (path.sender.value.length < 3)) tmp = true;
path.Submit.disabled = tmp;
if (tmp) return;
tmp = (path.msg.value == "");
if (!tmp && (path.msg.value.length < 10)) tmp = true;
path.Submit.disabled = tmp;
}
// Проверка корректности заполнения полей формы
function check() {
p_sender = document.myform.sender.value.toString();
if(p_sender != "") {
if(p_sender.length<3 || p_sender.length>20) {
alert ("Укажите ваше имя (3-20 символов)!");
document.myform.sender.focus();
}
} else {
alert("Необходимо ввести имя!");
document.myform.sender.focus();
}
p_email = document.myform.sender.value.toString();
if (p_email != "") {
t = p_email.indexOf("@");
if((p_email.indexOf(".") == -1) || (t == -1) || (t < 1) || (t
> p_email.length - 5) || (p_email.charAt(t - 1) == '.') || (p_email.charAt(t
+ 1) == '.')) {
alert("Некорректно указан E-mail !");
document.myform.email.focus();
return false;
}
}
p_icq = document.myform.icq.value.toString();
if(p_icq.length<5 || p_icq.length>9) {
alert ("Длина номера ICQ 5-9 символов!");
document.myform.icq.focus();
}
p_msg = document.myform.msg.value.toString();
if (p_msg.length < 10) {
alert ("Необходимо ввести текст сообщения (не менее 10 символов) !");
document.myform.msg.focus();
return false;
}
}
</script>
<form name='myform' method='post' action='test.php'
onSubmit='return check();'>
<input type='text' name='sender' value='' maxlength=20 onkeypress='checkreq()'
onkeyup='checkreq()' onblur='checkreq()'>
<input type='text' name='email' value=''>
<input type='text' name='icq' value='' maxlength=9 onKeyPress
='if ((event.keyCode < 48) || (event.keyCode > 57)) event.returnValue
= false;'>
<textarea name=msg cols=35 rows=10 onkeypress='checkreq()'
onkeyup='checkreq()' onblur='checkreq()'></textarea>
<input type='submit' name='Submit' value='Послать'>
</form>
Теперь при попытке пользователя отправить форму PHP-скрипту, управление передается
сначала ява-скрипту, который возвращает FALSE если будет найдена хоть одна
ошибка пользователя, курсор будет помещен в поле, содержащее ошибку (первое
по счету), и форма просто не будет отправлена.
Как было сказано выше, проверка формы ява-скриптом позволяет избежать отправки
неверно заполненных форм на сервер и тем самым снизить нагрузку на сервер
и трафик, но это не освобождает вас от необходимости жесткой проверки всех
данных, переданных пользователем, т.к. пользователь может намеренно отключить
ява-скрипт у себя в браузере, чтобы передать модифицированные данные.
Данный пример, конечно, не охватывает всех возможных вариантов проверки полей
формы (например, url или сравнение идентичности пароля и его подтверждения),
т.к. может возникнуть необходимость проверять различные данные, вводимые пользователем.
Здесь показаны наиболее часто встречающиеся поля и примеры их обработки. Остальное
вы можете написать сами, конечно, если довольно не плохо знаете JavaScript.
До сих пор мы защищали PHP-скрипт от некорректных данных, переданных из формы.
Но так же можно применить и средства, предлагаемые PHP, для защиты форм.
Наверняка многим знакома проблема флуда (для этого обычно используется простая
программа, зачастую написанная на том же PHP). Думаю, вам будет не очень приятно
обнаружить в своей гостевой книге пару тысяч сообщений, зачастую оскорбительного
характера? Самый простой способ решения этой проблемы - небольшая картинка
с кодом и поле для ввода этого кода (как на крупных почтовых сервисах). Думаете
это очень сложно? Наоборот - это дело 5 минут. Итак, приступим.
Листинг файла code.php, генерирующего изображение со случайным чисом
<?php
session_start();
$сode = rand(100000,999999);
session_register("сode");
$Image = imageCreateFromPng ("code.png");
$Color = imageColorAllocate($Image, 254, 165, 65);
settype ($сode, "string");
imageString($Image, 3, 30, 3, $сode, $Color);
Header("Content-type: image/png");
imagePng($Image);
imageDestroy($Image);
?>
В файле code.png у нас храниться чистый (или с необходимым фоном) PNG файл
размерами 100 на 20 пикселей. Случайное шестизначное число записывается в
переменную $code, сохраняется в сессии, и накладывается
на картинку. Данную картинку можно вывести в браузер следующим образом
<img src="code.php" width="100"
height="20" alt="Код" border="0">
далее в форму добавляем поле, в которое пользователь введет код
<input type=text name=code2 value="">
И далее, после отправки пользователем формы PHP-скрипту нам останется сравнить
код хранящийся, в сессии ($HTTP_SESSION_VARS['code']),
с кодом, переданным пользователем ($HTTP_POST_VARS['code2'])
и в случае несовпадения не принимать данные формы и вернуть ее пользователю.
Таким образом, программа-флудер просто не сможет считать код с картинки.
Так же хотелось бы обратить внимание на момент, не указанный в статье Алатарцева
Сергея, на которую я ссылался в начале. Как мы видим из примера нашей формы,
данные PHP-скрипту передаются методом POST. Обратите внимание на предыдущий
абзац: переменная code2 могла бы быть доступна в PHP-скрипте под именем $code2,
но тогда ее можно было бы передать и методом GET, просто набрав в адресной
строке браузера test.php?code2=123456. Чтобы лишить пользователя этой возможности
необходимо получать переменные из массива $HTTP_POST_VARS,
предварительно проверяя, была ли эта переменная передана методом POST -
if(!IsSet($HTTP_POST_VARS['code2'])) {действие_если_переменная_не_существует}.
Этот момент касается абсолютно всех переменных, передаваемых скрипту
методом POST от формы.
Вот собственно и все. Теперь ваша форма будет более надежной.
04.08.04