Сайтостроительство (8)

PHP-кодинг (25)

Веб-дизайн (9)

DHTML/JavaScript (8)

Подкастинг (1)

Безопасность в PHP (3)

Секретный раздел

Карта блога

Регистрация пользователей на PHP+MySQL

Скрипт гостевой книги с красивым дизайном

Галерея на jQuery

Простая система регистрации пользователей на сессиях

Форма обратной связи с защитой типа капча

Галерея на php+jquery

Шаблоны запросов и placeholders

Быстрое перенаправление средствами php

Flash плеер для вашего сайта

Сортировка столбцов в таблице на php+mysql

Этапы создания сайта

Распределенная система комментирования

Cистема навигации сайта

Перенос длинных строк в комментариях

Блочная верстка сайта

За весь период

За 2010-11

За 2009-06

За 2009-05

За 2009-04

За 2009-03

За 2009-02

За 2008-08

Бегун контекстная реклама

Ruseller видеоуроки

Letitbit файлообменник

Tak.Ru $$$ вебмастеру

WMmail почтовые рассылки

WMlink продажа трафика

Sape.Ru продажа ссылок

Главная » PHP-кодинг

Форма обратной связи с аттачем

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

Демо версия тут | Скачать скрипт формы обратной связи с аттачем

Давайте рассмотрим основные моменты в исходном коде этого скрипта:

Основные настройки и диагностические сообщения:


error_reporting(7);
$websitename="Форма обратной связи с аттачем"; 
$allowtypes=array("zip", "rar", "txt", "doc", "jpg", "png", "gif","odt","xml");
$myemail="youremail@domain.ru";
$priority="3";
$allowattach="1"; 
$max_file_size="1024";
$max_file_total="2048";
$submitvalue="Отправить"; 
$resetvalue="Сброс";
$defaultsubject="Без темы"; 
$use_subject_drop=false;
$subjects=array("Часть 1","Часть 2","Часть 3");
$emails=array("dept_1@domain.com","dept_2@domain.com","dept_3@domain.com");
$thanksmessage="Спасибо! Ваше письмо было отправлено, мы ответим в ближайшее время.";

Настройте для своего случая соответствующие переменные: $myemail и $allowtypes для определения вашего e-mail-адреса и типов поддерживаемых расширений для приаттачиваемого файла. В переменной emails перечисляются дополнительные email-адреса для пересылки на них копий этого же сообщения.

Также особенного внимания заслуживают функции для обработки приаттачиваемого (присоединяемого) файла.


function get_ext($key){ 
	$key=strtolower(substr(strrchr($key, "."), 1));
	$key=str_replace("jpeg","jpg",$key);
	return $key;
}
function phattach($file,$name){
	global $boundary;	
	$fp=@fopen($file,"r");
	$str=@fread($fp, filesize($file));
	$str=@chunk_split(base64_encode($str));
	$message="--".$boundary."\n";
	$message.="Content-Type: application/octet-stream; name=\"".$name."\"\n";
	$message.="Content-disposition: attachment; filename=\"".$name."\"\n"; 
	$message.="Content-Transfer-Encoding: base64\n";
	$message.="\n";
	$message.="$str\n";
	$message.="\n";
	return $message;
}
function clean($key){
	$key=str_replace("\r", "", $key);
	$key=str_replace("\n", "", $key);
	$find=array("/bcc\:/i","/Content\-Type\:/i","/Mime\-Type\:/i","/cc\:/i","/to\:/i");
	$key=preg_replace($find,"",$key);
	return $key;
}

Функция get_ext преобразует символы в имени файла к нижнему регистру, а также заменяет расширения jpeg на jpg.

Функция phattach возвращает заголовок типа сообщения для последующей отправки на мыло текстовых файлов внешних приложений формата application/octet-stream. А функция clean находит и удаляет нежелательные символы в имени.

Для проверки и удаления нежелательных типов файлов служит следующая процедура проверки:


$error="";
$types="";
$sent_mail=false;
$ext_count=count($allowtypes);
$i=0;
foreach($allowtypes AS $extension) {	
	If($i <= $ext_count-2) {
		$types .="*.".$extension.", ";
	} Else {
		$types .="*.".$extension;
	}
	$i++;
}
unset($i,$ext_count);

Цикл foreach делает разбор указанных расширений файлов в массиве $allowtypes[] по типам в соответствии с необходимым условием.

Далее привожу исходный код цикла обработки и передачи заполненной пользователем формы на e-mail адрес, указанный в переменной $myemail.


If($_POST['submit']==true) {
	extract($_POST, EXTR_SKIP);	
		If(trim($yourname)=="") { 
			$error.="Вы не ввели Ваше имя!
"; } If(trim($youremail)=="") { $error.="Вы не ввели Ваш email!
"; } Elseif(!eregi("^([a-z0-9_]|\\-|\\.)+@(([a-z0-9_]|\\-)+\\.)+[a-z]{2,4}\$",$youremail)) { $error.="Неправильный адрес электронной почты
"; } If(trim($emailsubject)=="") { $emailsubject=$defaultsubject; } If(trim($yourmessage)=="") { $error.="Вы не ввели Ваше сообщение!
"; } If($allowattach > 0) { For($i=0; $i <= $allowattach-1; $i++) { If($_FILES['attachment']['name'][$i]) { $ext=get_ext($_FILES['attachment']['name'][$i]); $size=$_FILES['attachment']['size'][$i]; $max_bytes=$max_file_size*1024; If(!in_array($ext, $allowtypes)) { $error.= "Недопустимое расширение для вашего файла: ".$_FILES['attachment']['name'][$i].", only ".$types." are allowed.
"; } Elseif($size > $max_bytes) { $error.= "Ваш файл: ".$_FILES['attachment']['name'][$i]." is to big. Max file size is ".$max_file_size."kb.
"; } } } $total_size=array_sum($_FILES['attachment']['size']); $max_file_total_bytes=$max_file_total*1024; If($total_size > $max_file_total_bytes) { $error.="Максимальный допустимый размер вашего файла ".$max_file_total."kb
"; } } If($error) { $display_message=$error; } Else { If($use_subject_drop AND is_array($subjects) AND is_array($emails)) { $subject_count=count($subjects); $email_count=count($emails); If($subject_count==$email_count) { $myemail=$emails[$emailsubject]; $emailsubject=$subjects[$emailsubject]; } } $boundary=md5(uniqid(time())); $yourname=clean($yourname); $yourmessage=clean($yourmessage); $youremail=clean($youremail); $headers="From: ".$yourname." <".$youremail.">\n"; $headers.="Reply-To: ".$yourname." <".$youremail.">\n"; $headers.="MIME-Version: 1.0\n"; $headers.="Content-Type: multipart/mixed; boundary=\"".$boundary."\"\n"; $headers.="X-Sender: ".$_SERVER['REMOTE_ADDR']."\n"; $headers.="X-Mailer: PHP/".phpversion()."\n"; $headers.="X-Priority: ".$priority."\n"; $headers.="Return-Path: <".$youremail.">\n"; $headers.="This is a multi-part message in MIME format.\n"; $message = "--".$boundary."\n"; $message.="Content-Type: text/plain; charset=\"windows-1251\"\n"; $message.="Content-Transfer-Encoding: quoted-printable\n"; $message.="\n"; $message.="$yourmessage"; $message.="\n"; If($allowattach > 0) { For($i=0; $i <= $allowattach-1; $i++) { If($_FILES['attachment']['name'][$i]) { $message.=phattach($_FILES['attachment']['tmp_name'][$i],$_FILES['attachment']['name'][$i]); } } } $message.="--".$boundary."--\n"; If(!mail($myemail,$emailsubject,$message,$headers)) { Exit("Произошла ошибка, пожалуйста, сообщите об этом администратору сайта.\n"); } Else { $sent_mail=true; } } }

Работает так: Если переменная отправки $_POST['submit'] вернула положительный результат (true), то выполняем все действия. Иначе у нас будет распечатываться форма, которую напишем ниже. В самом начале мы извлекаем с помощью функции extract все переменные, которые нам необходимы для обработки формы, чтобы лишний раз не писать $_POST для каждой переменной. Это очень удобно, хотя не рекомендуется. Далее производим проверку введенных полей: yourname, youremail, emailsubject, yourmessage, allowattach. Если в них пусто, то формируем строковую переменную сообщения ошибки $error, которую мы определили как $error=""; перед циклом разбора типов файлов. Если ошибка возникнет, то выведится соответствующее сообщение. Для идентификации аттач-файла используем переменную $allowattach, если она имеет место быть, то в цикле перебора её значений формируем временые массивы для хранения параметров файла с присвоением их значений переменным: $ext, $size, $max_bytes, $total_size, $max_file_total_bytes. Также проверяем расширение и размер файла на допустимость, если не существует(массив) или превышает(размер), то присваиваем переменной ошибки соответствующее строковое значение.

Если ошибок в переменной $error нет, то формируем конечные переменные для использования в заголовке отправляемого письма $headers: $boundary, $yourname, $yourmessage, $youremail. Если выбран файл, то формируем и для него заголовок в виде: $message.=phattach($_FILES['attachment']['tmp_name'][$i],$_FILES['attachment']['name'][$i]);

Затем с помощью функции mail() отправляем сформированное письмо. Если функция не сработала, то выводим сообщение, что произошла ошибка. В случае положительного результата присваиваем переменной $sent_mail флаг положительного результата true, значение которой перед отправкой было установлено в false.

Всё. Теперь осталось только создать html-формочку для пущей наглядности. Но перед этим напишем небольшой клиентский скрипт для вывода сообщений об ошибке в стандартном диалоговом окне в случае неправильно введенных или оставленных пустых полей формы. Разместите этот код в вашем html-документе между тэгами <head>...</head>.


<script type="text/javascript">
var error="";
e_regex = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,})+$/;
function Checkit(theform) {
	
	if(theform.yourname.value=="") {
		error+="Вы не ввели Ваше имя\n";
	}	
	if(theform.youremail.value=="") {
		error+="Вы не ввели Ваш email\n";
	} else if(!e_regex.test(theform.youremail.value)) {
		error+="Неправильный адрес электронной почты\n";
	}		
	if(theform.yourmessage.value=="") {
		error+="Вы не ввели Ваше сообщение\n";
	}	
	if(error) {
		alert('Произошли следующие ошибки:\n\n' + error);
		error="";
		return false;
	} else {
		return true;
	}
}
</script>

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


<?If($display_message) {?>
<div align="center" class="error_message"><b><?=$display_message;?></b></div><br />
<?}?>
<?If($sent_mail!=true) {?>
<form method="post" action="<?=$_SERVER['PHP_SELF'];?>" enctype="multipart/form-data" name="phmailer" onsubmit="return Checkit(this);">
<table align="center" class="table">
<tr><td colspan="2" class="table_header" width="100%"><?=$websitename;?></td></tr>
<?If($allowattach > 0) {?>
<tr>
<td width="100%" class="attach_info" colspan="2">
<b>Поддерживаемые типы файлов:</b> <?=$types?><br />
<b>Максимальный размер файла:</b> <?=$max_file_size?>kb.<br />
<b>Максимальный размер архива:</b> <?=$max_file_total?>kb.</td>
</tr>
<?}?>
<tr><td width="30%" class="table_body">Ваше имя:</td>
<td width="70%" class="table_body"><input name="yourname" type="text" size="30" value="<?=stripslashes(htmlspecialchars($yourname));?>" /><span class="error_message">*</span></td>
</tr>
<tr>
<td width="30%" class="table_body">Ваш Email:</td>
<td width="70%" class="table_body"><input name="youremail" type="text" size="30" value="<?=stripslashes(htmlspecialchars($youremail));?>" /><span class="error_message">*</span></td>
</tr>
<tr><td width="30%" class="table_body">Тема:</td><td width="70%" class="table_body">
<?If($use_subject_drop AND is_array($subjects)) {?>
<select name="emailsubject" size="1">
<?while(list($key,$val)=each($subjects)) {?>
<option value="<?=intval($key);?>"><?=htmlspecialchars(stripslashes($val));?></option>
<?}?></select>
<?} Else {?>
<input name="emailsubject" type="text" size="30" value="<?=stripslashes(htmlspecialchars($emailsubject));?>" />
<?}?>
</td></tr>
<?For($i=1;$i <= $allowattach; $i++) {?>
<tr>
<td width="30%" class="table_body">Прикрепить файл:</td>
<td width="70%" class="table_body"><input name="attachment[]" type="file" size="30" /></td>
</tr>
<?}?>
<tr><td colspan="2" width="100%" class="table_body">Ваше сообщение:<span class="error_message">*</span><br />
<div align="center"><textarea name="yourmessage" rows="8" cols="60"><?=stripslashes(htmlspecialchars($yourmessage));?></textarea></div>
</td></tr>
<tr>
<td colspan="2" width="100%" class="table_footer">
<input type="hidden" name="submit" value="true" />
<input type="submit" value="<?=$submitvalue;?>" /> &nbsp;
<input type="reset" value="<?=$resetvalue;?>" />
</td></tr>
</table></form>
<?} Else {?>
<div align="center" class="thanks_message"><?=$thanksmessage;?></div>
<html><head><meta http-equiv='Refresh' content='1; URL=index.php'></head></html>
<?}?>

Думаю в ней особо комментировать нечего. Отмечу только то, что многие служебные переменные для вывода мы определили в самом начале скрипта. Также обратите внимание на наличие обязательного значения атрибута enctype в тэге <form>, если он не указан, то файл не будет отправляться! В качестве атрибута "action" указано значение глобального массива $_SERVER['PHP_SELF']. За работу клиентского скрипта для проверки заполнения полей отвечает значение обработчика "onsubmit", который возвращает вызов функции Checkit(this).

Очень важный момент: Не забудьте написать в форме скрытое поле с именем submit и значением true. Оно символизирует об отправке данных.

После успешной отправки сообщения выводиться переменная $thanksmessage и перезагружается(обновляется) старничка формы обратной связи.

Пожалуй всё! Если что не понятно, спрашивайте в комментариях =)

Комментировать

Автор: admin | Добавлена: 10.05.2009 | Просмотров: 14387
Рейтинг: 16 | Голосов: 4

Оцените заметку: 1 2 3 4 5

Последние обновления в категории: PHP-кодинг

Комментарии (0)

Комментариев пока нет!

Только авторизованные пользователи могут добавлять комментарии. Зарегистрироваться.

Логин:
Пароль:
 

Регистрация

: Тема:

Заметок в базе: 56
Комментариев: 0
Всего юзеров: 114
Сейчас онлайн: 1