Strona używa cookies (ciasteczek). Dowiedz się więcej o celu ich używania i zmianach ustawień. Korzystając ze strony wyrażasz zgodę na używanie cookies, zgodnie z aktualnymi ustawieniami przeglądarki.    X

Polskie znaki w temacie maila w PHP

Dzisiaj krótki wpis, ale mam nadzieję przydatny. Jeśli wysyłacie maile funkcją mail() w PHP być może natknęliście się na problem polskich znaków. W samej treści maila z problemem radzimy sobie dodając dodatkowy nagłówek – na co pozwala funkcja mail() np: $naglowek =....; $naglowek .="Content-type: text/html; charset=utf-8"; mail('adres@mail.pl',$temat,$tresc,$naglowek)Niestety dodanie nagłówka nie ma wpływu na kodowanie znaków w temacie maila. Aby poradzić sobie z tym problemem musimy zakodować base64 temat i dodać do tematu odpowiednie informacje o kodowaniu:$temat= "=?UTF-8?B?".base64_encode("Temat z ogonkami ęóąśłżźćń")."?=";Po pierwszym znaku zapytania dajemy informacje o kodowaniu znaków, po następnym o kodowaniu base64 (literka „B”).

Cytując manual PHP o base64:

Ten sposób kodowania został zaprojektowany, aby móc bezpiecznie przesyłać dane binarne, poprzez warstwy transportujące nie zaprojektowane do obsługi 8 bitowego przesyłania informacji, np. treść emaila.
 

programowanie

Komentarze

0 nowych
gowain   19 #1 16.03.2012 13:01

Tak... na początku swojej drogi z php głowiłem się nad tym cholernie długo, na szczęście problem udało się rozwiązać :)

Xelosu   4 #2 16.03.2012 15:02

1) $temat= "=?UTF-8?B?".base64_encode("Temat z ogonkami ęóąśłżźćń")."?=";
Po co tutaj .base64_encode ?

2) Szkoda tylko, że używanie polskich znaków w temacie jest i tak nie zgodne z przyjętym standardem.
Ogólnie przyjmuje się, że znaki nie należące do kodu ASCII nie powinny znajdować się nigdzie poza strumieniem oznaczonym jako stricte tekstowy (czyt. przeznaczony tylko dla człowieka).

Wynika to z prostego faktu, że większość robotów ma problemy z interpretowaniem takiego tekstu.
Jest prawie gwarantowane, że cześć serwerów pocztowych źle to zinterpretuje i odrzuci wiadomość.

Jeśli stosujesz ten skrypt wysyłając mail ze strony do siebie i wiesz że one dochodzą to jeszcze jeszcze. Ale jeśli miałby on wysyłać maile na podany adres to klapa.

slepciu   11 #3 16.03.2012 15:34

@Xelosu - Odpowiadając na pytanie nr 1: po to żeby uniknąć problemów z pytania nr 2.
base64_encode koduje znaki, dzięki czemu w czasie przesyłania tematu nie ma w nim polskich znaków, litera po drugim znaku zapytania informuje klienta pocztowego o kodowaniu użytym w temacie (B-oznacza - base64), dzięki temu takie tematy przechodzą przez serwery poczty bez problemu.
Wyślij sobie wiadomość za pomocą jakiegoś klienta pocztowego i sprawdź jej źródło, zobaczysz podobny zapis, np temat użyty w artykule wysłany za pomocą Gmaila wygląda tak:
=?ISO-8859-2?B?UG9sc2tpZSB6bmFraSCx6rbmv7zx87M=?=
Różni się tylko tym, że Gmail używa innego kodowania zamiast UTF-8
Sposób jest sprawdzony na setkach i działa na 100%

WODZU   17 #4 16.03.2012 16:52

Kolejny przydatny wpis :)

gowain   19 #5 16.03.2012 18:34

@RaveStar Swoją drogą jestem ciekaw czy rzeczywiście nie występują takie problemy w innych językach... akurat wydaje mi się, że problem w php z polskimi znakami głównie polega na tym, że nie możesz wymusić na użytkowniku określonego kodowania znaków... możesz jedynie potem próbować konwertować na różne sposoby to co dostajesz...

slepciu   11 #6 17.03.2012 00:48

@gowain - "to, że ktoś straci ogonki, to jego sprawa. UTF8 to podstawa i każdy powinien się tego trzymać" - niestety takie podejście w aplikacjach internetowych jest nie do przyjęcia jeśli chcesz tworzyć aplikacje działające u większości użytkowników. Nie masz wpływu na to jakiej przeglądarki, cz klienta pocztowego używa odwiedzający stronę.

gowain   19 #7 17.03.2012 13:35

@splepciu No otóż to, to Ty musisz zadbać, żeby dane, które ktoś wprowadza np. w formularzu były poprawnie zapisane (utf-8), ale jest jeszcze druga strona - robisz formularz, który wysyła kopię wiadomości do jego twórcy - Jeżeli ktoś ma na stałe ustawione inne kodowanie niż utf-8 (np win-1250) to nic nie poradzisz, zawsze się zrobią krzaczki...

gowain   19 #8 17.03.2012 13:36

Sorki za literówkę w nicku :)

iluzion   5 #9 17.03.2012 15:45

@RaveStar

Wskaż języki pozbawione problemów.

"w Javie na Windows XP, która ustawia znaki dla UI z Windows (1250) przez co gdy w bazie mamy UTF, to wypuszczenie takiego stringa na ekran zawsze źle się kończy"

To co jest lepsze? "Automat", który coś sobie ustawia, czy kontrola nad kodowaniem? Autor wpisu pokazał prostą, może niezbyt elegancką, ale skuteczną metodę, niezależną od języka programowania, czyli konkatenację ciągu znaków. W rezultacie otrzymał to czego wymaga standard. Przykład:

From: =?US-ASCII?Q?Keith_Moore?=
To: =?ISO-8859-1?Q?Keld_J=F8rn_Simonsen?=
CC: =?ISO-8859-1?Q?Andr=E9?= Pirard
Subject: =?ISO-8859-1?B?SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=?=
=?ISO-8859-2?B?dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==?=

http://www.ietf.org/rfc/rfc2047.txt

OT:

Prawidłowe rozwiązanie tego problemu w Pythonie.

>>> from email.message import Message
>>> from email.header import Header
>>> msg = Message()
>>> msg['Subject'] = Header(u'Temat z ogonkami ęóąśłżźćń', 'utf-8')
>>> print msg.as_string()
Subject: =?utf-8?b?VGVtYXQgeiBvZ29ua2FtaSDDqsOzwrnCnMKzwr/Cn8Omw7E=?=

Jako ćwiczenie polecam napisanie klasy/funkcji w swoim ulubionym języku programowania, która wysyła maile z załącznikami do wskazanych adresatów. Wiadomość ma zawierać znaki non-ascii (np. z polskimi ogonkami) w tytule, treści, nazwie adresatów, nazwach plików z załącznika i ma być wyświetlana poprawnie w popularnych programach pocztowych: Outlook, Thunderbird, Opera Mail.

iluzion   5 #10 17.03.2012 18:06

Ups... IDLE mnie oszukało. Powinno być:

Subject: =?utf-8?b?VGVtYXQgeiBvZ29ua2FtaSDEmcOzxIXFm8WCxbzFusSHxYQ=?=

Sprawdzenie:

>>> import base64
>>> print base64.b64decode('VGVtYXQgeiBvZ29ua2FtaSDEmcOzxIXFm8WCxbzFusSHxYQ=').decode('utf-8')
Temat z ogonkami ęóąśłżźćń

  #11 13.05.2012 11:31

Dziekuje, nareszczie uporalem sie z tym problemem.

slepciu   11 #12 14.05.2012 10:54

@Anj. - proszę bardzo :)

  #13 15.06.2012 21:18

Dzięki wielkie za to rozwiązanie! A już myślałem, że nie ma na to rozwiązania i do tej pory jakoś sobie 'radziłem' :)

slepciu   11 #14 19.06.2012 13:55

@GrzegorzD (niezalogowany) - cieszę się, że mogłem pomóc :)

  #15 05.11.2012 22:01

Dzięki wielkie. Już straciłem nadzieję.

  #16 07.11.2012 10:43

śmiga :D dzięki wielkie!

  #17 08.11.2012 00:13

Użyłem tego sposobu, tylko ze w mym przypadku posłużyłem się akurat kodowaniem ISO, które odpowiadało całej aplikacji webowej.

Dziękuję za poradę.

  #18 03.02.2013 15:47

no i pomogło:)

slepciu   11 #19 05.02.2013 19:08

@Dominik Wójcik - no cieszę się :)

  #20 07.08.2013 20:10

Rozwiazanie dziala prawidlowo i maile przychodza teraz z polskimi znakami i z polskim tytulem...jednak u mnie pojawil sie nowy problem - tresc maila przychodzi jako tekst zapisany w jednej linii (wczesniej uklad tresci maila byl zgodny z tym wpisanym do formularza; uwzglednial przerwy miedzy akapitami "tzw entery :)"). Co zrobic z tym fantem?

slepciu   11 #21 14.08.2013 19:23

Prawdopodobnie chodzi o nagłówek: "Content-type: text/html; charset=utf-8", który podałem w przykładzie, a który powoduje, że treść maila jest traktowana jako HTML, a w HTML'u przejścia do nowej linii są ignorowane. Musisz albo użyć znaczników HTML do formatowania tekstu, albo zmienić ten naglówek na "Content-type: text/plain", to powinno rozwiązać problem.

  #22 27.08.2013 19:32

Dobry wpis - przydał się! Podziękowania dla autora! :)

  #23 10.10.2013 14:59

Super dzięki !

  #24 28.11.2013 07:21

Wielkie dzięki za info, szukałem rozwiązania przez kilka dni a tu proszę :)

  #25 05.12.2013 16:27

Super! tego właśnie szukałem, wielki dzięki!

  #26 05.12.2013 19:08

no dobra, ale jak zrobic aby w polu Nadawca byly polskie znaki ? :)))) czyli zamiast przyklad@przyklad.pl bylo:
Chrząszcząóśłżśćńę ?

Bo z tym sie mecze i nie moge zrobic:/

  #27 05.06.2014 13:28

Niestety to rozwiązanie nie działa. Próbowałem na różne sposoby - łącznie z przykładem minimalnym tj.
podanym w treści artykułu. Za każdym razem temat maila dochodzi w części tzn. zostaje ucięty w miejscu wystąpienia pierwszego polskiego znaku i reszt tematu nie widać.

slepciu   11 #28 05.06.2014 20:32

@asdf132 (niezalogowany) - sprawdź kodowanie plików PHP, choć nie jestem pewny czy tu leży problem. Sposób opisany w artykule stosuje w wielu aplikacjach internetowych i działa bez problemu, więc błędu szukałbym gdzie indziej

  #29 02.01.2016 11:54

mam problem z kodowaniem polskich znaków używam następującego kodu gdzie należy dodać kodowanie z powyższego przykładu ? oto mój kod

";

} else {


isset($_POST['From']);
strlen($_POST['subject'])>0;
$to = ".....@wp.pl.";



$subject = " " . $_POST['subject'];
$header = "From: " . $_POST['from'];
$message = "Treść: " . $_POST['message'];
$result = mail($to, $subject, $message, $header);
?>

slepciu   11 #30 11.01.2016 10:58

@Anonim (niezalogowany):
Jeśli chodzi o treść maila to tutaj:
$header = "From: " . $_POST['from'] . "\r\n" .
"Content-type: text/html; charset=utf-8";