Часть проблемы - длинные строки, но wordwrap()
недостаточно для решения этой проблемы.
Письмо может иметь произвольно длинные строки, но они передаются по протоколу, который допускает только короткие строки. Таким образом, длинные линии должны быть разделены. Протокол помечает строки, которые были разделены путем добавления = к их концу, так что вначале это выглядит следующим образом.
Characters 2 3 4 5 6 7
12346790123456789012345678901234567890132456789012345678901234567890123456789
This is a long line with text which goes beyond the 78 character limit imposed by the protocol
выглядит так
This is a long line with text which goes beyond the 78 character limit=
imposed by the protocol
Использование = как это означает, что = не может быть использовано в вашем сообщении, поэтому его нужно экранировать. Поэтому вам нужно заменить = в вашем сообщении на = 3D (где 3D - шестнадцатеричный код для =).
Также целесообразно заменить любые управляющие символы (с кодом ascii <32) на = xx и все, что имеет код ascii более 126. Я использую эти функции, чтобы сделать это, тогда вам просто нужно сделать <code>$message=encodeText($message) перед отправкой, и проблема должна исчезнуть.
function encodeText($input) {
// split input into lines, split by \r\n, \r or \n
$lines=preg_split("/(?:\r\n|\r|\n)/", $input);
$text="";
// for each line, encode it into a 78 char max line.
for ($i=0; $i<count($lines); $i++) {
$text.=encodeLine($lines[$i]);
}
return $text;
}
/**
* This splits a line into a number of pieces, each shorter than the 78 char
* limit. It also add continuation marks (i.e. =) to then end of each piece
* of the resulting line, and escapes any = characters, control characters
* or characters with bit 8 set, and backspace.
* @return a multiline string (with /r/n linebreaks)
*/
function encodeLine($line) {
$split=Array();
$result="";
$piece='';
$j=0;
for ($i=0; $i<strlen($line); $i++) {
// if you've just split a line, you'll need to add an = to the
// end of the previous one
if ($j>0 && $piece=="") $split[$j-1].="=";
// replace = and not printable ascii characters with =XX
if (ord($line{$i})==0x3D) {
$piece.="=3D";
} else if (ord($line{$i})<32) {
$piece.="=".bin2hex($line{$i});
} else if (ord($line{$i})>126) {
$piece.="=".bin2hex($line{$i});
} else {
$piece.=$line{$i};
}
// if the resulting line is longer than 71 characters split the line
if (strlen($piece)>=72) {
$split[$j]=$piece;
$piece="";
$j++;
}
}
// the last piece being assembled should be added to the array of pieces
if (strlen($piece)>0) $split[]=$piece;
// if a piece ends in whitespace then replace that whitespace with =20
// for a space or =09 for a tab.
for ($i=0; $i<count($split); $i++) {
$last=substr($split[$i],-1);
if ($last=="\t") $last="=09";
if ($last==" ") $last="=20";
$split[$i]=substr($split[$i],0,strlen($split[$i])-1).$last;
}
// assemble pieces into a single multiline string.
for ($i=0; $i<count($split); $i++) {
$result.=$split[$i]."\r\n";
}
return $result;
}