Как стать автором
Обновить

Кракозябрица в имени отправителя письма на почте Yandex

Введение

Доброго времени суток, уважаемые!

Хочу кратенько поведать о проблеме отображения имени отправителя письма при отправке на ящики Яндекс.Почты и привести ее решение.

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

С чего все начиналось


Итак, есть самописный сайт на php + angular. Обычный лендинг с калькулятором.
Пришла очередь задаче по отправке писем клиентам и менеджерам о поступивших заказах.

Казалось бы, чего уж проще? Берешь и пишешь:

$headers = "MIME-Version: 1.0" . PHP_EOL .
            "Content-Type: text/html; charset=utf-8" . PHP_EOL .
            'From: Почтальон Симпатикович Зигнатуров <no-reply@xxxxxxx.me>' . PHP_EOL .
            'Reply-To: order@xxxxxx.me' . PHP_EOL;

$to = 'aaa@yandex.ru, bbb@gmail.com';

$letter = 'order!';

$result = mail($to, $subject, $letter, $headers );


При этом сохраняем файл в кодировке UTF-8 без BOM и выполняем.
Смотрим почтовый ящик gmail — все в порядке! Имя отправителя отображается вполне себе корректно:



Смотрим Яндекс — опять красота.



Уже открываю шампанское… Вот она, победа. Но не тут-то было.
Открываю письмо и вижу:



… та-дам! Кракозябрица.

Убираю шампанское, достаю бубны. Начинаю шерстить интернет в поисках решения, пишу в поддержку Яндекса.
Мне приходит ответ: «Попробуйте кодировать в base64». Что кодировать — я так и не понял. Пробовал кодировать кириллические символы и заголовок целиком.

Но приходит мысль: зачем изобретать велосипед? Надо посмотреть, как делают старшие товарищи по цеху. Открываю первое письмо и смотрю его свойства. Что же я там вижу?

Content-Type: text/html; charset=windows-1251
....
From: =?windows-1251?B?RkwucnU=?= <no_reply@free-lance.ru>
Subject: =?windows-1251?B?ze7i++Ug7/Du5ery+yDt4CBGTC5ydQ==?=


Логика подсказывает, что заветное решение находится внутри символов "=?… ?=" (да простится мне серость моя сообществом мудрейших!).
Смотрю дальше и вижу кодировку windows-1251. Так, еще один шаг к успеху! Подвигаю шампанское ближе.

Затем идет еще символ «B» и знак вопроса. Отбрасываю их, беру оставшийся код и смотрю, что же это такое?

echo base64_decode('ze7i++Ug7/Du5ery+yDt4CBGTC5ydQ==');




Так, у меня файл с кодировкой utf-8. Сохраняю его как windows-1251 и запускаю снова.



Бинго!

Решение вопроса


Для файлов в кодировке utf-8 я использовал такое решение:

function adopt($text) {
	return '=?UTF-8?B?'.base64_encode($text).'?=';
}

$headers = "MIME-Version: 1.0" . PHP_EOL .
            "Content-Type: text/html; charset=utf-8" . PHP_EOL .
            'From: '.adopt('Почтальон Симпатикович Зигнатуров').' <no-reply@xxxxxxx.me>' . PHP_EOL .
            'Reply-To: order@xxxxxx.me' . PHP_EOL;

$to = 'aaa@yandex.ru, bbb@gmail.com';

$letter = 'order!';

$result = mail($to, adopt($subject), $letter, $headers );


Обратите внимание — тема письма также закодирована:

В результате я получил корректное отображение отправителя письма:



Прошу не судить строго за мой первый литературно-технический очерк. Буду благодарен профессиональным отзывам и дополнением материала.
Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.