Posílání mailů v PHP pomocí PHPMaileru

V tomto článku se budeme zabývat využitím třídy PHPMailer k posílání mailů pomocí programovacího jazyka PHP. Článek je zaměřen na ty, kterým nevyhovuje použití vestavěné funkce mail(), buď kvůli tomu, že si nechtějí na vlastní PC, na němž jim PHP běží, poštovní server (SMTP) a nebo využívají služeb SMTP serveru, který požaduje autentizaci uživatele.

Instalace PHPmaileru

Z webové stránky PHPmaileru si stáhneme aktuální verzi – v době psaní článku je to 2.1 (phpmailer for php5) z června 2008. K dispozici jsou dva balíčky – jeden zabalený zipem, druhý gzipem. Oba balíčky jsou funkčně rovnocenné, vyberte si podle vlastní chuti (většinou zip pro Windows, gzip pro Unixové systémy). Po rozbalení uvidíme několik souborů, důležité jsou class.phpmailer.php a class.smtp.php. Tyto soubory buď umístíme někam v rámci include_path v PHP (do adresáře, který najdeme v souboru php.ini) a nebo do adresáře naší aplikace. První způsob nám umožní vkládat PHPMailer do našich aplikací pomocí include "class.phpmailer.php";, u druhé metody budeme muset pro každou aplikaci zkopírovat soubor do adresáře aplikace a potom vkládat pomocí include "./class.phpmailer.php";.

Zbývá jen podotknout, že u většiny hostingů zřejmě nebude možné zkopírovat soubory do include_path, na druhou stranu by měl být webhoster schopen na požádání PHPMailer nainstalovat.

České chybové hlášky

V případě, že chcete, aby PHPMailer obsahoval i české chybové hlášky, je potřeba ještě z instalačního balíčku z adresáře language zkopírovat soubor phpmailer.lang-cz.php do adresáře, do kterého jsme již dříve umístili soubor class.phpmailer.php. Nastavení českých chybových hlášek provedeme pomocí zavolání metody SetLanguage: $mail->SetLanguage("cz");, kterou můžeme umístit kamkoliv mezi vytvoření objektu $mail a odeslání e-mailu pomocí $mail->Send(). Viz ukázku kódu v následující části.

Rychle rychle, chci posílat maily

V této části si ukážeme jednoduchý kód pro poslání e-mailu a tento si okomentujeme.

<?php
  require "class.phpmailer.php";
  $mail = new PHPMailer();
  $mail->IsSMTP();  // k odeslání e-mailu použijeme SMTP server
  $mail->Host = "adresa.smtp.serveru";  // zadáme adresu SMTP serveru
  $mail->SMTPAuth = true;               // nastavíme true v případě, že server vyžaduje SMTP autentizaci
  $mail->Username = "jmenouzivatele";   // uživatelské jméno pro SMTP autentizaci
  $mail->Password = "heslo";            // heslo pro SMTP autentizaci
  $mail->From = "skript@example.com";   // adresa odesílatele skriptu
  $mail->FromName = "Testovací skript"; // jméno odesílatele skriptu (zobrazí se vedle adresy odesílatele)

  $mail->AddAddress("prvni.prijemce@example.com");  // přidáme příjemce
  $mail->AddAddress("druhy.prijemce@example.net", "Jméno druhého příjemce");  // a klidně i druhého, včetně jména

  $mail->Subject = "První mail poslaný pomocí PHPMaileru";    // nastavíme předmět e-mailu
  $mail->Body = "Ahoj ahoj!\n\n Posílám ti první svůj první e-mail přes PHPMailer.";  // nastavíme tělo e-mailu
  $mail->WordWrap = 50;   // je vhodné taky nastavit zalomení (po 50 znacích)
  $mail->CharSet = "utf-8";   // nastavíme kódování, ve kterém odesíláme e-mail

  if(!$mail->Send()) {  // odešleme e-mail
     echo 'Došlo k chybě při odeslání e-mailu.';
     echo 'Chybová hláška: ' . $mail->ErrorInfo;
  }
  else
  {
     echo 'E-mail byl v pořádku odeslán.';
  }
?>

První dva řádky nám načtou třídu PHPMaileru a vytvoří instanci třídy PHPMailer, pojmenovanou $mail. Na dalším řádku nastavíme, že chceme poštu odesílat přes SMTP server, pro který následně nastavíme adresu serveru, zapneme SMTP autentizaci a uživatelské jméno a heslo pro SMTP autentizaci. V případě, že použijeme SMTP server, který SMTP autentizaci nevyžaduje (těch je minimum), uvedeme jako hodnotu proměnné SMTPAuth false a následující dva řádky (nastavení uživatelského jména a hesla) můžeme vynechat.

Nyní následují nastavení samotné e-mailové zprávy. Nejdříve nastavíme položku From – tzn. e-mailovou adresu odesílatele skriptu (ta se zobrazí příjemci), případně ještě doplněnou o jméno odesílatele skriptu – ten je v proměnné FromName. Jedním z nejdůležitějších kroků je nastavení příjemců e-mailu. Toho dosáhneme zavoláním metody AddAddress(). Tato metoda má jeden povinný a jeden nepovinný parametr. Prvním, povinným, parametrem je e-mailová adresa příjemce, druhým, volitelným, je jeho jméno. (E-mailové programy většinou zobrazují odesílatele/příjemce e-mailu ve tvaru Jméno příjemce <e-mailová adresa příjemce>).

Teď nám zbývá jen nastavit předmět zprávy – proměnnou Subject a samotný obsah zprávy – proměnnou Body. V obou dvou můžeme bez problémů použít diakritiku. Obsah proměnné Subject v sobě nesmí obsahovat odřádkování (\n) a je rozumné jej zvolit v přiměřené délce (do 60 znaků). V obsahu e-mailu – proměnné Body – můžeme odřádkování (pomocí \n) použít. Co nemůžeme použít, jsou značky jazyka HTML (<br>, <hr> apod.). O jejich použití si povíme dále. Posledními dvěma nastaveními jsou proměnné WordWrap a CharSet. WordWrap určuje znak, za nímž dojde k zalomení textu. Obsah proměnné CharSet rozhoduje o tom, zda-li se vaše e-mailová zpráva s diakritikou zobrazí příjemci jako „rozsypaný čaj“ a nebo jako čitelný text. Proto je potřeba tuto proměnnou správně nastavit podle kódování použitého v PHP skriptu.

Poslední část naší ukázky odesílá e-mail pomocí metody Send() a v případě neúspěchu i chybovou hlášku.

Posílání e-mailů v HTML

PHPMailer obsahuje i podporu pro posílání e-mailů ve formátu HTML. Zapnout podporu pro e-maily ve formátu HTML je možné jedním ze dvou způsobů. Buď zavoláme explicitně $mail->IsHTML(true); a nebo nastavíme obsah proměnné AltBody. Obě tyto metody přepnou MIME typ zprávy na multipart/alternative.

Tělo e-mailu v HTML ukládáme, stejně jako u textových e-mailů, do proměnné Body. Abychom umožnili zobrazit nějaký obsah i klientům, kteří HTML obsah nepodporují, je nanejvýš vhodné uložit do proměnné AltBody textovou alternativu HTML obsahu e-mailu.

Relevantní část kódu může vypadat následovně:

...
  $mail->IsHTML(true); // tento řádek je zbytečný, protože níže nastavujeme obsah proměnné AltBody
  $mail->Body = "<html><body>Obsah e-mailu<br>včetně <b>nejrůznějších</b> HTML značek<hr></body></html>";
  $mail->AltBody = "Alternativní textový obsah pro e-mail, bez HTML značek";
...

Důležité upozornění – vidíme, že e-mail v HTML by měl obsahovat značku <html> a <body>, neboť přítomnost těchto značek v HTML e-mailech kontrolují některé antispamové nástroje, a náš e-mail by tak klidně mohl být označen jako spam.

To je zatím vše, příště (to nevím kdy bude) si ukážeme posílání e-mailů s přílohami, to jak přiloženými, tak vloženými.

Příspěvek byl publikován v rubrice PHP se štítky , , . Můžete si uložit jeho odkaz mezi své oblíbené záložky.

33 komentářů u Posílání mailů v PHP pomocí PHPMaileru

  1. trancemaniac napsal:

    Chtěl bych se zeptat, zda nevíte někdo, proč zpráva nelze odeslat na seznam?
    Chybová hláška: Language string failed to load: recipients_failedneco@seznam.cz

  2. admin napsal:

    Chybová hláška skrývá 2 věci. Nepodařilo se načíst správný překlad chybové hlášky „recipients_failed“, což by ukazovalo na nenalezený soubor s překlady (např. phpmailer.lang-cz.php pro český překlad).

    Samotný problém, na který tato hláška má upozornit, je že neco@seznam.cz není platným příjemcem e-mailu. Záleží na tom, jestli používáš odesílání přes SMTP server a nebo přes funkci „mail“. V případě SMTP bude zřejmě nutné použít SMTP autentizaci, abys mohl odesílat e-maily i na jiné domény než jsou nastaveny v konfiguraci SMTP serveru. V případě nepoužití SMTP serveru bohužel poradit neumím.

  3. trancemaniac napsal:

    Paráda už to fungujem použil jsem tu autentizaci, díky 🙂

  4. Lonanek napsal:

    Mám dotaz ohledně funkce phpmailera na serverech WZ.CZ.
    100% chodí na localhost, ale na servru webzdarma.
    Hláška:
    Parse error: parse error, expecting `T_OLD_FUNCTION‘ or `T_FUNCTION‘ or `T_VAR‘ or `‘}“ in /3w/wz.cz/k/kksmirice/class.phpmailer.php on line 45

    Samozřejmě následují další protože není správně načtena instance. Už si sám nevím rady, prosím HELP ME

    Děkuji

  5. admin napsal:

    Nevím, jakou verzi PHP má wz.cz nainstalováno, ale PHPmailer existuje ve variantách jak pro php 4, tak pro php 5/6, takže je potřeba stáhnout správnou verzi…

  6. Lonanek napsal:

    Domníval jsem se, že má 5-ku. Bohužel ne, 4 je na wz.cz maximum.
    Problém je v tom, že stejně není funkční protože wz-tko nemá povoleno fsockopen.

    Díky.

  7. Pingback: E-maily s přílohou v PHP - PHPmailer | nufue's

  8. Als napsal:

    Diky moc ! Prave jsem tuhle tridu potreboval a Tento clanek mi hodne pomohl. V podstate bych potreboval jeste vyresit odesilani obrazku a bude to ok 😉

  9. Vojta napsal:

    dobrý den,

    php mailer mi normalne fungoval……z niceho nic mi ale nefunguje, nejsem si vedom, ze bych neco podstatneho menil = chybova hlaska : Language string failed to load: instantiate nevíte kde je problem?? diky za jakoukoli radu

  10. Vojta napsal:

    jeste bych chtel dodat ze nepouzivam SMTP

  11. David Hynek napsal:

    Dobrý den,

    sluší se poděkovat, s tímhle jsem se pral dost dlouho a bez nějakého úspěchu, sice jsem zprovoznil mail, ale ten mi fungoval jen někde a někdy, ale nikdy na mém počítači, takže jsem měl dost problémy s testováním a psaním scriptů… Děkuji ještě jednou velmi moc :o) David Hynek

  12. Pingback: Čeština v předmětu e-mailu (PHP) | nufue's

  13. kalows napsal:

    Z textu jsem vytušil, že není rozdíl mezi instalací na serveru nebo na localhostu. Je to tak?

  14. admin napsal:

    @kalows
    rozdíl není, neboť spočívá jen ve zkopírování souborů

  15. kalows napsal:

    Je možné zablokovat v phpmaileru vypisování chybových hlášení, např.: „SMTP Error: Could not authenticate.“ ?

    Nechávám si je vypisovat z vlastního skriptu pomocí ($mail->ErrorInfo), výpis od phpmailera je duplicitní a narušuje mi stránku.

    Děkuju.

  16. admin napsal:

    @kalows

    zkusil bych
    $mail->SMTPDebug = 0;
    ...
    try {
    $mail->send();
    } catch (phpmailerException $e) {
    echo $e->errorMessage();
    } catch (Exception $e) {
    echo $e->getMessage();
    }

  17. kalows napsal:

    Pokusně generuji a odesílám v cyklu větší počet zpráv, které se liší pouze v oslovení. PHPmailer aktivuji při každém průchodu cyklu, přjemcem zpráv jsem rovněž já. Pokusím-li se odeslat více než čtyři zprávy, odejdou pouze čtyři. Zatím jsem ještě nezjistil, zda jsou to první čtyři v pořadí. U všech ostatních se objeví chybové hlášení:

    SMTP Error: Could not authenticate.

    Takto vše probíhá, ať zkouším pokusné zprávy adresovat na jednu adresu nebo na více adres. Všechny tři adresy mám u jednoho poskytovatele (www.savana.cz). Mám hledat problém i nadále u sebe (zatím se mi to nedaří) nebo může být problém i na straně poskytovatele, přestože je odesílání částečně funkční?

    Děkuju.

  18. kalows napsal:

    Jsem o trochu chytřejší. Problémy, které jsem popisoval výše jsem si zavinil sám. Protože jsem připravoval hromadné odesílání mailů, musel jsem část kódu z této stránky zacyklovat. Do těla cyklu se mi dostal i řádek:

    $mail = @new PHPMailer(); .

    Tak jsem spouštěl při každém průchodu cyklu novou instanci php maileru. Tím jsem si řekl o mnoho nezdarů a chybových hlášení.

    Pro ty, kteří mají zájem, přikládám vlastní, již funkční úpravu. Odzkoušel jsem ji na smtp.savana.cz, kde mám mailové schránky. Ještě mě čeká vyřešit časové limity odesílání. S dlouhou přílohou se to zakousne s odkazem na class.smtp.php .

    $Zpr = „sem něco napište“
    require „class.phpmailer.php“;
    $mail = @new PHPMailer();
    for ($i = 0; $i SetLanguage(„cz“);
    $mail->IsSMTP(); // k odeslání e-mailu použijeme SMTP server
    $mail->Host = „smtp.savana.cz“;
    $mail->SMTPAuth = true;
    $mail->Username = $NasMail;
    $mail->Password = „moje.heslo“;
    $mail->From = $NasMail;
    $mail->FromName = „Bedřich Hrozný“;
    $mail->AddAddress($Email); // přidáme příjemce
    $mail->Subject = ‚Zpráva od Bédi‘;
    $mail->Body = $Zpr;
    $mail->WordWrap = 50;
    $mail->CharSet = „windows-1250″;
    $mail->AddAttachment($att, $pojmenovat);
    if( !$mail->Send() )
    $Chyby .= $Partner.‘ ‚.$Mail.“\n\t“.$mail->ErrorInfo.“\n“;
    }
    echo $Chyby;

    Hodně zdaru.

  19. kalows napsal:

    Kód má vypadat takto:

    $Zpr = „sem něco napište“
    require „class.phpmailer.php“;
    $mail = @new PHPMailer();
    for ($i = 0; $i SetLanguage(„cz“);
    $mail->IsSMTP(); // k odeslání e-mailu použijeme SMTP server
    $mail->Host = „smtp.savana.cz“;
    $mail->SMTPAuth = true;
    $mail->Username = $NasMail;
    $mail->Password = „moje.heslo“;
    $mail->From = $NasMail;
    $mail->FromName = „Bedřich Hrozný“;
    $mail->AddAddress($Email); // přidáme příjemce
    $mail->Subject = ‚Zpráva od Bédi‘;
    $mail->Body = $Zpr;
    $mail->WordWrap = 50;
    $mail->CharSet = „windows-1250″;
    $mail->AddAttachment($att, $pojmenovat);
    if( !$mail->Send() )
    $Chyby .= $Partner.‘ ‚.$Mail.“\n\t“.$mail->ErrorInfo.“\n“;
    }
    echo $Chyby;

  20. kalows napsal:

    Nedaří se mi vložit správný kód. Znak „je menší“ v cyklu for skrývá text až k prvnímu výskytu znaku „je větší“.

  21. Email z formuláře napsal:

    Chtěl bych využit PHPMailer k odesílání dat z formuláře na můj email. člověk vyplní formulář, svůj email, aplikace např. send.php převezme data z formuláře nacpe proměnné do Body, Subject a odešle. Jenže potřebuji zajistit, aby From drželo data – proměnnou emailu převzatou z formuláře. Toto ovšem nefunguje, pokud zde není vložena stejná emailová adresa jako v Username. Děkuji.

  22. admin napsal:

    @Email z formuláře: to je otázkou nastavení SMTP serveru, s phpMailerem to nejspíš nemá žádnou spojitost. Bez konkrétní chybové hlášky těžko hodnotit.

  23. Hromadné odesílání napsal:

    Ahoj, podařilo se mi rozběhnout hromadné odesílání, problém je ale v tom, že zpráva se sice odešle bez žádné chyby, ale nikomu nedojde. Chybová hláška nic nevypíše. Pokud to ale odešlu například 30ti jiným emailům, tak to dojde v pořádku. Je možné že by mohla být chyba v nějakém emailu, přes který to neprojde? A jde to nějak ošetřit, pokud je neplatný email aby ho přeskočil a odeslalo se to na ten zbytek? Děkuji.

  24. admin napsal:

    @Hromadné odesílání: Co to znamená „nikomu nedojde“? Po jak dlouhé době? Hodina, den, týden?

  25. Hromadné odesílání napsal:

    Odešlu nějaké skupině lidí nějaký email, ale nikdo z té skupiny ho nedostane. Přitom se to ale tváří že je vše v pořádku, ale zpráva nedorazí. Ale když ho pošlu tu samou zprávu jiné skupině, tak jim dorazí. Tím že to nevyhodí žádnou hlášku (jako že třeba email neexistuje), tak jsem celkem v pasti a nevím jak to řešit.

  26. Michal napsal:

    Dobrý den, PHP mailer sem používal normálně a z ničeho nic mi přestal fugovat … vypíšu formulář a dám odeslat a nevýpíše to nic a chybovou hlásku prostě nic 🙁 díky za nějakou pomoc

  27. Michal Juránek napsal:

    Zdravím,

    mám takový problém, že si pomocí php vytvořím na serveru txt soubor, zapísu si do něj text, který je odřádkovaný. Když ten soubor zkopíruji ze serveru do počítače a otevřu v notepadu, tak mám text pořád krásně strukturovaný na řádky.

    Když si ale tento txt soubor pošlu pomocí mail funkce, tak se mi v příloze zruší formátování a řádky jsou spojeny do jedné dlouhé věty.

    Zkoušel jsem hledat na netu a testoval jsem různé mail skripty, ale u všech to zlobí, takže bude problém někde v té mail funkcí, která txt soubor nějak přeformátuje.

    Nemáte někdo tušení jak nebo čím to spravit?

  28. Tombik napsal:

    Díky, přesně tohle jsem potřeboval 🙂

  29. Lukáš Fichna napsal:

    Michal Juránek: místo entru použijte „\n“ a bude to fungovat…
    Jinak děkuji autorovi za článek.

  30. Filip Urban napsal:

    zdravim, rad bych tento skriptik pouzil k posilani udaju z formulare na nastaveny mail, ale nedari se mne prevzit text input poli. Prosim o radu 😉

    dekuji

    SENDMAIL.PHP
    IsSMTP(); // k odeslání e-mailu použijeme SMTP server
    $mail->Host = „out.smtp.cz“; // zadáme adresu SMTP serveru
    $mail->SMTPAuth = true; // nastavíme true v případě, že server vyžaduje SMTP autentizaci
    $mail->Username = „filip.urban@machala.cz“; // uživatelské jméno pro SMTP autentizaci
    $mail->Password = „furban01“; // heslo pro SMTP autentizaci
    $mail->From = „info@machala.cz“; // adresa odesílatele skriptu
    $mail->FromName = „Machala GROUP SE“; // jméno odesílatele skriptu (zobrazí se vedle adresy odesílatele)

    $mail->AddAddress($_POST[‚email‘]); // přidáme příjemce

    $mail->Subject = „dotaz“; // nastavíme předmět e-mailu

    $mail->IsHTML(true); // tento řádek je zbytečný, protože níže nastavujeme obsah proměnné AltBody
    $mail->Body = „Dobrý den Obsah e-mailuvčetně nejrůznějších HTML značek“;
    $mail->AltBody = „Alternativní textový obsah pro e-mail, bez HTML značek“;

    $mail->WordWrap = 50; // je vhodné taky nastavit zalomení (po 50 znacích)
    $mail->CharSet = „iso-8859-2“; // nastavíme kódování, ve kterém odesíláme e-mail

    if(!$mail->Send()) { // odešleme e-mail
    echo ‚Došlo k chybě při odeslání e-mailu.‘;
    echo ‚Chybová hláška: ‚ . $mail->ErrorInfo;
    }
    else
    {
    echo ‚E-mail byl v pořádku odeslán.‘;
    }
    ?>

  31. Adrian napsal:

    chcem sa opýtať že bude mi phpmailer fungovat na localhoste ? napr cez xampp ?

    Dakujem vopred za odpoved

  32. Lea napsal:

    Dobrý den,

    phpmailer se mi bohužel nepodařilo rozchodit. Dříve jsem používala funkci mail, vše fungovalo, dokud nám správce našeho serveru vlastní poštovní server zrušil a přešli jsme na gmail.

    Hledala jsem a našla tento článek a doufala, že mi to problém vyřeší. Bohužel – když spustím soubor pokus.php (kde jsem jen zkopírovala text výše, přepsala smtp a komu se to má poslat), nakopírovala phpmailer do stejného adresáře jako soubor, ale objeví se mi bílá obrazovka :((

    Nevíte někdo, co s tím?

    Děkuju

Napsat komentář

Vaše emailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *