Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[PHP] Encoding probleem mail bericht

Pagina: 1
Acties:

  • storeman
  • Registratie: April 2004
  • Laatst online: 19:18
Ik gebruik Zend_Mail uit Zend Framework om mails uit te lezen en deze wil ik opslaan in de database.

Encoding instellingen:
Datatabase: UTF8
Iconv: UTF8 (init_set)
mbstring: UTF8 (ini_set)
html-meta: UTF8

Als ik het part met text/html heb gevonden, en deze blijkt "quoted-printable" te zijn, haal ik hier de functie
"quoted_printable_decode"

overheen. In de meeste gevallen werkt dit goed. Ik heb echter een e-mail ontvangen waar deze tekenreeks in staat:
=A0

Dit blijkt een ISO-8858 non-breaking space te zijn. In UTF8 moet dit volgens mij =C2=A0 worden (of \xC2\xA0).

Wat ik heb geprobeerd
PHP:
1
2
3
4
5
protected function _quotedPrintableContent( \Zend_Mail_Part $part ){
        $content = $part->getContent();
        $content = quoted_printable_decode($content);
        return $content;
    }


Als ik dit opsla, geeft Postgres als melding dat \xA0 geen geldig utf-karakter is. Dit klopt volgens mij ook.

code:
1
2
3
4
5
6
protected function _quotedPrintableContent( \Zend_Mail_Part $part ){
        $content = $part->getContent();
        $content = quoted_printable_decode($content);
        $content = mb_convert_encoding($content, 'UTF8');
        return $content;
}


Als ik dit opsla, krijg ik de Â


code:
1
2
3
4
5
6
7
protected function _quotedPrintableContent( \Zend_Mail_Part $part ){
        $content = $part->getContent();
        $content = str_replace(array('=C2=A0', '=A0', '=XX=='), array('=XX==','=XX==', "\xA0"), $content);
        $content = quoted_printable_decode($content);
        $content = mb_convert_encoding($content, 'UTF8');
        return $content;
}


Dit lijkt me sowieso een slecht idee, maar je wilt wat. De laatste \xA0 heb ik ook veranderd naar =C2=A0 of \xC2\xA0

Ik heb ook nog over schillende plekken wat geprobeert met mb_convert_encoding. Ook geen succes..

Google geeft vele hits, maar dit specifieke probleem kan ik helaas nog steeds niet tackelen.

"Chaos kan niet uit de hand lopen"


  • _Peter2_
  • Registratie: November 2008
  • Laatst online: 16:27
Je kan eens kijken bij: http://www.php.net/manual/en/function.utf8-encode.php

Probleem is bekend bij het gebruik van character sets. Een ander potentieel probleem is als er een BOM wordt meegestuurd in het bericht.

[ Voor 11% gewijzigd door _Peter2_ op 08-08-2013 10:16 ]

Diablo III: <GOT> Pteer#2475 --- POE: Dwergux


  • _js_
  • Registratie: Oktober 2002
  • Laatst online: 25-10 14:28
Je e-mail is dus niet in UTF-8, je geeft aan dat je mbstring hebt ingesteld op utf-8, dus als je mb_convert_encoding gebruikt dan zal die er van uitgaan dat je wilt converteren van utf-8 behalve als je specifiek aangeeft welke encoding de mail gebruikt. Als het goed is staat dat in de headers van elk part (of in de headers van het bericht als het niet multipart is). Geef dat op als 3e parameter bij mb_convert_encoding en het zou goed moeten werken.

[ Voor 7% gewijzigd door _js_ op 08-08-2013 10:18 ]


  • storeman
  • Registratie: April 2004
  • Laatst online: 19:18
@_js_

Mee eens, de mail is inderdaad in ISO-8859-1, de characterset kan ik dan ook eenvoudig achterhalen vanuit de part. Wat je zegt over de derde parameter is onjuist. mbstring doet een automatische detectie als je geen parameter meegeeft, maargoed, als nog kan ik hem dan wel meegeven.

De internal_encoding heeft te maken met de output van quoted_printable_decode, en niet met de input volgens mij.

PHP:
1
2
3
4
5
6
7
protected function _quotedPrintableContent( \Zend_Mail_Part $part ){
        $content = $part->getContent();
        $charset = $this->_getHeaderField($part, 'content-type', 'charset');
        $content = mb_convert_encoding($content, $charset, 'Quoted-Printable');
        $content = mb_convert_encoding($content, 'UTF8', $charset);
        return $content;
}

Helaas, nog steeds de Â

PHP:
1
2
3
4
5
6
7
8
protected function _quotedPrintableContent( \Zend_Mail_Part $part ){
        $content = $part->getContent();
        $charset = $this->_getHeaderField($part, 'content-type', 'charset');
        ini_set('iconv.internal_encoding', $charset);
        $content = quoted_printable_decode($content);
        $content = mb_convert_encoding($content, 'UTF8', $charset);
        return $content;
}

Evenzo

@_Peter2_
Ja, die pagina had ik ook al doorgenomen, wat zou ik daarop moeten zien wat mij helpt?

"Chaos kan niet uit de hand lopen"


  • _Peter2_
  • Registratie: November 2008
  • Laatst online: 16:27
Je hebt gelijk, functie zou vergelijkbaar moeten zijn met mb_convert_encoding. Ik kende zelf de functie mb_convert_encoding nog niet. (ging af op mijn eerste hit op convert latin1 to utf8).

Waar zie je die "Â"? Dat is volgens mij namelijk de =C2 in iso8859-1.

Wellicht dat je display dus geen UTF8 gebruikt, maar latin1, waardoor er dus 2 tekens worden gestuurd ipv 1.
(De  gevolgd door een no break space)

[ Voor 22% gewijzigd door _Peter2_ op 08-08-2013 11:44 ]

Diablo III: <GOT> Pteer#2475 --- POE: Dwergux


  • _js_
  • Registratie: Oktober 2002
  • Laatst online: 25-10 14:28
storeman schreef op donderdag 08 augustus 2013 @ 11:01:
@_js_

Mee eens, de mail is inderdaad in ISO-8859-1, de characterset kan ik dan ook eenvoudig achterhalen vanuit de part. Wat je zegt over de derde parameter is onjuist. mbstring doet een automatische detectie als je geen parameter meegeeft, maargoed, als nog kan ik hem dan wel meegeven.
Uit de handleiding:
from_encoding

Is specified by character code names before conversion. It is either an array, or a comma separated enumerated list. If from_encoding is not specified, the internal encoding will be used.
Daarnaast is het natuurlijk erg moeilijk om de encoding automatisch te detecteren, bv. iso-8859-2 of iso-8859-3 daar zit niet veel verschil tussen, dus je kunt het voor de zekerheid beter wel opgeven, zelfs al zou het zo werken als jij dacht.

Voorbeeldcode:
PHP:
1
2
3
4
5
<?php
    $source = "\xa0";
    $converted = mb_convert_encoding($source, 'UTF-8', 'ISO-8859-1');
    echo bin2hex($converted);
?>

Geeft als uitvoor netjes:
code:
1
c2a0


Dit geeft ook weer aan waarom je hier een zo klein mogelijk voorbeeld moet maken, het helpt ook om te zien waar het fout gaat.

[ Voor 23% gewijzigd door _js_ op 08-08-2013 12:00 ]


  • storeman
  • Registratie: April 2004
  • Laatst online: 19:18
Heren bedankt. Ik heb zelf zojuist flink voor de kop geslagen.

Na meer debuggen, blijkt het karakter op 190 (\xa0) te worden omgezet naar \xC2\xA0, dus eigenlijk kan het niet fout in de database staan, was mijn conclusie.

Hoe ik het nu doe:
PHP:
1
2
3
4
5
6
7
8
9
10
11
protected function _quotedPrintableContent( \Zend_Mail_Part $part ){
        $content = $part->getContent();
        
        //var_dump(mb_list_encodings());die();
        $charset = strtoupper($this->_getHeaderField($part, 'content-type', 'charset'));
        
        $content = mb_convert_encoding($content, $charset, 'Quoted-Printable');
        $content = mb_convert_encoding($content, 'UTF-8', $charset);
        
        return $content;
}


Toen ging het licht aan! De output!

De mail wordt uiteindelijk verwerkt en ik doe een paar dingetjes met html via DOMDocument.

PHP:
1
2
3
$html = utf8_decode($mail->content_html);
/* DOMmeDocumentDingen */
echo utf8_encode($dom->saveHTML());

Bovenstaande lost het op.

Ik maakte de denkfout doordat ik in de console ook de  zag, maar de console snapt UTF-8 natuurlijk niet.

Dat zijn 8 uur van mijn leven die ik nooit meer terugkrijg. Bedankt voor het meedenken, heren.

[ Voor 24% gewijzigd door storeman op 08-08-2013 12:38 ]

"Chaos kan niet uit de hand lopen"


  • _Peter2_
  • Registratie: November 2008
  • Laatst online: 16:27
storeman schreef op donderdag 08 augustus 2013 @ 12:05:Dat zijn 8 uur van mijn leven die ik nooit meer terugkrijg. Bedankt voor het meedenken, heren.
Och...zoals iemand mij ooit zei: "De expert is degene die alles al eens fout heeft gedaan".

Kortom, hoewel het je 8 uur heeft gekost, vergeet je dit niet snel weer.

Diablo III: <GOT> Pteer#2475 --- POE: Dwergux

Pagina: 1