или как отправить сообщение на e-mail посредством HTML формы

Вы имеете свой собственный web-сайт и хотите получать от своих пользователей письма или сообщения, вопросы, советы или просто пожелания по электронной почте, тогда этот урок для вас!

Как отправить сообщение по e-mail

Нам нужны следующие файлы:

  1. form.html - страница с формой.
  2. form_processing.php - файл со скриптом, обрабатывающим HTML форму .

Рассмотрим код form.html:

Обработка HTML формы с помощью PHP



Ваше имя:


E-mail:


Тема:


Сообщение:





HTML форма содержит поля для ввода имени, почтового адреса пользователя, темы сообщения, текста сообщения и кнопку «Отправить», при нажатии на которую, информация отправляется на обработку к PHP скрипту в файл form_processing.php .

Метод гипертекстового транспортного протокола имеет два значения: get (по умолчанию) и post . Чаще используется метод post , так как позволяет передавать большие объемы данных. Все значения, передающиеся к обрабатывающему скрипту посредством метода post , сохраняются в ассоциативном массиве $_POST (этот массив изначально встроен в php интерпретатор), который состоит из переменных $_POST , где name - фактическое имя поля ввода - значение атрибута name="" :

Создадим файл-обработчик form_processing.php:

/* Осуществляем проверку вводимых данных и их защиту от враждебных
скриптов */
$your_name = htmlspecialchars ($_POST [ "your_name" ]);
$email = htmlspecialchars ($_POST [ "email" ]);
$tema = htmlspecialchars ($_POST [ "tema" ]);
$message = htmlspecialchars ($_POST [ "messages" ]);
/* Устанавливаем e-mail адресата */
$myemail = "[email protected]" ;
/* Проверяем заполнены ли обязательные поля ввода, используя check_input
функцию */
$your_name = check_input ($_POST [ "your_name" ], "Введите ваше имя!" );
$tema = check_input ($_POST [ "tema" ], "Укажите тему сообщения!" );
$email = check_input ($_POST [ "email" ], "Введите ваш e-mail!" );
$message = check_input ($_POST [ "message" ], "Вы забыли написать сообщение!" );
/* Проверяем правильно ли записан e-mail */
if (! preg_match ("/([\w\-]+\@[\w\-]+\.[\w\-]+)/" , $email ))
{
show_error ("
Е-mail адрес не существует"
);
}
/* Создаем новую переменную, присвоив ей значение */
$message_to_myemail = "Здравствуйте!
Вашей контактной формой было отправлено сообщение!
Имя отправителя: $your_name
E-mail: $email
Текст сообщения: $message
Конец"
;
/* Отправляем сообщение, используя mail() функцию */
$from = "From: $yourname <$email> \r\n Reply-To: $email \r\n" ;
mail ($myemail , $tema , $message_to_myemail , $from );
?>

Ваше сообщение было успешно отправлено!


На Главную >>>


/* Если при заполнении формы были допущены ошибки сработает
следующий код: */
function check_input ($data , $problem = "" )
{
$data = trim ($data );
$data = stripslashes ($data );
$data = htmlspecialchars ($data );
if ($problem && strlen ($data ) == 0 )
{
show_error ($problem );
}
return $data ;
}
function show_error ($myError )
{
?>


Пожалуйста исправьте следующую ошибку:





exit();
}
?>

Участок кода:

— выведет указанный текст, если поля HTML формы были заполнены правильно. index.php - главная страница вашего сайта.

Участок кода:

— укажет характер допущенной ошибки.

Значение переменной:

$from = "From: $yourname <$email> \r\n Reply-To: $email \r\n" ;
?>

— автоматически отобразит e-mail пользователя в нужной строке, когда вы будете писать ответ.

HTML формы — сложные элементы интерфейса. Они включают в себя разные функциональные элементы: поля ввода и

Можно обрабатывать формы, не заботясь о фактических именах полей.

Для этого можно использовать (в зависимости от метода передачи) ассоциативный массив $HTTP_GET_VARS или $HTTP_POST_VARS . Эти массивы содержат пары имя/значение для каждого элемента переданной формы. Если Вам все равно, Вы можете использовать ассоциативный массив $_REQUEST .

Пример 6

Обработка произвольного ввода независимо от метода передачи $value) echo "$key == $value
"; ?>

Пример 7. Обработка нажатия на кнопку с использованием оператора "@".

">

С помощью функции header() , послав браузеру заголовок "Location" , можно перенаправить пользователя на новую страницу.

Например:

Передача файла на сервер. Залить файл. UpLoad

PHP позволяет передавать на сервер файлы. HTML-форма, предназначенная для передачи файла, должна содержать аргумент enctype="multipart/form-data" .

Кроме того в форме перед полем для копирования файла должно находиться скрытое поле с именем max_file_size . В это скрытое поле должен быть записан максимальный размер передаваемого файла (обычно не больше 2 Мбайт).

Само поле для передачи файла - обычный элемент INPUT с аргументом type="file" .

Например:

" method="post">

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

Пример 8

Обработка переданного файла "; echo "имя: ".$_FILES["userfile"]["name"]."
"; echo "размер: ".$_FILES["userfile"]["size"]."
"; echo "тип: ".$_FILES["userfile"]["type"]."
"; } ?>
" method="post">

Примеры загрузки файлов на сервер

Если возникнут проблеммы с перекодировкой сервером загруженного файла, символ с кодом 0х00 заменен на пробел (символ с кодом 0х20 ), допишите в файл httpd.conf из каталога Апача (/usr/local/apache) следующие строки.

CharsetRecodeMultipartForms Off

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

Одна страница может содержать несколько форм, поэтому необходимы средства, которые позволяли бы отличить одну форму от другой. Более того, вы должны как-то сообщить форме, куда следует перейти, когда пользователь выполняет действие с формой (как правило, нажимает кнопку отправки данных). Обе задачи решаются заключением форм в следующие теги HTML:

Как видно из приведенного фрагмента, в тегах форм указываются два важных элемента: действие и метод. Действие указывает, какой сценарий должен обрабатывать форму, а метод определяет способ передачи данных этому сценарию. Существует два метода:

  • Метод get передает все данные формы в конце URL. Из-за различных ограничений, связанных со спецификой языков и длиной данных, этот метод применяется редко.
  • Метод post передает все данные формы в теле запроса. Этот метод используется чаще, чем get.

В этой главе приведена лишь очень краткая вводная информация по основному син-таксису форм HTML. Более полную информацию можно найти в книге А. Хоумера и К. Улмена «Dynamic HTML. Справочник» (СПб.: Питер, 1999).

Элементы форм, ориентированные на ввод с клавиатуры

Наше знакомство с построением форм начнется с элементов, ориентированных на ввод с клавиатуры. Таких элементов всего два -- текстовое поле (text box) и текстовая область (text area).

Текстовое поле

В текстовых полях обычно вводится короткая текстовая информация -- скажем, адрес электронной почты, почтовый адрес или имя. Синтаксис определения текстового поля:

Определение текстового поля включает пять атрибутов:

  • type -- тип элемента (для текстовых полей -- text);
  • size -- общий размер текстового поля в браузере;
  • maxlength -- максимальное количество символов, вводимых в текстовом поле;
  • value -- значение, отображаемое в текстовом поле по умолчанию.

Текстовое поле изображено на рис. 10.1.

Рис. 10.1. Текстовое поле

Особой разновидностью текстовых полей является поле для ввода паролей. Оно работает точно так же, как обычное текстовое поле, однако вводимые символы заменяются звездочками. Чтобы создать в форме поле для ввода паролей, достаточно указать type="password" вместо type="text".

Текстовая область

Текстовая область (text area) используется для ввода несколько больших объемов текста, не ограничивающихся простым именем или адресом электронной почты. Синтаксис определения текстовой области:

Определение текстового поля включает три атрибута:

  • name -- имя переменной, в которой сохраняются введенные данные;
  • rows -- количество строк в текстовой области;
  • cols -- количество столбцов в текстовой области.

Текстовая область изображена на рис. 10.2.

Рис. 10.2. Текстовая область

Элементы форм, ориентированные на ввод с мыши

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

Флажки (checkboxes) используются в ситуациях, когда пользователь выбирает один или несколько вариантов из готового набора -- по аналогии с тем, как ставятся «галочки» в анкетах. Синтаксис определения флажка:

Определение флажка включает три атрибута:

  • type -- тип элемента (для флажков -- checkbox);
  • value -- значение, присваиваемое переменной по умолчанию. Если флажок установлен, именно это значение будет присвоено переменной с указанным именем. Если флажок не установлен, значение атрибута value не используется.

Флажок изображен на рис. 10.3.

Рис. 10.3. Флажок

Переключатель

Переключатель (radio button) представляет собой разновидность флажка; он работает практически так же за одним исключением -- в любой момент времени в группе может быть установлен лишь один переключатель. Синтаксис определения переключателя:

Как видите, синтаксис почти не отличается от определения флажка. Определение переключателя поля включает три атрибута:

  • type -- тип элемента (для переключателей -- radio);
  • name -- имя переменной, в которой сохраняются введенные данные (в данном случае -- состояние элемента);
  • value -- значение, присваиваемое переменной по умолчанию. Если переключатель установлен, именно это значение будет присвоено переменной с указанным именем. Если флажок не установлен, значение атрибута value не используется.

Переключатель изображен на рис. 10.4.

Рис. 10.4. Переключатель

Раскрывающийся список

Раскрывающиеся списки особенно удобны в ситуации, когда у вас имеется длинный перечень допустимых вариантов, из которого пользователь должен выбрать один вариант. Как правило, раскрывающиеся списки применяются при работе с относительно большими наборами данных -- например, при перечислении американских штатов или стран. Синтаксис определения раскрывающегося списка:

Определение скрытого поля включает три атрибута:

  • type -- тип элемента (для скрытых полей -- hidden);
  • name -- имя переменной, в которой сохраняются скрытые данные;
  • value -- значение, по умолчанию сохраняемое в скрытом поле.

Вообще говоря, название этого элемента -- скрытое поле -- несколько неточно. Хотя скрытые поля не отображаются в браузерах, пользователь может просто выполнить команду View Source и увидеть, какие скрытые значения хранятся в форме.

Кнопка отправки данных

Кнопка отправки данных инициирует действие, заданное атрибутом action тега . Синтаксис определения:

  • type -- тип элемента (для кнопки отправки данных -- submit);

Рис. 10.6. Кнопка отправки данных

Кнопка сброса

Кнопка сброса отменяет все изменения, внесенные в элементы формы. Обычно никто ею не пользуется, однако кнопки сброса так часто встречаются на формах в Web, что я решил привести ее описание. Синтаксис определения:

=" текст _на_кнопке">

Определение кнопки включает два атрибута:

  • type -- тип элемента (для кнопки сброса -- reset);
  • value -- текст, по умолчанию отображаемый на кнопке.

Кнопка сброса выглядит точно так же, как и кнопка отправки данных, если не считать того, что на ней обычно выводится слово «Reset» (рис. 10.6).

Все вместе: пример формы

От описания базовых компонентов форм мы переходим к практическому примеру -- построению формы для обработки данных, введенных пользователем. Допустим, вы хотите создать форму, в которой пользователь может высказать мнение о вашем Сайте. Пример такой формы приведен в листинге 10.1.

Листинг 10.1. Пример формы для сбора данных

Please take a moment to tell us what you think about our site:

Name:


Email:


How frequently do you visit our site?:


I frequently purchase the following products from our site:

Software

Cookware

Chef"s Hats

0ur site"s greatest asset is:

Product selection

Cool design

Customer Service

Comments:


Внешний вид формы в браузере изображен на рис. 10.7.

Рис. 10.7. Пример формы для ввода данных

Вроде бы все понятно. Возникает вопрос -- как получить данные, введенные пользователем, и сделать с ними что-нибудь полезное? Этой теме посвящен следующий раздел, «Формы и PHP».

Не забывайте: все сказанное ранее -- не более чем вводный курс. Приведенная информация ни в коем случае не исчерпывает всех возможностей, предоставляемых различными компонентами форм. За дополнительной информацией обращайтесь к многочисленным учебникам по работе с формами, опубликованным в Web, а также книгам по HTML.

От предварительного знакомства с формами HTML мы переходим к самому интересному -- применению PHP для обработки данных, введенных пользователем в форме.

Формы и PHP

Обработка данных в формах имеет много общего с обработкой переменных, передаваемых в URL, -- эта тема подробно рассматривалась в предыдущей главе.

Вводные примеры

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

Пример 1: передача данных формы из одного сценария в другой

В первом примере представлена характерная ситуация -- когда пользовательские данные вводятся на одной странице и отображаются на другой. В листинге 10.2 приведен код формы для ввода имени пользователя и адреса электронной почты. Когда пользователь щелкает на кнопке отправки данных (кнопка Go!), форма обращается к странице, приведенной в листинге 10.3. В свою очередь, листинг 10.3 выводит переменные $name и $mail, переданные с запросом.

Листинг 10.2. Простая форма

Listing 10-2

Give us some information!

Your Name:


Your Email:


Листинг 10.3. Отображение данных, введенных в листинге 10.1

Listing 10-3

// Вывести имя и адрес электронной почты.

В общих чертах происходит следующее: пользователь заполняет поля формы и нажимает кнопку отправки данных. Управление передается странице, приведенной в листинге 10.3, где происходит форматирование и последующее отображение данных. Как видите, все просто.

Существует и другой способ обработки данных форм, при котором используется всего один сценарий. К недостаткам этого способа относятся увеличение сценария и как следствие -- затруднения с редактированием и сопровождением. Впрочем, есть и достоинства -- уменьшение количества файлов, с которыми вам приходится работать. Более того, в этом варианте сокращается избыточный код при проверке ошибок (эта тема рассматривается ниже в данной главе). Конечно, в некоторых ситуациях работать с одним сценарием неудобно, но, по крайней мере, вы должны знать об этой возможности. В примере 2 воспроизводится пример 1, но с использованием лишь одного сценария.

Пример 2: альтернативная обработка формы (с одним сценарием)

Обработка данных формы в одном сценарии реализуется относительно просто. Вы проверяете, были ли присвоены значения переменным формы. Если значения присвоены, сценарий обрабатывает их (в нашем примере -- просто выводит), а если нет -- отображает форму. Решение о том, было ли задано значение переменной или нет, принимается при помощи функции strcmp(), описанной в главе 8. Пример реализации формы с одним сценарием приведен в листинге 10.4. Обратите внимание: атрибут action формы ссылается на ту же страницу, в которой определяется сама форма. Условная команда i f проверяет состояние переменной скрытого поля с именем $seenform. Если значение $seenform не задано, форма отображается в браузере, а если задано -- значит, форма была заполнена пользователем и введенные данные обрабатываются сценарием (в данном примере -- просто выводятся в браузере).

Листинг 10.4. Ввод данных на форме в одном сценарии

Listing 10-4

// Все кавычки внутри $form должны экранироваться,

Give us some information!

Your Name:


Your Email:


// Для проверки используется значение скрытой переменной $seenform.

if ($seenform != "у"):

print "Hi. $name!. Your email address is $email";

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

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

Пример 3: автоматическая отправка данных по электронной почте

Вывести пользовательские данные в браузере несложно, но вряд ли это можно назвать содержательной обработкой пользовательского ввода. Один из способов обработки информации заключается в ее отправке по электронной почте -- например, администратору сайта. Хотя при помощи гиперссылки mailto: можно отправить сообщение прямо из браузера, следует учитывать, что внешние приложения электронной почты настроены не на каждом компьютере. Следовательно, отправка сообщений с web-формы более надежно гарантирует, что сообщение будет доставлено адресату.

В следующем разделе, mail(), создается небольшая форма, в которой пользователь вводит информацию и комментарии по поводу сайта. Затем данные форматируются соответствующим образом и передаются стандартной функции PHP mail(). Но прежде чем переходить к построению формы, необходимо предварительно рассмотреть синтаксис функции mail().

Функция mail() отправляет сообщение заданному адресату по электронной почте. Синтаксис функции mail():

boolean mail (string получатель, string тема, string сообщение [, string доп_заголовки])

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

В системе UNIX функция mail() использует утилиту sendmail. В Windows эта функция работает лишь при наличии установленного почтового сервера или если функция mail() связана с работающим сервером SMTP. Эта задача решается модификацией переменной SMTP в файле php.ini.

Если вы сделали все необходимое и функция mail() работает в вашей системе, попробуйте выполнить следующий фрагмент (конечно, адрес [email protected] заменяется вашим настоящим адресом электронной почты):

$email = "[email protected]";

$subject = "This is the subject";

$message = "This is the message";

$headers = "From: [email protected]";

mail ($email, $subject, $message, $headers);

Хотя при обширной переписке, конечно, следует использовать специализированные почтовые программы вроде majordomo (http://www.greatcircle.com/majordomo), в простых случаях функции PHP mail() оказывается вполне достаточно.

Итак, после знакомства с функцией mail() можно применить ее на практике. В листинге 10.5 показано, как получить информацию от пользователя и отправить ее по адресу, заданному администратором сценария.

Листинг 10.5. Пересылка пользовательских данных функцией mail()

Listing 10-5

// Все кавычки внутри $form должны экранироваться.

// в противном случае произойдет ошибка.

Send us your comments!

Your Name:


Your Email:


Your Comments:


// Если форма ранее не отображалась, отобразить ее.

// Для проверки используется значение скрытой переменной $seenform.

if ($seenform != "у") :

print "$form"; else:

// Переменная $recipient определяет получателя данных формы

$recipient = "[email protected]";

// Тема сообщения

$subject = "User Comments ($name)";

// Дополнительные заголовки $headers = "From: $email";

// Отправить сообщение или выдать сообщение об ошибке

mail($recipient, $subject, $comments, $headers) or die("Could not send email!");

// Вывести сообщение для пользователя

print "Thank you $name for taking a moment to send us your comments!";

Неплохо, правда? Листинг 10.5 работает так же, как листинг 10.4; сначала мы проверяем, отображалась ли форма ранее. Если это происходило, программа вызывает функцию mail() и пользовательские данные отправляются по адресу, определяемому переменной $recipient. Затем в браузере выводится благодарственное сообщение для пользователя.

Простейшим расширением этого примера будет отправка благодарственного сообщения по электронной почте (вторым вызовом mail()). Следующий пример развивает эту идею -- пользователю предлагается на выбор несколько бюллетеней. Выбранные бюллетени отправляются по электронной почте.

Пример 4: отправка запрашиваемой информации по электронной почте

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

Информационные сообщения хранятся в отдельных файлах. В нашем примере используются три текстовых файла:

  • site.txt -- информация о сайте;
  • team.txt -- информация о талантливых разработчиках сайта;
  • events.txt -- приглашение на очередное мероприятие.

Исходный текст примера приведен в листинге 10.6.

Листинг 10.6. Отправка информации, запрашиваемой пользователем

Listing10-5

Receive information about our site!

Your Email:


Site Architecture

Development Team

Upcoming Events

if ($seenform != "y") :

print "$form"; else:

$headers = "From: [email protected]";

// Перебрать все пары "ключ/значение"

while (list($key, Sval) = each ($information)) :

// Сравнить текущее значение с "у" if ($val == "у") :

// Построить имя файла, соответствующее текущему ключу

$filename = "$key.txt":

$subject = "Requested $key information";

// Открыть файл

$fd = fopen ($filename, "r");

// Отправить сообщение

mail($email, $subject, $contents, $headers) or die("Can"t send email!");; fclose($fd);

// Известить пользователя об успешной отправке

print sizeof($information)." informational newsletters

have been sent to $email!";

В листинге 10.6 мы перебираем пары «ключ/значение» в цикле while и отправляем только те бюллетени, у которых значение равно у. Следует помнить, что имена текстовых файлов должны соответствовать ключам массива

(site.txt, team.txt и events.txt). Имя файла строится динамически по ключу, после чего файл открывается по имени и его содержимое загружается в переменную ($contents). Затем переменная $contents передается функции mail() в качестве параметра.

В следующем примере пользовательские данные сохраняются в текстовом файле.

Пример 5: сохранение пользовательских данных в текстовом файле

Пользовательские данные сохраняются в текстовом файле для последующего статистического анализа, поиска и т. д. -- короче, любой обработки по вашему усмотрению. В листинге 10.7, как и в предыдущих примерах, данные формы обрабатываются в одном сценарии. Пользователю предлагается ввести четыре объекта данных: имя, адрес электронной почты, язык и профессию. Введенная информация сохраняется в текстовом файле user_information.txt. Элементы данных разделяются символами «вертикальная черта» (|).

Листинг 10.7. Сохранение пользовательской информации в текстовом файле

// Создать форму

Give us your personal info!

Your Name:


Your Email:


Your Preferred Language:


Your Occupation:""ibr>


// Заполнялась ли форма ранее? if ($seenform != "у") :

print "$form"; else:

$fd = fopen("useMnformation.txt", "a");

// Убедиться, что во введенных данных не встречается

// вертикальная черта.

$name = str_replace("|", "", $name);

$email = str_replace("|", "", $email);

// Построить строку с пользовательскими данными

$user_row = $name." ".$email."|".$language." ".$job."\n";

fwrite($fd, $user_row) or die("Could not write to file!");

print "Thank you for taking a moment to fill out our brief questionnaire!":

Обратите внимание на фрагмент, в котором мы проверяем, что пользователь не включил в имя или адрес электронной почты символы «вертикальная черта» (|). Функция str_replace() удаляет эти символы, заменяяих пустой строкой. Если бы это не было сделано, пользовательские символы | нарушили бы структуру файла данных и существенно затруднили (а то и сделали невозможным) его правильную обработку.

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

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

Проверка ошибок

Обработка пользовательских данных дает осмысленный результат лишь в том случае, если данные имеют правильную структуру. Проверить достоверность введенных данных невозможно, однако вы можете проверить их целостность (например, убедиться в том, что адрес электронной почты соответствует стандартному шаблону). Хотя для проверки данных часто применяется технология JavaScript, могут возникнуть проблемы с несовместимостью браузеров. Поскольку код PHP выполняется на стороне сервера, вы всегда можете быть уверены в том, что проверка данных формы даст нужный результат (конечно, при условии правильности вашей программы).

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

Пример 6: вывод информации о пустых или ошибочно заполненных полях формы

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

Мы последовательно проверяем все поля формы и убеждаемся в том, что они не остались пустыми. Там, где это возможно, проверяется правильность структуры введенных данных. Если проверка прошла успешно, мы переходим к следующему полю; в противном случае программа выводит сообщение об ошибке, устанавливает флаг, который позднее используется для повторного отображения формы, и переходит к следующему полю. Процедура повторяется до тех пор, пока не будут проверены все поля формы (листинг 10.8).

Листинг 10.8. Проверка данных формы и вывод сообщений об ошибках

Listing 10-8

// Создать форму

Give us some information!

Your Name:


Your Email:


// Заполнялась ли форма ранее?

if ($seenform != "у"):

// Пользователь заполнил форму. Проверить введенные данные, else:

$error_flag = "n";

// Убедиться в том. что поле имени содержит информацию

if ($name == "") :

print "* You forgot to enter your name!


":

$error_flag = "y";

// Убедиться в том. что поле адреса содержит информацию

if ($email == "") :

print "* You forgot to enter your email !


"

$error_flag = "y";

// Преобразовать все алфавитные символы в адресе

// электронной почты к нижнему регистру

$email = strtolower(trim($email)):

// Убедиться в правильности синтаксиса

// адреса электронной почты

if (! @eregi("^+".

"(+\.)+".

"(){2.4}$". $email)) :

print "* You entered an invalid email address!


" :

$error_flag = "y";

// Если флаг ошибки $error_flag установлен.

// заново отобразить форму

if ($error_flag == "у") : print "$form";

// Обработать данные пользователя

print "You entered valid form information!";

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

за необходимым товаром или услугой в другое место.

Динамическое конструирование форм

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

В следующем разделе я представлю сценарий, в котором раскрывающийся список строится динамически по содержимому массива. Этот прием несложен, однако

он экономит немало времени как при исходном программировании, так и при последующем сопровождении программы.

Пример 7: построение раскрывающегося списка

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

В листинге 10.9, как и в предыдущих примерах, реализован вариант с одним сценарием. Сначала мы проверяем, было ли присвоено значение переменной $site. Если проверка дает положительный результат, вызывается функция header() с параметром, в котором значение $site присоединяется к строке «Location:http://». При передаче этой команды функция header О перенаправляет браузер на указанный URL. Если значение переменной $site не задано, форма выводится в браузере. Раскрывающийся список строится в цикле, количество итераций зависит от размера массива Sfavsites. В листинге 10.9 я включил в этот массив пять своих любимых сайтов. Конечно, вы можете добавить в него сколько угодно своих сайтов.

Запомните одно важное обстоятельство -- функция header() должна вызываться до вывода данных в браузере. Ее нельзя просто вызвать в любой точке сценария PHP. Несвоевременные вызовы header() порождают столько проблем у неопытных программистов PHP, что я рекомендую повторить это правило раз пять, чтобы лучше запомнить его.

Листинг 10.9. Динамическое построение раскрывающегося списка

if ($site != "") :

header("Location: http://Ssite");

Listing 10-9</Fit1e></p> <p><body bgcolor="#ffffff" text="#000000" Iink="#cbda74" vlink="#808040" alink="#808040"</p> <p>$favsites = array ("www.k10k.com". "www.yahoo.com",</p> <p>"www.drudgereport.com",</p> <p>"www.phprecipes.com",</p> <p>"www.frogdesign.com"):</p> <p>// Создать форму</p> <p><form action = "Listing10-9.php" method="post"></p> <p><select name="site"></p> <p><option value = "">Choose a site:</p> <p>while ($х < sizeof ($favsites)) :</p> <p>print "<option value="$favsites[$x]">$favsites[$x]";</p> <p><input type="submit" value="go!"></p> <p>Динамическое конструирование форм особенно удобно при обработке больших объемов данных, которые в любой момент могут измениться, что приведет к устареванию всей жестко закодированной информации форм. Впрочем, я рекомендую жестко кодировать все статические данные (например, список штатов США), поскольку это ускорит работу программы.</p> <h2>Проект: Пишем гостевую книгу на PHP</h2> <p>Прежде всего создается инициализационный файл, содержащий некоторые глобальные переменные и функции приложения (листинг 10.10).</p> <b> <i> </i> </b><p>Листинг 10.10. <i> Файл init.inc, используемый при создании гостевой книги </i></p> <p>// Файл: init.inc</p> <p>// Назначение: глобальные переменные и функции для проекта гостевой книги</p> <p>// Заголовок страницы по умолчанию</p> <p>$title = "My Guestbook";</p> <p>// Цвет фона</p> <p>$bg_color = "white": /</p> <p>// Гарнитура шрифта</p> <p>$font_face = "Arial, Verdana, Times New Roman";</p> <p>// Цвет шрифта</p> <p>$font_color = "black";</p> <p>// Дата отправки $post_date - date("M d y");</p> <p>// Файл данных гостевой книги</p> <p>$guest_file = "comments.txt";</p> <p>// Функция читает данные гостевой книги</p> <p>//и отображает их в браузере</p> <p>function view_guest($guest_file) {</p> <p>GLOBAL $font_face, $font_color;</p> <p>print "Return to <a href=\"index.php\">index</a>,<br><br>";</p> <p>// Если в файле гостевой книги имеются данные...</p> <p>if (filesize($guest_file) > 0) :</p> <p>// Открыть файл данных гостевой книги</p> <p>$fh = fopen($guest_file. "r") or die("Couldn"t open $guest_file");</p> <p>print "<table border=1 cellpadding=2 cellspacing=0 width=\"600\">";</p> <p>// Повторять до конца файла</p> <p>$line <= fgetsdfh, 4096);</p> <p>// Разбить строку на компоненты</p> <p>// и присвоить каждый компонент переменной</p> <p>list($date. $name, $email, $comments) = explode("|", $line):</p> <p>// Если указано имя посетителя, вывести его</p> <p>if ($name != "") :</p> <p>print "<tr>":</p> <p>print "<td><font color=\"$font_co!or\"</p> <p>face=\"$font_face\">Date:</font></td>";</p> <p>print "<td><font color=\"$font_color\"</p> <p>face=\"$font_face\">$date</font></td>";</p> <p>print "</tr>";</p> <p>print "<tr>";</p> <p>print "<td><font color=\"$font_color\"</p> <p>face=\"$font_face\">Name:</font></td>";</p> <p>print "<td><font color=\"$font_color\"</p> <p>face=\"$font_face\">$name</font></td>";</p> <p>print "</tr>";</p> <p>print "<tr>";</p> <p>print "<td><font color=\"$font_color\"</p> <p>face=\"$font_face\">Email:</font></td>";</p> <p>print "<td><font color=\"$font_color\"</p> <p>face=\"$font_face\">$email</font></td>";</p> <p>print "</tr>";</p> <p>print "<tr>";</p> <p>print "<td valign=\"top\"><font color=\"$font_color\"</p> <p>face=\"$font_face\">Message:</font></td>";</p> <p>print "<td><font color=\"$font_color\"</p> <p>face=\"$font_face\">$comments</font></td>";</p> <p>print "</tr>";</p> <p>print "<tr><td colspan=\"2\"> :</td></tr>";</p> <p>print "</table>";</p> <p>// Закрыть файл</p> <p>print "<h3>Currently there are no entries in the guestbook!</h3>";</p> <p>// Функция сохраняет новую информацию в файле данных</p> <p>function add_guest($name, $email, $comments) {</p> <p>GLOBAL $post_date, $guest_file;</p> <p>// Отформатировать данные для ввода,</p> <p>$contents = "$post_date|$name|$email |$comments\n";</p> <p>// Открыть файл данных</p> <p>$fh = fopen($guest_file. "a") or dieC"Could not open $guest_file!");</p> <p>// Записать данные в файл</p> <p>$wr = fwrite($fh, $contents) or die("Could not write to $guest_file!");</p> <p>// Закрыть файл fclose($fh);</p> <p>Затем создаются еще три файла: файл ссылок index.php, файл add_guest.php для вывода информации гостевой книги и файл view_guest.php для ввода новых данных. Файл index.php (листинг 10.11) просто отображает две ссылки для выполнения основных функций гостевой книги -- просмотра и добавления новых данных. Эти ссылки легко включаются в сайт, имеющий более сложную структуру.</p> <i> </i><p><b> Листинг 10.11. </b> Файл index.php со ссылками для просмотра и добавления новых данных в гостевую книгу</p> <p>INCLUDE("init.inc");</p> <p><title><?=$page_title;?>

View the guestbook!

Sign the guestbook!

Файл view_guest.php (листинг 10.12) выводит всю информацию гостевой книги, хранящуюся в файле данных.

Листинг 10.12. Файл view_guest.php

INCLUDE("init.inc");

vi ew_guest ($guest_file);

Файл add_guest.php (листинг 10.13) запрашивает у пользователя новые данные для внесения в гостевую книгу. Введенная информация записывается в файл данных.

Листинг 10.13. Файл add_guest.php

INCLUDE("init.inc");

<?=$page_title:?>

// Если форма еще не отображалась - запросить данные у пользователя

if (! $seenform) :



Comment:


// Форма уже отображалась - добавить данные в текстовый файл.

add_guest($name, $email, $comment);

print "

Your comments have been added to the guestbook.

Click here to return to the index.

";

К числу основных преимуществ модульной разработки приложений относится простота адаптации для других систем. Допустим, вы решили перейти от хранения данных в текстовом файле к использованию базы данных. Стоит изменить содержимое add_guest() и view_guest(), и ваша гостевая книга перейдет на работу с базой данных.

На рис. 10.8 показано, как выглядит гостевая книга после сохранения пары записей.

Рис. 10.8. Просмотр гостевой книги (view_guest.php)

Информация, показанная на рис. 10.8, хранится в файле данных в следующем виде:

Oct 29 00|Michele|[email protected]|I love cheese!

Oct 29 00|Nino|[email protected]|Great site!

Итоги

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

  • общие сведения о синтаксисе форм;
  • передача данных форм между сценариями PHP;
  • обработка форм в одном сценарии;
  • функция mail();
  • отправка данных формы по электронной почте;
  • автоматическая обработка пользовательских запросов на получение информации;
  • сохранение данных пользователя в текстовом файле;
  • проверка ошибок;
  • динамическое конструирование форм.

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

В основном, для передачи параметров используются методы POST и GET .
Главное отличие методов POST и GET заключается в способе передачи информации. В методе GET параметры передаются через адресную строку (URL ), т.е. в HTTP -заголовке запроса, в то время как в методе POST параметры передаются через тело HTTP -запроса и никак не отражаются в адресной строке.

1. Кнопки – Тег

Тег обязателен.
Параметры:
disabled – блокирует доступ и изменение элемента.
type – тип кнопки
value – Значение кнопки, которое будет отправлено на сервер или прочитано с помощью сприптов.


Параметр DISABLED
Блокирует доступ и изменение кнопки. Она в таком случае отображается серой и недоступной для активации пользователем. Кроме того, такая кнопка не может получить фокус путем нажатия на клавишу Tab , мышью или другим способом. Тем не менее, такое состояние кнопки можно изменять через скрипты.

Параметр TYPE
Определяет тип кнопки, который устанавливает ее поведение в форме. По внешнему виду кнопки разного типа никак не различаются, но у каждой такой кнопки свои функции. Значение по умолчанию: button .
Аргументы:
button – Обычная кнопка.
reset – Кнопка для очистки введенных данных формы и возвращения значений в первоначальное состояние.

Submit – Кнопка для отправки данных формы на сервер.

Параметр VALUE Определяет значение кнопки, которое будет отправлено на сервер. На сервер отправляется пара «имя=значение », где имя задается параметром name тега

1.1. Кнопка (input type=button)
1.2. Кнопка с изображением (input type=image)

Кнопки с изображениями аналогичны по действию кнопке Submit , но представляют собой рисунок. Для этого задаем type=image и src="image.gif" .

Когда пользователь щелкнет где-нибудь на изображении, соответствующая форма будет передана на сервер с двумя дополнительными переменными – sub_x и sub_y . Они содержат координаты нажатия пользователя на изображение. Опытные программисты могут заметить, что на самом деле имена переменных, отправленных браузером, содержат точку, а не подчеркивание, но PHP автоматически конвертирует точку в подчеркивание.

1.3. Кнопка отправки формы (input type=submit)

Служит для отправки формы сценарию. При создании кнопки для отправки формы необходимо указать 2 атрибута: type="submit" и value="Текст кнопки" . Атрибут name необходим, если кнопка не одна, а несколько и все они созданы для разных операций, например кнопки "Сохранить", "Удалить", "Редактировать" и т.д. После нажатия на кнопку сценарию передается строка имя=текст кнопки.


РНР -сценарий не требуется.

1.4. Массив кнопок (submit) для выбора варианта действий
2. Кнопка сброса формы (Reset)

При нажатии на кнопку сброса (reset ), все элементы формы будут установлены в то состояние, которое было задано в атрибутах по умолчанию, причем отправка формы не производиться.


РНР -сценарий не требуется.

3. Флажок (checkbox)

Флажки checkbox предлагают пользователю ряд вариантов, и разрешает произвольный выбор (ни одного, одного или нескольких из них).

Белый
Зеленый
Синий
Красный
Черный
$go) { echo $index." - > ".$go."
"; }; };

4. Переключатель(radio)

Переключатели radio предлагают пользователю ряд вариантов, но разрешает выбрать только один из них.
Пример 1.

Белый
Зеленый
Синий
Красный
Черный

Пример 2.
// первый набор кнопок
// второй набор кнопок
// третий набор кнопок
\n"; ?>

5. Текстовое поле (text)

При создании обычного текстового поля размером size и максимальной допустимой длины maxlength символов, атрибут type принимает значение text . Если указан параметр value , то поле будет отображать указанный в переменной value. При создании поля не забывайте указывать имя поля, т.к. этот атрибут является обязательным.

6. Поле для ввода пароля (password)

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

7. Скрытое текстовое поле (hidden)

Позволяет передавать сценарию какую то служебную информацию, не отображая её на странице.

8. Выпадающий список (select)

Тэг . Теги позволяют определить содержимое списка, а параметр value определяет значение строки. Если в теге указан параметр selected , то строка будет изначально выбранной. Параметр size задает, сколько строк будет занимать список. Если size равен 1 , то список будет выпадающим. Если указан атрибут multiple , то разрешено выбирать несколько элементов из списка. Но эта схема практически не используется, а при size = 1 не имеет смысла.

Если необходимо создать выпадающий с предсказуемой последовательностью. Например, список с годами с 2000 по 2050. То используется следующий прием.

9. Многострочное поле ввода текста (textarea)

Многострочное поле ввода текста позволяет отправлять не одну строку, а сразу несколько. При необходимости можно указать атрибут readonly , который запрещает редактировать, удалять и изменять текст, т.е. текст будет предназначен только для чтения. Если необходимо чтобы текст был изначально отображен в многострочном поле ввода, то его необходимо поместить между тэгами .
Существует параметр wrap – задание переноса строк. Возможные значения:
off – отключает перенос строк;
virtuals – показывает переносы строк, но отправляет текст как он введен;
physical – переносы строк оставляются в исходном виде.
По умолчанию тег

Для того, чтобы в многострочном текстовом поле соблюдалось html-форматирование (перенос строк по средством тега
или
), то используйте функцию nl2br() :

10. Кнопка для загрузки файлов (browse)

Служит для реализации загрузки файлов на сервер. При создании текстового поля также необходимо указать тип поля type как "file" .

Загрузить файл:

Способы общения браузера с сервером

Способов, предоставляемых протоколом HTTP , немного. Это важная информация. Никаких других способов нет. На практике используются два:
GET – это когда данные передаются в адресной строке, например, когда пользователь жмет ссылку.
POST – когда он нажимает кнопку в форме.

Метод GET

Чтобы передать данные методом GET не надо создавать на HTML -странице форму (использовать формы для запросов методом GET вам никто не запрещает) – достаточно ссылки на документ с добавлением строки запроса, которая может выглядеть как переменная=значение. Пары объединяются с помощью амперсанда &, а к URL страницы строка присоединяется с помощью вопросительного знака «? ».
Но можно не использовать пары ключ=значение, если надо передать всего одну переменную – для этого надо после знака вопроса написать ЗНАЧЕНИЕ (не имя) переменной.
Преимущество передачи параметров таким способом заключается в том, что клиенты, которые не могут использовать метод POST (например, поисковые машины), все же смогут, просто пройдя по ссылке, передать параметры скрипту и получить содержимое.
Недостаток в том, что просто изменив параметры в адресной строке, пользователь может повернуть ход сценария непредсказуемым образом и это создает огромную дыру в безопасности, в сочетании с неопределенными переменными и register_globals on или кто-нибудь может узнать значение важной переменной (например ID -сеcсии), просто посмотрев на экран монитора.
:
- для доступа к общедоступным страницам с передачей параметров (повышение функциональности)
- передача информации, не влияющей на уровень безопасности
:
- для доступа к защищенным страницам с передачей параметров
- для передачи информации, влияющей на уровень безопасности
- для передачи информации, не подлежащей модифицированию пользователем (некоторые передают текст SQL -запросов.

Метод POST

Передать данные методом POST можно только с помощью формы на HTML странице. Основное отличие POST от GET в том, что данные передаются не в заголовке запроса а в теле, следовательно, пользователь их не видит. Модифицировать можно только изменив саму форму.
Преимущество :
- большая безопасность и функциональность запросов с помощью форм методом POST .
Недостаток :
- меньшая доступность.
Для чего следует использовать :
- для передачи большого объема информации (текст, файлы..);
- для передачи любой важной информации;
- для ограничения доступа (например, использовать для навигации только форму – возможность, доступная не всем программам-роботам или грабберам-контента).
Для чего не следует использовать :

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

//Форма для загрузки файлов

Отправить этот файл:

В приведенном выше примере "URL " необходимо заменить ссылкой на PHP -скрипт. Скрытое поле MAX _FILE_SIZE (значение необходимо указывать в байтах) должно предшествовать полю для выбора файла, и его значение является максимально допустимым размером принимаемого файла. Также следует убедиться, что в атрибутах формы вы указали enctype="multipart/form-data" , в противном случае загрузка файлов на сервер выполняться не будет.
Внимание
Опция MAX _FILE_SIZE является рекомендацией браузеру, даже если бы PHP также проверял это условие. Обойти это ограничение на стороне браузера достаточно просто, следовательно, вы не должны полагаться на то, что все файлы большего размера будут блокированы при помощи этой возможности. Тем не менее, ограничение PHP касательно максимального размера обойти невозможно. Вы в любом случае должны добавлять переменную формы MAX _FILE_SIZE , так как она предотвращает тревожное ожидание пользователей при передаче огромных файлов, только для того, чтобы узнать, что файл слишком большой и передача фактически не состоялась.

Как определить метод запроса?

Напрямую:

Getenv("REQUEST_METHOD");

вернет GET или POST .

Какой способ следует применять?

Если форма служит для запроса некой информации, например – при поиске, то ее следует отправлять методом GET . Чтобы можно было обновлять страницу, можно было поставить закладку и/или послать ссылку другу.
Если же в результате отправки формы данные записываются или изменяются на сервере, то следует их отправлять методом POST , причем обязательно, после обработки формы, надо перенаправить браузер методом GET . Так же, POST может понадобиться, если на сервер надо передать большой объём данных (у GET он сильно ограничен), а так же, если не следует "светить" передаваемые данные в адресной строке (при вводе логина и пароля, например).
В любом случае, после обработки POST надо всегда перенаправить браузер на какую-нибудь страницу, пусть ту же самую, но уже без данных формы, чтобы при обновлении страницы они не записывались повторно.

Как передать данные в другой файл непосредственно из тела PHP -программы методом GET и POST ?

Пример, для демонстрации отправки данных методом POST и GET одновременно и получения ответа от сервера.



Эта статья также доступна на следующих языках: Тайский

  • Next

    Огромное Вам СПАСИБО за очень полезную информацию в статье. Очень понятно все изложено. Чувствуется, что проделана большая работа по анализу работы магазина eBay

    • Спасибо вам и другим постоянным читателям моего блога. Без вас у меня не было бы достаточной мотивации, чтобы посвящать много времени ведению этого сайта. У меня мозги так устроены: люблю копнуть вглубь, систематизировать разрозненные данные, пробовать то, что раньше до меня никто не делал, либо не смотрел под таким углом зрения. Жаль, что только нашим соотечественникам из-за кризиса в России отнюдь не до шоппинга на eBay. Покупают на Алиэкспрессе из Китая, так как там в разы дешевле товары (часто в ущерб качеству). Но онлайн-аукционы eBay, Amazon, ETSY легко дадут китайцам фору по ассортименту брендовых вещей, винтажных вещей, ручной работы и разных этнических товаров.

      • Next

        В ваших статьях ценно именно ваше личное отношение и анализ темы. Вы этот блог не бросайте, я сюда часто заглядываю. Нас таких много должно быть. Мне на эл. почту пришло недавно предложение о том, что научат торговать на Амазоне и eBay. И я вспомнила про ваши подробные статьи об этих торг. площ. Перечитала все заново и сделала вывод, что курсы- это лохотрон. Сама на eBay еще ничего не покупала. Я не из России , а из Казахстана (г. Алматы). Но нам тоже лишних трат пока не надо. Желаю вам удачи и берегите себя в азиатских краях.

  • Еще приятно, что попытки eBay по руссификации интерфейса для пользователей из России и стран СНГ, начали приносить плоды. Ведь подавляющая часть граждан стран бывшего СССР не сильна познаниями иностранных языков. Английский язык знают не более 5% населения. Среди молодежи — побольше. Поэтому хотя бы интерфейс на русском языке — это большая помощь для онлайн-шоппинга на этой торговой площадке. Ебей не пошел по пути китайского собрата Алиэкспресс, где совершается машинный (очень корявый и непонятный, местами вызывающий смех) перевод описания товаров. Надеюсь, что на более продвинутом этапе развития искусственного интеллекта станет реальностью качественный машинный перевод с любого языка на любой за считанные доли секунды. Пока имеем вот что (профиль одного из продавцов на ебей с русским интерфейсом, но англоязычным описанием):
    https://uploads.disquscdn.com/images/7a52c9a89108b922159a4fad35de0ab0bee0c8804b9731f56d8a1dc659655d60.png