Почему в письмах появляются слова, разорванные знаками вопроса?

Рейтинг: 1Ответов: 1Опубликовано: 03.02.2023

Проблема с письмами, отправленными на яндекс через PHP

С сайта на почту яндекс отправляются письма о заказах. Письма отправляются через функцию PHP mail() Периодически письма приходят с артефактами - некоторые символы заменяются знаками ? Такая проблема возникла внезапно и наблюдается только на почте яндекс, раньше письма приходили нормальные Если отправлять на gmail или mail.ru, таких проблем нет. Кодировка используется utf-8.

<?php
$subj = "Подтверждение оплаты заказа на сайте";
$header = "Content-Type: text/html ; charset=utf-8;\nMIME-Version: 1.0\nFrom: site.ru <remind@site.ru>\n";
$msg = "Новый заказ<br>";
$msg .= "Номер заказа: " .$order->ID .";<br>";
// формирование текста письма с информацией о заказе
mail('siteoperator@yandex.ru', $subj, $msg, $header);
?>

Фрагмент письма с "артефактами"

Район доставки: По городу;
Стоимость доставки: 200;
Адрес: ---;
Имя получателя: Анна;
Телефон пол? ?чателя: +7-(900)-000-0000;
Заказчик: Кс? ?ния;
Электронная почта: atulpan@list.ru;
Телефон: +7-(900)-000-0000;

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

В чем может быть проблема?

Ответы

▲ 1

Это очень забавный вопрос. К появлению таких артефактов приводит сочетание двух факторов:

  1. Игнорирование переводов строк при составлении текста, в результате чего всё тело письма оказывается одной длинной строкой. Которую по правилам отправки почтовых отправлений надо разбивать на более короткие, что и делает почтовый сервер, отправляющий сообщение.
  2. Тот факт, что символы кириллицы в UTF-8 занимают два байта.

В результате такой автоматической разбивки слова "получателя" на одной строке от остается "пол" и половинка буквы "у", которая не является валидным символом UTF-8 и поэтому отображается как знак вопроса, затем идет перевод строки, который отображается как пробел, и дальше вторая половинка буквы "у" в виде знака вопроса, и остаток слова, "чателя".

Для костыльного решения проблемы надо не забывать добавлять символ перевода строки в текст. И плюс не забывать кодировать тело и заголовок письма в соответствии со стандартами.

Но нормальным решением будет не использовать функцию mail, а взять нормальную почтовую программу, типа PHPMailer