Все сталкивались с тривиальной задачей — создание формы для отправки по e-mail.
Обычно не возникает никаких проблемм. Но и работа эта не столь интересна и увлекательна. Простая рутина.
Возникает идея создать программу, которая автоматизировала бы этот процесс.
Для начала определим задачу.
Предположим, нам нужно создать формы на сайте.
В формах может присутствовать:
заголовок раздела формы
текстовое поле (text)
текстовый блок (textarea)
поле пароля (password)
поле выбора из списка (select)
поле checkbox
поле радио буттона (radio)
невидимое поле (hidden)
поле загрузки файла (file)
Отсылать письма предполагается в текстовом виде с аттачами. Письма в формате html не пользуются популярностью у народа.
Должна быть проверка на заполненность полей, обязательных к заполнению.
Вот все пункты задачи готовы.
Решено сделать 3 файла:
файл с формой
файл отправки формы
файл инициализации формы
Забегая вперед, могу предположить, что кто-то захочет положить файлы программы (первые два) в отдельный каталог, например forms, и будет просто инклюдить файл с формой на нужных страницах сайта, передавая ему параметром путь к файлу инициализации данной формы. Так как формы могут все-таки отличаться друг от друга в оформлении, я не стану городить огромный файл с бесконечным количеством вариантов и приведу полностью рабочий пример, работающий на сайте «Седьмого континента» в разделе «поставщики», а также на сайте gipragor.ru в разделе «задать вопрос».
Добавлю, что в наших случаях в формах были вариации вида полей text, textarea (в форме «Седьмого континента» 3 вида поля text). В вашем случае, возможно, понядобится еще несколько вариантов для полей. Все делается аналогично тому, что будет рассмотрено ниже.
Начнем с описания файла инициализации формы.
Ниже приведен текст файла ini.php
Выбор адресата^head^0
Выберите из списка^select^1^mail\tконсультант|info@gipragor.ru|selected\tадмин|totoeval@mtu-net.ru
Ваши координаты^head^0
Имя^text^1
Телефон^text^0
Факс^text^0
<nobr>Е-mail</nobr>^text^0
Я хочу получить ответ по телефону^checkbox^0^checked
Вопрос^head^0
Тема^textarea^1
Вопрос^textarea^1^long
Присоединить файл^file^0^attach
Присоединить файл 2^file^0^attach2
Предыдущая страница^hidden^0^refer
Как видим, каждое поле формы описывается отдельной строкой.
Как я ни старался сделать универсальным оформление всех полей форм, — не получилось.
Вследствие этого, предлагаю такое оформление:
Первым везде идет название поля, которое выводится на экран.
Вторым — тип поля формы:
text
password
textarea
checkbox
radio
hidden
file
Третий — указатель обязательного заполнения поля. Если стоит 1 — поле обязательно. Если параметр пустой или любой отличающийся от 1, то поле не обязательное.
Четвертым указываем дополнительный параметр, если он необходим. У каждого вида поля свои дополнительные параметры:
text — long указывает на то, что поле-строка будет длинной и размещена под названием; обычное поле, без параметра, размещается справа от названия
textarea — то же самое, что и у text
checkbox — checked указывает на то, что чекбокс будет выбран по-умолчанию
radio — четвертым параметром указывается имя группы радио-буттонов, а пятым — checked, как и у checkbox
file — указываем имя указателя массива загружаемых файлов
hidden — указываем параметр, в соответствии с которым в значение этого поля будет подставлено определенное значение, либо параметр будет передан как есть
Ну вот покончили с инициализацией формы.
Теперь попробуем написать программу, выводящую форму пользователю.
Создаем файл index.php с нижеприведенным содержимым.
а кнопки отправки формы и очищения можно задать в файле инициализации,
добавив и их обработку в программе.
-->
</form>
<p>Вы можете задать вопрос.
С вопросом можно отправить файлы.<br>
Ответ вы получите на адрес электронной почты,
указанный в координатах,
либо по телефону, если поставите галочку у соответствующего пункта.</p>
<!--
Яваскрипт, которому мы передали список полей формы, обязательных к заполнению
Он определит после попытки отправки формы, заполненны ли эти поля.
Если не заполнены, то скрипт ругнется и укажет какое поле не заполненно,
установив в него курсор.
-->
<script language="JavaScript">
fields = new Array(<? echo $fields; ?>);
fieldnames = new Array(<? echo $fieldnames; ?>);
function Validate(forma)
{
for(i=0;i<fields.length;i++)
{
field = fields[i];
if (forma.elements[field].value == "")
{
alert("Вы должны заполнить поле \""+fieldnames[i]+"\"");
forma.elements[field].focus();
return false;
}
}
return true;
}
</script>
</td>
</tr>
</table>
<!-- конец -->
Ну вот, наша форма выводится на экран пользователя, и он старательно, прикусив язык, заполняет все её поля.
Но мы-то знаем, что вывести форму и заполнить её — половина дела. Важно получить форму, обработать её и отправить по выбранному или указанному по-умолчанию адресу.
Ниже приведен текст файла отправки письма с аттачами send.php, который мы кладем в папку с index.php.
<?
// определяем, с какой страницы пришел посетитель на страницу отправки
if (strpos($HTTP_REFERER, "gipragor.ru/feedback") === false) {
// если не со страницы отправки формы, то кидаем его в форму
header("location: .");
}
// если посетитель прошел проверку, читаем файл инициализации
$texts=file("ini.php");
// перебираем все строки в файле и сохраняем в новый массив только не пустые
for ($j=0; $j<(sizeof($texts)); $j++)
{
$texts[$j]=trim($texts[$j]);
if ($texts[$j] != "") {$proposal_text[]=$texts[$j];}
}
// Объявляем пустую строковую переменную, в которой будет храниться сообщение
$mailtext="";
// Перебираем все строки массива формы
for ($i=0; $i<(sizeof($proposal_text)); $i++)
{
// Разбиваем строки по разделительному символу ^
// получаем подстроки, в которых хранится:
// 0 - текст названия поля формы
// 1 - тип поля формы
// 2 - указатель обязательности заполнения поля формы
// 3 - дополнительные параметры поля формы
$proposal=explode('^',$proposal_text[$i]);
$type=trim($proposal[1]);
if (isset($proposal[3])) {$proposal[3]=trim($proposal[3]);}
if (!isset($form[$i])) {$form[$i]="нет данных";}
// перебираем варианты типов полей формы
switch ($type)
{
case "head": // если заголовок раздела формы
if ($mailtext != "")
{
// если это не первый заголовок в форме,
// то ставим перед ним 2 пустые строки
$mailtext.="\n\n";
}
$mailtext.="\t$proposal[0]\n";
break;
case "text": // если поле текствое - строка
if (isset($proposal[3]))
{
if ($proposal[3] == "long")
{ // если строка длинная, то
// выводим ее под названием поля
$mailtext.="$proposal[0]:\n$form[$i]\n\n";
}
}
else
{ // если строка не длинная,
// то выводим ее справа от названия поля
$mailtext.="$proposal[0]: $form[$i]\n";
}
break;
case "textarea": // поле текстового блока
$mailtext.="$proposal[0]:\n$form[$i]\n\n";
break;
case "radio": // радио буттон
$group == "$proposal[2]";
$mailtext.="$proposal[0]: $group\n";
break;
case "checkbox": // чекбокс
if (trim($form[$i]) == "on")
{ // если чекбокс выделили, то его значение - on
$mailtext.="$proposal[0]\n";
}
break;
case "hidden": // скрытое поле. Обрабатываем его взависимости от параметра
if (!isset($proposal[3])) {$param = "form[$i]";}
if ($param="refer") {$form[$i]=urldecode($form[$i]);}
$mailtext.="$proposal[0]: $form[$i]\n";
break;
case "file": // поле файла отправляемого пользователем в виде аттача к письму
if (!isset($proposal[3])) {$param = "form[$i]";}
else {$param=$proposal[3];}
// создаем массив из файлов-аттачей
$att_arr[]=$file_att[$param];
$att_arr_type[]=$file_att_type[$param];
$att_arr_name[]=$file_att_name[$param];
break;
case "select": // поле селекта
if (isset($proposal[3])) { // если есть параметры селекта
$options = explode("\t", $proposal[3]);
// разбиваем параметры и перебираем каждую строку
$option_text=explode("|",$options[0]);
// разбиваем первый подпараметр селекта
//на имя селекта и вид (multiselect и обычный)
if ($option_text[0] == "mail") {$mailto=$form[$i];}
// если 0 параметр равен mail -
// значит это варианты e-mail адресата (в нашем случае)
$mailtext.="$proposal[0]: $form[$i]\n";
}
break;
default:
}
}
// удалим из текста формы теги html
$mailtext=strip_tags($mailtext);
// удалим специальные символы из текста формы
// используя стандартный способ из руководства php
// Читаем файл аттача ('rb' = читаем в двоичном виде)
$file = fopen($fileatt,'rb'); // открываем поток
$data = fread($file,filesize($fileatt));
fclose($file); // закрываем поток
// Кодируем Base64 содержимое файла
$data = chunk_split(base64_encode($data));
// Добавляем содержимое файла к сообщению
// с соответствующими заголовком и описанием типа данных
$message .= "--{$mime_boundary}\n".
"Content-Type: {$fileatt_type};\n".
" name=\"{$fileatt_name}\"\n".
"Content-Transfer-Encoding: base64\n\n".
$data."\n\n";
}// так перебираем все отправляемые файлы
}
$message .= "--{$mime_boundary}--\n";
// в конец сообщения добавляем разделительную строку с окончанием сообщения
// Отправляем сообщение
@mail($to, $subject, $message, $headers);
// сообщаем в куки, что письмо отправлено
setcookie ("is_send", "send_query", time()+120);
// переводим пользователя к странице формы
// где ему сообщат, что письмо его отправлено
header("location: .");
?>
Результатом работы программы будет письмо, приходящее на выбранный или указанный по-умолчанию адрес. С письмом может быть прислано произвольное, установленное в инициализации количество файлов-аттачей.
Все вышенаписанное предназначено для начинающих программировать на php, и для полета мысли уже опытных.