Отправка e-mail в русской кодировке средствами PHP

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

Тело письма может быть текстом в любой кодировке. Немного сложнее дело обстоит с составляющими заголовка письма (Subject, From, To), они по стандарту должны быть в US-ASCII. Использование в заголовках кодированного текста регламентируется стандартом RFC-2047. Стандарт задает две возможные формы кодирования - BASE64 и Quoted-Printable. BASE64 более универсальна и работает в том числе для кодировки UTF-8, поэтому мы выбрали именно эту форму. MIME-совместимый почтовый клиент обязан уметь читать обе формы.

Далее код функции, который достаточно схематичен:

<?php

function send_mime_mail($name_from, // имя отправителя
                        $email_from, // email отправителя
                        $name_to, // имя получателя
                        $email_to, // email получателя
                        $data_charset, // кодировка переданных данных
                        $send_charset, // кодировка письма
                        $subject, // тема письма
                        $body // текст письма
                        ) {
  $to = mime_header_encode($name_to, $data_charset, $send_charset)
                 . ' <' . $email_to . '>';
  $subject = mime_header_encode($subject, $data_charset, $send_charset);
  $from =  mime_header_encode($name_from, $data_charset, $send_charset)
                     .' <' . $email_from . '>';
  if($data_charset != $send_charset) {
    $body = iconv($data_charset, $send_charset, $body);
  }
  $headers = "From: $fromrn";
  $headers .= "Content-type: text/plain; charset=$send_charsetrn";

  return mail($to, $subject, $body, $headers);
}

function mime_header_encode($str, $data_charset, $send_charset) {
  if($data_charset != $send_charset) {
    $str = iconv($data_charset, $send_charset, $str);
  }
  return '=?' . $send_charset . '?B?' . base64_encode($str) . '?=';
}

?>

Мы определили собственную функцию mime_header_encode() для преобразования каждого заголовка в MIME-совместимый формат, несмотря на то, что в PHP предусмотрена аналогичная функция mb_encode_mimeheader(). От встроенной функции нам пришлось отказаться, так как на нашем сервере (PHP 5.1.6) она работает некорректно (возвращает неверный результат).

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

<?php
send_mime_mail('Автор письма',
               'sender@site.ru',
               'Получатель письма',
               'recepient@site.ru',
               'CP1251',  // кодировка, в которой находятся передаваемые строки
               'KOI8-R', // кодировка, в которой будет отправлено письмо
               'Письмо-уведомление',
               "Здравствуйте, я Ваша программа!");
?>

Комментарии

Оставьте свой комментарий
И
Иван

Добрый день. Есть форма с данными, анкета, заполняется клиентом. Нужно реализовать по нажатию кнопки отправка письма с данными формы и смс с текстом Спасибо и т.д. По отдельности все работает, как сделать это нажатием одной кнопки.
Спасибо.

П
Петя

Здравствуйте. Подскажите пожалуйста, какую часть кода поменять, чтобы при получении писем в Microsoft Office Outlook, имя выводилось русскими буквами.

<?php

include('kcaptcha/kcaptcha.php');
session_start();
require_once("config.php");

if ($_POST['act']== "y")
{
if(isset($_SESSION['captcha_keystring']) && $_SESSION['captcha_keystring'] == $_POST['keystring'])
{

if (isset($_POST['posName']) && $_POST['posName'] == "")
{
$statusError = "$errors_name";

}
elseif (isset($_POST['posEmail']) && $_POST['posEmail'] == "")
{
$statusError = "$errors_mailfrom";
}
elseif(isset($_POST['posEmail']) && !preg_match($_POST['posEmail']))
{
$statusError = "$errors_incorrect";

unset($_POST['posEmail']);
}
elseif (isset($_POST['posRegard']) && $_POST['posRegard'] == "")
{
$statusError = "$errors_subject";
}
elseif (isset($_POST['posText']) && $_POST['posText'] == "")
{
$statusError = "$errors_message";
}

elseif (!empty($_POST))
{
$headers = "MIME-Version: 1.0rn";
$headers .= "Content-type: text/plain; charset=windows-1251rn";
$headers .= "Date: ".date("Y-m-d (H:i:s)",time())."rn";
$headers .= "From: "".$_POST['posName']."" <".$_POST['posEmail'].">rn";
$headers .= "X-Mailer: My Send E-mailrn";

mail("$mailto","$subject","$message","$headers");

unset($name, $posText, $mailto, $subject, $posRegard, $message);

$statusSuccess = "$send";
}

}else{
$statusError = "$captcha_error";
unset($_SESSION['captcha_keystring']);
}
}
?>

G
guest

Может быть, это поможет.

$message = "Имя пославшего:".$namen." Электронный адрес:".$emailn." Контактный телефон:".$phonen." Сообщение:".$messn. " IP-адрес:$REMOTE_ADDR";
Формат

echo " ".$var1."".$var2;

//вывести на экран
echo "Имя пославшего:".$namen." Электронный адрес:".$emailn." Контактный телефон:".$phonen." Сообщение:".$messn. " IP-адрес:$REMOTE_ADDR";

T
trafland

Здравствуйте.
Сам я в .php не смыслю, попросил у знакомого скрипт отправки письма с сайта накодить. Сделал, НО, проблема в том-что я не могу прописать номер телефона (ну что бы с сайта, с формы отправления, отправитель мне прислал и контактный телефон). Сам ковырял - ничего не получилось. Посмотрите пожалуйста код и подскажите как быть ?!

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<Title>Mail</Title>
<STYLE>
<!--
A {color: #014e82;font-weight: lighter; font-size: 13px;font-family: verdana,Helvetica,sans-serif; text-decoration: none; }
A:hover { color: #FF0000; font-weight: lighter; font-size: 13px;font-family: verdana,Helvetica,sans-serif;text-decoration: underline; }
-->
</STYLE>

</head>

<body>
<body MARGINWIDTH="0" MARGINHEIGHT="0" topmargin="0" rightmargin="0" leftmargin="0" onload="">

<TABLE BORDER="0" WIDTH="750" height="100%" CELLSPACING="0" CELLPADDING="0" align="center">
<TR>
<TD align="center"valign="center"WIDTH="100%"height="510"BGCOLOR="#a2ce9b">

<!--center razdel-->
<?php

if (isset ($name))
{
$name = substr($name,0,20); //Не может быть более 20 символов
if (empty($name))
{
echo "<center>заполнить форму<p>";
echo "<a href=/contact.html>назад</a>";
exit;
}
}
else
{
$name = "не указано";
}

if (isset ($email))
{
$email = substr($email,0,50); //Не может быть более 50 символов
if (empty($email))
{
echo "<center>заполнить форму<p>";
echo "<a href=/contact.html>назад</a>";
exit;
}
}
else
{
$email = "не указано";
}

if (isset ($phone))
{
$email = substr($phone,0,50); //Не может быть более 50 символов
if (empty($phone))
{
echo "<center>заполнить форму<p>";
echo "<a href=/contact.html>назад</a>";
exit;
}
}
else
{
$phone = "не указано";
}

if (isset ($mess))
{
$mess = substr($mess,0,1000); //Не может быть более 1000 символов
if (empty($mess))
{
echo "<center>заполнить форму<p>";
echo "<a href=/contact.html>назад</a>";
exit;
}
}
else
{
$mess = "не указано";
}

$i = "не указано";
if ($name == $i AND $email == $i AND $phone == $i AND $mess == $i)
{
echo "Ошибка ! Скрипту не были переданы параметры !";
exit;
}

$to = "info@gmail.com";
$subject = "Сообщение с вашего интернет-сайта";
$message = "Имя пославшего:$namen Электронный адрес:$emailn Контактный телефон:$phonen Сообщение:$messn IP-адрес:$REMOTE_ADDR";
mail ($to,$subject,$message) or print "Не могу отправить письмо !!!";
echo "<center><a href=/contact.html>спасибо - Ваше сообщение принято и в ближайшее время мы с Вами свяжемся</a>";
exit;
?></td>
<!--finish center razdel-->

</TR>
</TABLE>

</body>
</html>

P
petrik

Респект АВТОРУ!!!!!!!
Все четко работает!
Раньше при отправке, письма попадали под спам фильтр, а сейчас всё чудесно!

C
css

и сам вызов функции (пример, вы пишите свое)

send_mime_mail('Студия продвижения',
'admin@leadsyou.ru',
$emailusernsend,
'windows-1251',
'windows-1251',
'Вам письмо от печкина',
'Я пишу письмо большое, не плохое и кривое... Прочитай его без скуки В Бате или Аутлуке.. ну и так далее.. ');
И сделали бы вы поле для добавления комментариев побольше.. трудно писать в эти 5 строчек..

C
css

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

Я поправила этот код, правда не проверяла его , если кодировка разная на сайте и в письме. Но если везде windows-1251, то работает и в Бате и в Аутлуке

function send_mime_mail($name_from, // имя отправителя
$email_from, // email отправителя
$email_to, // email получателя
$data_charset, // кодировка переданных данных
$send_charset, // кодировка письма
$subject, // тема письма
$body // текст письма
) {
$to = $email_to;
$subject = mime_header_encode($subject, $data_charset, $send_charset);
$from = mime_header_encode($name_from, $data_charset, $send_charset).' <' . $email_from . '>';
if($data_charset != $send_charset) {
$body = iconv($data_charset, $send_charset, $body);
}

$headers ="Content-type: text/plain; charset="".$send_charset.""n";
$headers .="From: $fromn";
$headers.="Mime-Version: 1.0n";

return mail($to, $subject, $body, $headers);
}

function mime_header_encode($str, $data_charset, $send_charset) {
if($data_charset != $send_charset) {
$str = iconv($data_charset, $send_charset, $str);
}
return '=?' . $send_charset . '?B?' . base64_encode($str) . '?=';
}

C
css

В функции send_mime_mail сделайте замену строки

$to = mime_header_encode($name_to, $data_charset, $send_charset)
. ' <' . $email_to . '>';

на такое
$to = $email_to;
и будет отправлять на емайлы через запятую

Д
Джек

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