Docela nedávno jsem se zasekl při použití funkce mail(). Text e-mailu jsem chtěl mít kódovaný v utf-8, což zprvu nebyl žádný problém. Do hlavičky e-mailu jsem vložil Content-Type: text/plain; charset="utf-8 a bylo po ptákách. :-)
Myslel jsem si, že mám vyhráno. Pokusné odeslané e-maily dorazliy vpořádku. Až po chvíli jsem zjistil, že tyto e-maily zobrazuje dobře snad jen Gmail. Schránka na Centrumu mi z diakritiky v předmětu zprávy udělala otazníky. Bylo mi jasné, že někde musím definovat kódování předmětu zprávy. Jenže kde?
Předmět zprávy stačí vložit v tomto formátu:
"=?utf-8?B?".base64_encode("Toto je text předmětu")."?=".
Content-type se vztahuje jen k tělu zprávy a netýká hlaviček samotného e-mailu! Udělal jsem si tedy funkci, která vrací řetězec ve správně zakódovaném tvaru pro hlavičku:
function zakoduj($text) {
return "=?utf-8?B?".base64_encode($text)."?=";
}
Jistě jste si všimli funkce base64_encode(). Manuál praví, že tato funkce vrací data zakódované pomocí base64. Toto kódování je navrženo tak, aby umožnilo binárním datům přežít transport přenosovými vrstvami, které nejsou osmibitové, jako jsou například těla emailů.
Bohužel při použití této funkce nám data nabydou až o 33%.
Jak tedy na odeslání e-mailu?
function odesli_mail($komu, $predmet, $telo) {
$hlavicka = "MIME-Version: 1.0\n";
$hlavicka.= "Content-Type: text/plain; charset=\"utf-8\"\n";
$hlavicka.= "Content-Transfer-Encoding: base64\n";
$hlavicka.= "From: neco@neco.cz\n";
$hlavicka.= "Reply-To: neco@neco.cz\n";
$telo = Base64_Encode($telo);
$predmet = zakoduj($predmet);
if(mail($komu, $predmet, $telo, $hlavicka))
return TRUE;
else
return FALSE;
}
Nesmíme zapomenout, že se každá hlavička musí zalomit a může obsahovat maximálně 76 znaků! Hlavičku zalomíme vložením \r\n na konec řádku. Matně si ale vzpomínám, že některé servery nahrazují \n za \r\n, takže ve finále vznikne \r\r\n.
Můžeme použít i funkci chunk_split, která za každých 76 znaků vloží \r\n. Samozřejmě lze zvolit i jiné parametry, viz manuál.
Další čtení:
Kategorie: Web a vše kolem něj ≈ 08. 11. 2006 ≈ Počet zobrazení: 6036x
Littlemaple [
1289] -- 09. 11. 2006 01:17:18
Užitečný článek! Díky, je to hezky pohromadě a až to budu potřebovat, budu vědět, že je to tady. Jinak jsem věděl, že s tímto jsou problémy.
littlemaple (zavinac) centrum.cz |
www |
IM: littlemaple@jabber.cz |
Reagovat
Lord AgEnT [
1290] -- 09. 11. 2006 14:45:55
Hmm, zajímavé, podivuhodné ovšem je, že pokud si z centra na centrum pošlete mail, tak se taky rozhodí kodování pouze v předmětu... :/
agent_ (zavinac) centrum.cz |
www |
IM: 162729221 |
Reagovat
MeBa [
1292] -- 12. 11. 2006 11:42:23
Mailum se doporucuju uplne vyhnout. Ja programoval aplikaci, co prijimala emaily (v Perlu) a parsovala je. Kazdy klient je posila jinak a cele MIME je uplne krok mimo podle me :-) Fakt sranda...
Gringo [
1294] -- 12. 11. 2006 21:53:23
Mě se osvědčila třída phpmailer (http://phpmailer.sourceforge.net), plus nějaká ta funkce odněkud na kódování hlaviček (předmět + odesílatel/adresát) v quoted printable, protože php4 to standardně neumí, narozdíl od pětkové verze.
Peca [
1314] -- 27. 11. 2006 18:47:34
Díky za článek. Zrovna to jsem potřeboval, aby mi diskuzní fórum vanilla neposílala zmršené předměty mailů. Někdy mám pocit, že tyhle problémy dělají autoři GPL projektů schválně, aby nás lenochy donutili alespoň trochu se v PHP povrtat :-)).
adobrovolny (zavinac) gmail.com |
Reagovat
ObiSkyWalker [
1475] -- 03. 06. 2007 16:56:14
No paráda, funguje
Díky moc za návod
nick? [
1492] -- 07. 09. 2007 09:19:59
Mě toto bohužel nefunguje, na jednom serveru mi to odřádkuje ty hlavičky a sem v pédeli
spaze [
1497] -- 29. 10. 2007 11:00:56
Odesilat text (coz nejsou binarni data), tedy text i hlavicky, v
Base64 je divny, necitelny apod, na to mame Quoted-Printable. No a pak
dalsi veci, jako chybejici hlavicka Date (ano, je povinna, treba misto
zbytecnyho Reply-To by se naramne hodila, pak je mensi
pravdepodobnost, ze mail zachyti nejakej hodne nabrousenej filtr) a
dalsi veci, ktere jsou v danem clanku zminene, nicmene
neimplementovane (konce radek, zalamani)
Hooonza [
1536] -- 16. 05. 2008 19:50:16
Našel jsem ke kódování hlavičky už hotové funkce: iconv_mime_encode (http://cz.php.net/manual/en/function.iconv-m
ime-encode.php
- v PHP5)vytvoří celou hotovou hlavičku ve správném kódování. mb_encode_mimeheader (http://cz.php.net/manual/en/function.mb-enco
de-mimeheader.php
) hlavičku taky zakóduje