Pravděpodobně jste už někdy ve své PHP aplikaci potřebovali naprogramovat odesílání mailů a jistě se shodneme, že zkoušet, zda funguje správně, není na vývojovém PC úplně pohodlné. Někteří to řeší tak, že to odzkouší až na testovacím serveru, jiní doufají, že se to tak nějak správně odesílá. Správným fungování máme na mysli to, že se do e-mailu generuje to, co se tam generovat má.
Možnost 1 – použití živého SMTP serveru
Pro použití SMTP serveru není potřeba žádného složitého nastavování. Stačí v php.ini
nastavit adresu SMTP serveru (třeba od vašeho providera), a je to.
SMTP = smtp.t-email.cz
smtp_port = 25
sendmail_from = martin.hujer@example.com
Hodnotu sendmail_from
nastavte na nějaký reálný e-mail, protože jinak může SMTP bránit odeslání nebo budou maily na straně příjemce padat do SPAMu. Toto, na první pohled jednoduché, řešení má velkou nevýhodu – může se snadno stát, že z aplikace omylem odešlete testovací e-maily přímo zákazníkům (vzpomeňme na známou testovací SMS serveru iHNed). Ale na druhou stranu se může hodit, když potřebujete otestovat zobrazení HTML e-mailů v různých webmailech. Jinak je většinou vhodnější použít nějaké jiné řešení, třeba dummy SMTP server.
Poznámka: Pokud vyvíjíte na Windows, můžete zkusit alternativu k sendmailu – fake sendmail.
Možnost 2 – použití dummy SMTP serveru
Tzv. dummy (neboli fiktivní) SMTP server je aplikace, která se z pohledu PHP chová jako běžný SMTP server, ale e-maily si nechává v sobě a nikam je neodesílá. Nemůže se vám tedy stát, že odešlete něco, co jste nechtěli. Jako příklad použijeme smtp4dev (spoustu dalších si můžete najít vyhledáním dummy smtp server). Program se po spuštění tváří jako lokální SMTP server, takže stačí v php.ini
změnit SMTP:
SMTP = localhost
Po odeslání testovacího mailu vyskočí bublina
a e-mail si můžeme prohlédnout v hlavním okně
Po poklikání se e-mail otevře jako náhled ve výchozím programu (může to být například Outlook nebo Thunderbird). Případně je možné si zobrazit detaily zprávy včetně hlaviček v interním prohlížeči aplikace.
Možnost 3 – ukládání e-mailů do souborů
Pokud si nechcete instalovat další program, můžete použít řešení, které jsme dali dohromady s Tomášem Fejfarem. V php.ini
máme volbu sendmail_path
, která je v distribučním balíčku zakomentovaná a je u ní komentář „For Unix only“. Ale toho se nebudeme bát, odkomentujeme jej, a protože volba může obsahovat jakýkoliv příkaz, vložíme tam toto:
sendmail_path = "more | i:\xampplite\sendmail\savemail.bat"
Vše, co by se předávalo sendmailu, předáme skriptu příkazové řádky, který vypadá takto:
savemail.bat
::kam budeme ukládat e-maily? SET mailpath=I:\xampplite\sendmail\mails if not exist %mailpath% mkdir %mailpath% ::pokud je ráno mezi 0-9h, tak musíme hodiny získat jiným způsobem - " 0" jinak dělá neplechu v názvu souboru IF %time:~0,2% EQU 0 ( SET hours=0%time:~1,1% ) ELSE ( SET hours=%time:~0,2% ) ::sestavíme název souboru SET filename=20%date:~11,4%-%date:~6,2%-%date:~3,2%_%hours%-%time:~3,2%-%time:~6,2%_%time:~9,2% ::zajistíme unikátnost souboru :random SET file=%mailpath%\%filename%%RANDOM%.eml IF EXIST %file% goto :random ::e-mail uložíme do souboru more %1 > %file% ::otevřeme adresář s e-maily Průzkumníkem :: start %mailpath% ::a nebo přímo otevřeme e-mail start %file%
Tento dávkový soubor vytvoří jméno souboru podle aktuálního data a času, uloží do něj obsah e-mailu a složku s e-maily otevře v Průzkumníku (nebo otevře přímo e-mail).
Řešení pro Linux
Na Linuxu je možné nastavit sendmail_path
takto:
sendmail_path = "/home/martinhujer/mail/send.sh"
A použít skript:
send.sh
#!/bin/sh
#kam budeme ukládat e-maily?
mailpath=/tmp
#název souboru
file=$(date +"%Y-%m-%d")\_$(date +"%H-%M-%S_%N")".eml"
echo $mailpath/$file
#mail ze /dev/stdin uložíme do souboru
while read x ; do echo $x >> $mailpath/$file ; done
Ten uloží e-mail do souboru do adresáře /tmp
. (Otevření souboru jsem zde neřešil – pozn.aut.)
Možnost 4 – ukládání e-mailů do souborů přímo v aplikaci
Pokud PHP framework podporuje odesílání e-mailů, tak většinou umožňuje použití různých adaptérů (transportů) pro odesílání e-mailů (pomocí funkce mail()
, přes SMTP,…). Není tedy problém si vytvořit svoji implementaci transportu, která bude e-maily ukládat do souboru. Například Zend Framework takový adaptér obsahuje již v základu, použití může vypadat takto:
<?php
require_once 'Zend/Loader/Autoloader.php';
Zend_Loader_Autoloader::getInstance()->setFallbackAutoloader(true);
Zend_Mail::setDefaultTransport(
new Zend_Mail_Transport_File(
array(
'path' => __DIR__,
'callback' => function() {
do {
$file = 'email-' . date('Y-m-d_H-i-s') . '_' . mt_rand() . '.eml';
} while (file_exists($file));
return $file;
},
)
)
);
$mail = new Zend_Mail('utf-8');
$mail->addTo('mhujer@gmail.com');
$mail->setSubject('Test subj');
$mail->setBodyText('test text');
$mail->send();
Tuto možnost je vhodné kombinovat s ukládáním mailů odeslaných přímo přes mail()
– může se stát, že v kódu někde je zapomenuté přímé volání této funkce, tak aby vám nějaký odesílaný e-mail neušel.
Závěr
V článku jsme si ukázali, jak lze testovat odesílání e-mailů z PHP třeba i o něco elegantněji, než prostým posláním a následnou kontrolou e-mailové schránky. Pokud používáte ještě nějaké jiné (a třeba lepší) řešení, podělte se o něj v diskusi.
Přehled komentářů