e-posta konu mola aralıkla aksanlı sözler - Ben bunu nasıl durdurabilirim?

4 Cevap php

We have a custom php email marketing app, and an interesting problem: If the subject line of the message contains a word with accents, it 'swallows' the spaces between it and the following word. An example: the phrase

Ángel Ríos escucha y sorprende

(en azından gmail ve lotus notlar) tarafından gösterildiği gibi

ÁngelRíos escucha y sorprende

Mesajı kaynağında belirli bir satır gösterir:

Subject: =?ISO-8859-1?Q?=C1ngel?= =?ISO-8859-1?Q?R=EDos?= escucha y sorprende

(Yarı-tam başlıkları):

Delivered-To: me@gmail.com
Received: {elided}
Return-Path: <return@path>
Received: {elided}
Received: (qmail 23734 invoked by uid 48); 18 Aug 2009 13:51:14 -0000
Date: 18 Aug 2009 13:51:14 -0000
To: "Adriano" <me@gmail.com>
Subject: =?ISO-8859-1?Q?=C1ngel?= =?ISO-8859-1?Q?R=EDos?= escucha y sorprende
MIME-Version: 1.0
From: {elided}
X-Mailer: PHP
X-Lista: 1290
X-ID: 48163
Content-Type: text/html; charset="ISO-8859-1"
Content-Transfer-Encoding: quoted-printable
Message-ID: <kokrte.rpq06m@example.com>

EDIT:

App mesajları hazırlamak için Html Mime Mail eski bir sürümünü kullanan, ben daha yeni bir sürüme yükseltmek için çalışacağım. Neyse, bu konuyu kodlar işlevi:

/**
 * Function to encode a header if necessary
 * according to RFC2047
 */
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;
}

Ve burada konu kodlanmış kod:

if (!empty($this->headers['Subject'])) {
    $subject = $this->_encodeHeader($this->headers['Subject'],
                                    $this->build_params['head_charset']);
    unset($this->headers['Subject']);
}

Wrap-up

Sorun, gerçekten, söz konusu program durumunda, alan kodlayan değildi oldu. PHP yüklü sürüm bir özel uygulama detay destek vermedi çünkü The accepted answer (bu cevap için açıklamalarda belirtildiği) hafif bir modifikasyon sonra, benim sorun çözüldü.

Final answer

Kabul cevabı sorunu çözmek yaptım rağmen, biz, e-postaların binlerce birlikte, sunucu üzerindeki tüm kullanılabilir belleği çiğneme olduğunu bulundu. Bu e-posta çerçevenin orijinal geliştirici web sitesini kontrol ve fonksiyon aşağıdaki güncelleştirilmiş olmuştu bulundu:

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, $replacement , $input);
        }
        if (!empty($matches[1])) {
            $input = str_replace(' ', '=20', $input);
            $input = '=?' . $charset .  '?Q?' .$input . '?=';
        }
        return $input;
    }

düzgünce sorunu çözmüş ve mem sınırının altında kaldı hangi.

4 Cevap

(Bakınız RFC 2047) yanı arasındaki boşluk kodlamak gerekir:

(=?ISO-8859-1?Q?a?= =?ISO-8859-1?Q?b?=)     (ab)

Komşu 'kodlu word adlı arasındaki beyaz boşluk gösterilmez.

[...]

(=?ISO-8859-1?Q?a_b?=)                      (a b)

Kodlanmış metnin bir bölümü içinde görüntülenecek bir SPACE neden amacıyla, SPACE 'kodlanmış-kelime' bir parçası olarak kodlanmış GEREKIR.

(=?ISO-8859-1?Q?a?= =?ISO-8859-2?Q?_b?=)    (a b)

Bir UZAY kodlanmış metnin iki dizeleri arasındaki görüntülenmesine neden amacıyla, SPACE 'kodlanan kelime en birinin parçası olarak kodlanmış OLABİLİR.

Peki bunu yapmak gerekir:

Subject: =?ISO-8859-1?Q?=C1ngel=20R=EDos?= escucha y sorprende

Edit Bu fonksiyonu deneyin:

function _encodeHeader($str, $charset='ISO-8859-1')
{
    $words = preg_split('/(\s+)/', $str, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
    $func = create_function('$match', 'return $match[0] === " " ? "_" : sprintf("=%02X", ord($match[0]));');
    $encoded = false;
    foreach ($words as $key => &$word) {
        if (!ctype_space($word)) {
            $tmp = preg_replace_callback('/[^\x21-\x3C\x3E-\x5E\x60-\x7E]/', $func, $word);
            if ($tmp !== $word) {
                if (!$encoded) {
                    $word = '=?'.$charset.'?Q?'.$tmp;
                } else {
                    $word = $tmp;
                    if ($key > 0) {
                        $words[$key-1] = preg_replace_callback('/[^\x21-\x3C\x3E-\x5E\x60-\x7E]/', $func, $words[$key-1]);
                    }
                }
                $encoded = true;
            } else {
                if ($encoded) {
                    $words[$key-2] .= '?=';
                }
                $encoded = false;
            }
        }
    }
    if ($encoded) {
        $words[$key] .= '?=';
    }
    return implode('', $words);
}

Mbstring ve UTF dönüşümleri Look up. İngilizce dışındaki dillerde özel karakterlerin çoğu UTF8 karakter kümesi ele alınır.

UTF8 konu dize dönüştürme ve e-posta gibi gönderilen sağlamak doğru bir konu satırları işlemek gerekir.

Biz benzer bir sorun e-posta gönderme vardı en azından o zaman bizim için yaptım

eklemek

$input = str_replace('?', '=3F', $input);

Bu fragmanın in:

if (!empty($matches[1])) {
$input = str_replace('?', '=3F', $input);
$input = str_replace(' ', '=20', $input);
$input = '=?' . $charset .  '?Q?' .$input . '?=';
}

Sorun? = Kodlama sonuna yakın göründüğü gibi, daha iyi Subject: =?ISO-8859-1?Q?=C1ngel R=EDos escucha y sorprende?= göndermek istiyorum görünür.