Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Кодирование заголовков в HTMLMimeMail5 - съедает пробелы!
 
 автор: DDK   (29.07.2008 в 23:27)   письмо автору
 
 

В HTMLMimeMail5 заголовок письма и имя+адрес отправителя кодируются вот таким методом в Mime:


private function encodeHeader($input, $charset = 'ISO-8859-1')
    {
        preg_match_all('/(\w*[\x80-\xFF]+\w*)/', $input, $matches);
        foreach ($matches[1] as $value) {
            $replacement = preg_replace('/([\x80-\xFF])/e', '"=" . strtoupper(dechex(ord("\1")))', $value);
            $input = str_replace($value, '=?' . $charset . '?Q?' . $replacement . '?=', $input);
        }
        
        return $input;
    }


Не могу разобраться, в чём дело: кодировка в аргумент $charset передаётся windows-1251, русский текст отображается нормально, но при пропуске его через эту функцию в кириллическом тексте удаляются пробелы. Причём только в кириллическом. Если же пропускать английский текст (Vasya Pupkin), то пробелы между словами никуда не деваются.

Я не очень понимаю механизм работы данной функции, по-этому прошу вашей помощи!

  Ответить  
 
 автор: Trianon   (29.07.2008 в 23:40)   письмо автору
 
   для: DDK   (29.07.2008 в 23:27)
 

Кодирование методом quoted-printable - это не только кодирование символов национальных алфавитов. Это еще и кодирование пробелов между ними. Внимательнее читайте RFC.
Например RFC-1521 п.5.1, правило #3 и #4

  Ответить  
 
 автор: DDK   (30.07.2008 в 01:38)   письмо автору
 
   для: Trianon   (29.07.2008 в 23:40)
 

Эмм... и что мне исходя из этого делать, простите ? :)

  Ответить  
 
 автор: Trianon   (31.07.2008 в 23:04)   письмо автору
 
   для: DDK   (30.07.2008 в 01:38)
 

Если бы задачка надежно решалась за десять минут - я бы привел решение.

Если же Вы просто хотите знать почему конкретный текст оказывается искаженным - приведите здесь пример текста и результат кодирования. Поглядим.

  Ответить  
 
 автор: DDK   (31.07.2008 в 22:19)   письмо автору
 
   для: DDK   (29.07.2008 в 23:27)
 

Эм... up :)

  Ответить  
 
 автор: Jura   (31.07.2008 в 23:25)   письмо автору
 
   для: DDK   (29.07.2008 в 23:27)
 


function GGquoted_printable_encode($string, $encoding='UTF-8') { $len = strlen($string); $result = ''; $enc = false; for($i=0;$i<$len;++$i) { $c = $string[$i]; if (ctype_alpha($c)) $result.=$c; else if ($c==' ') { $result.='_'; $enc = true; } else { $result.=sprintf("=%02X", ord($c)); $enc = true; } } if (!$enc) return $string;       return '=?'.$encoding.'?q?'.$result.'?=';
} // конец функции

function GGquoted_printable_decode($string_quoted_printable, $to_charset="CP1251") { $decode=trim(quoted_printable_decode($string_quoted_printable));
$decode=str_replace(array('=?','?'),'', str_replace('?q?','|', $decode)); $out_array=split("\|",$decode);  //echo "<pre>".var_dump($out_array)."</pre>";
if(!empty($out_array)){$charset=$out_array['0'];$data=iconv($charset, $to_charset, $out_array[1]);return $data;} else {return "error";}
} // конец функции


Полагаю эти функции будут как никак кстати.

  Ответить  
 
 автор: DDK   (02.08.2008 в 14:09)   письмо автору
 
   для: Jura   (31.07.2008 в 23:25)
 

спасибо большое, попробую!

  Ответить  
 
 автор: DDK   (03.08.2008 в 23:49)   письмо автору
 
   для: DDK   (02.08.2008 в 14:09)
 

Приведённая Вами функция как-то странно работала: заголовок письма (Subject) стал отображаться нормально, с пробелами, а вот информация из полей "От кого" и "Кому" исказилась и стала отображать вместо себя закодированый отрывок. Это же ипорушило и само письмо, т.е. его текст (HTML) и вложения.

Немного почесав репу над обоими вариантами функции, я попробовал их скрестить и в итоге понадобилось добавить всего одну строку:


private function encodeHeader($input, $charset = 'ISO-8859-1')
{
    preg_match_all('/(\w*[\x80-\xFF]+\w*)/', $input, $matches);
    foreach ($matches[1] as $value) {
        $replacement = preg_replace('/([\x80-\xFF])/e', '"=" . strtoupper(dechex(ord("\1")))', $value);
        $input = str_replace($value, '=?' . $charset . '?Q?' . $replacement . '?=', $input);
    }
    input = str_replace(' ', '=?'.$charset.'?Q?=20?=', $input);
    return $input;
}


Как видно, добавилась строка:

input = str_replace(' ', '=?'.$charset.'?Q?=20?=', $input);

Функция разбивает строку по словам в массив, кодирует каждый элемент полученного массива (каждое слово) и в оригинальном тексте заменяет слова соответствующим, но уже закодированным выражением (зачем оно делается через такую задницу - мне не ясно). Пробелма заключалась в том, что при разбиении текста по словам функция оставляла в оригинальной строке символы пробела нетронутыми, так как они служили признаком при разбиении на слова. Добавленная в код функции строка же просто кодирует все оставшиеся в явном виде пробелы в исходной переменной.

Вот, надеюсь, кому-нибудь пригодится :)

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования