Помогите с php mail() headers кодировкой, пожалуйста
Привет!
Только начал разбираться с php и уже вторые сутки не пойму в чем беда.
В письмах, отсылаемых php, в некоторых почтовых клиентах слетает кодировка в поле «от кого». Такая же проблема была с темой письма, однако решилась путём: mail($to,"=?windows-1251?B?".base64_encode($subject)."?=",$message,$headers); — вместо просто mail($to,$subject,$message,$headers);
Однако, когда такой же костыль я вставляю в $headers в поле From: то сообщения не отсылаются вообще. В логе постфикс только рапорты об отправленных сообщениях. Что я вставляю в $headers: $headers .= "From: =?windows-1251?B?".base64_encode($mailfrom)."?= <".$email."> \r\n";
Собственно, интересны переносы — оберните в <source ></source>…
Да и адрес отправителя надо указать… From: =?windows-1251?B?x+D/4uroIO3gIOLo5+jy6ug=?= <admin@test.com>
From правильнее кодировать с помощью mb_encode_mimeheader до того, как кодировать прочие заголовки.
Т.е. алгортим примерно следующий:
Проверяем, что у нас есть mbstring (для старых версий php возможны варианты)
Проверяем, что у mbstring прописаны правильные значения кодировок по умолчанию (читаем доки, в том числе по функции mb_encode_mimeheader)
Кодируем поле FROM с помощью mb_encode_mimeheader
Устанавливаем все хидеры (имеет смысл посмотреть реализацию PEAR — там не без ошибок, как ни удивительно, но в целом оно рабочее)
Уже так и не понял, что я сделал, но оно заработало! Проблема теперь в другом =\
Поле from: заполняется из Фамилии и E-mail человека, который «регистрируется». Фамилия кодируется в UTF-8 с помощью =?UTF-8?B?".base64_encode($lastname)." <$email>\n";
Так вот, с фамилиями до 10 знаков — всё ок. Более 10 знаков — письма не отправляются =( Я так понимаю, дейсвует какое-то ограничение строки или что-то в этом роде. Если идеи?
Рад за вас. Сам в свое время просидел с почтой долго-долго — в результате переписал под себя PEAR.Mail, так чтобы оно не глючило.
Проблем может быть две:
1) Директивами постфикса можно замутить ограничение длины заголовков. Причем, если я правильно помню — индивидуально для каждого. И, если конфиг брался из инета из наиболее популярных подробных мануалов, такая ситуация весьма вероятна.
2) Не вполне корректно конвертированная комбинация русского языка, UTF-8 и base64 может давать незапланированные появления переносов строк или еще какой-нибудь бяки, соответственно, портится заголовок и возникают проблемы с отправкой.
Имеет смысл:
Попробовать английские фамилии. Убедиться, что режется все после 10 знака.
Если с длинными английскими фамилиями все отправляется — копать в сторону кодировок. Если нет — в сторону конфигов постфикса
На всякий случай — перед отправкой (когда хидеры сформированы) их стоит пропустить через функцию (в данном случае — ассоциативный массив, но можно и напрямую:)
function sanitizeHeaders($headers)
{
foreach ($headers as $key => $value) {
$headers[$key] =
preg_replace('=((<CR>|<LF>|0x0A/%0A|0x0D/%0D|\\n|\\r)\S).*=i',
null, $value);
}
return $headers;
}
я читал уже этот материал.
Проблема в том, что письма не отсылаются ВООБЩЕ с костылём для смены кодировки (я пробовал и utf-8 и пр.)
то есть строка $headers .= "From: =?windows-1251?B?".base64_encode($mailfrom)."?= <".$email."> \r\n"; тоже ничего не изменила.
Ещё раз — проблема в коде хидеров.
При $headers .= "From: ".$mailfrom." <".$email."> \r\n"; сообщение отсылается и приходит с птичьим языком в поле From: в IBM Notes (Outlook & Gmail работают).
При $headers .= "From: =?windows-1251?B?".base64_encode($mailfrom)."?= <".$email."> \r\n"; письма не отправляются вообще!
от кодировки не зависит, трабл в самом коде в строке $headers = «From:......»
Так как я полный нуб, я скорее всего где то не там ставлю точку, кавычку и т.п. =\
Прошу прощения, не внимательно читал вопрос. Увидел знакомые слова — написал))
Пробуйте не "\r\n", а просто "\n"
Из мана:
Замечание:
Если сообщения не отправляются, попробуйте использовать только LF (\n). Некоторые агенты пересылки сообщений Unix (особенно » qmail) автоматически заменяют LF на CRLF (что приводит к двойному CR, если использовалось CRLF). Используйте эту меру в крайнем случае, так как это нарушает » RFC 2822.