Jak v PHP poslat e-mail s přílohou pomocí MIME třídy
Na Intervalu již vyšel článek „Jak v PHP poslat e-mail s přílohou“, při posílání přílohy se však vloží příloha s příponou .dat, což je způsobeno špatným MIME typem. Budeme zde tedy řešit posílání přílohy e-mailem jiným způsobem a to pomocí MIME třídy.
jak jsem již naznačil, budu vycházet z článku Jak v PHP poslat e-mail s přílohou. Pro pořádek jen upozornění, že veškeré zabezpečení kontroly posílaných údajů si musí udělat už každý uživatel sám.
K řešení problému budeme využívat třídy. Třída je šablonou objektu zahrnující vlastnosti a metody, které popisují objekt a pracují s ním. Následující třída mime_mail poskytuje jednoduché rozhraní k MIME.
Třída mime_mail
Třídu si uložíme jako mime_mail.inc Nalezl jsem ji už jako hotovou na internetu (nakladatelství Wrox Press).
<?
// uložit jako „mime_mail.inc“
class mime_mail
{
var $parts;
var $to;
var $from;
var $headers;
var $subject;
var $body;
/*
* void mime_mail()
* konstruktor třídy
*/
function mime_mail() {
$this->parts = array();
$this->to = „“;
$this->from = „“;
$this->subject = „“;
$this->body = „“;
$this->headers = „“;
}
/*
* void add_attachment(string message, [string name], [string ctype])
* vloží přílohu do objektu zprávy
*/
function add_attachment($message, $name = „“, $ctype = „application/octet-stream“) {
$this->parts[] = array (
„ctype“ => $ctype,
„message“ => $message,
„encode“ => $encode,
„name“ => $name
);
}
/*
* void build_message(array part=
* vytvoření části vícedílné zprávy
*/
function build_message($part) {
$message = $part[ „message“];
$message = chunk_split(base64_encode($message));
$encoding = „base64“;
return „Content-Type: „.$part[ „ctype“].
($part[ „name“]? „; name = \““.$part[ „name“].
„\““ : „“).
„\nContent-Transfer-Encoding: $encoding\n\n$message\n“;
}
/*
* void build_multipart()
* vytváří vícedílnou zprávu
*/
function build_multipart() {
$boundary = „b“.md5(uniqid(time()));
$multipart =
„Content-Type: multipart/mixed; boundary = $boundary\n\nThis is a MIME encoded message.\n\n–$boundary“;
for($i = sizeof($this->parts)-1; $i >= 0; $i–)
{
$multipart .= „\n“.$this->build_message($this->parts[$i]).
„–$boundary“;
}
return $multipart.= „–\n“;
}
/*
* string get_mail()
* vrací vytvořenou zprávu
*/
function get_mail($complete = true) {
$mime = „“;
if (!empty($this->from))
$mime .= „From: „.$this->from. „\n“;
if (!empty($this->headers))
$mime .= $this->headers. „\n“;
if ($complete) {
if (!empty($this->to)) {
$mime .= „To: $this->to\n“;
}
if (!empty($this->subject)) {
$mime .= „Subject: $this->subject\n“;
}
}
if (!empty($this->body))
$this->add_attachment($this->body, „“, „text/plain“);
$mime .= „MIME-Version: 1.0\n“.$this->build_multipart();
return $mime;
}
/*
* void send()
* odesílá zprávu(poslední funkce třídy, kterou je potřeba zavolat)
*/
function send() {
$mime = $this->get_mail(false);
mail($this->to, $this->subject, „“, $mime);
}
}; // konec třídy
?>
Formulář
Následující formulář slouží k zadání e-mailové adresy odesílatele, e-mailové adresy příjemce, ke vložení souboru jako přílohy a případně k napsání stručného textu k e-mailu. Soubor si pojmenujeme send.php:
<? if(empty($_POST[‚akce‘])):?>
<form action=“send.php“ method=“post“ enctype=“multipart/form-data“>
Odesílatel: <input type=“text“ name=“odesilatel“ value=““ size=“50″ maxlenght=“50″ />
Příjemce: <input type=“text“ name=“prijemce“ value=““ size=“50″ maxlenght=“50″ />
Předmět: <input type=“text“ name=“predmet“ value=““ size=“50″ maxlenght=“50″ />
Text: <textarea name=“dopis“ cols=“50″ rows=“10″></textarea>
Soubor: <input type=“file“ name=“soubor“ />
<input type=“submit“ name=“akce“ value=“Odeslat“ />
</form>
<? endif;
Samotný skript který slouží k poslání e-mailu
Pokračujeme zápisem v souboru send.php:
if(!empty($_POST[‚akce‘])):
include „mime_mail.inc“;
// načtení třídy mime_mail
$newFile=“upload/“.$_FILES[‚soubor‘][‚name‘];
// cesta k souboru
move_uploaded_fileCopy($_FILES[‚soubor‘][‚tmp_name‘], „$newFile“);
// nahraný soubor zkopírujeme z dočasného adresáře
if(File_Exists($newFile)):
// kontrola, zda existuje soubor
$fd=FOpen($newFile, „r“);
// otevření souboru pro čtení
$data=FRead($fd, FileSize($newFile));
// binární čtení dat
FClose($fd);
// zavření souboru
$mail=new mime_mail;
// vytvoření instance objektu
$mail->from = $_POST[‚odesilatel‘];
// nastavení údajů
$mail->to = $_POST[‚prijemce‘];
$mail->subject = $_POST[‚predmet‘];
$mail->body = $_POST[‚dopis‘];
$mail->add_attachment($data, $_FILES[‚soubor‘][‚name‘], $_FILES[‚soubor‘][‚type‘]);
$mail->send();
// odeslání e-mailu
echo „Odesláno“;
// potvrzení o odeslání
else:
echo „Chyba“;
// pokud soubor neexistuje
endif;
unlink($newFile);
// smazani dočasného souboru
endif;
?>
Adresářová struktura
V našem projektu nakonec vytvoříme podadresář upload, do kterého budeme dočasně ukládat posílané soubory. Skript je tedy hotov a nezbývá nic jiného, než jej otestovat, případně přidat kontrolní mechanismy vkládaných dat.
Starší komentáře ke článku
Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.
Mohlo by vás také zajímat
Nejnovější
-
Jak rozšířit úložiště Macu za pětinovou cenu?
16. prosince 2024 -
Nové trendy v doménách pro osobní projekty – DIY, LIVING a LIFESTYLE
9. prosince 2024 -
Jak chránit webové stránky před Web/AI Scrapingem
27. listopadu 2024 -
Jaký monitor je nejlepší k novému Macu Mini?
25. listopadu 2024
Aleš Novotný
Říj 16, 2009 v 13:53Zdravím.
Nevím jestli na příspěvky zde někdo reaguje, nicméně za pokus to stojí:
Díky moc za článek i vzorový příklad – povedlo se mi to rozběhnout.
Ale nefunguje čeština v těle mailu – jen š a ž se neposílá správně.
Kde dělám chybu?
Díky Aleš
Freeze
Říj 16, 2009 v 23:38@Aleš Novotný:
Chyba bude zřejmě v kódování. Windows-1250 a latin2 se od sebe liší (z používaných znaků) právě v š, ž.
Teoreticky by mělo stačit přidat korektní hlavičku charset. Ale některé e-mailové klienty neberou win1250 kódování, takže doporučím spíš latin2 nebo to rovnou přepsat do utf-8 ;)
Jinak zřejmě na příspěvky ani nikdo nereaguje. Přecejenom se jedná o články již pár let staré. Já jsem narazil náhodou.
Marek
Úno 10, 2010 v 19:36Hlásilo mi chybu na riadku (volá nedefinovanú funkciu): move_uploaded_fileCopy ($_FILES[‚soubor‘][‚tmp_name‘], „$newFile“);
vyriešil som ju tak ze som riadok zmenil na:
move_uploaded_file ($_FILES[‚soubor‘][‚tmp_name‘], „$newFile“);
tak to funguje :-)
Honza M.
Říj 2, 2011 v 11:33@Freeze:
Také mi nastal problém s kodováním, většinu koduju v utf-8, tedy respektivě vše na stránkách, pokud používám klasický vlastní kod na odesílání mailu bez přílohy, tak je vše OK, tam mám dopsané správné kodování, případně předělání an něj, ale zde v tomto kodu i přes několikahodinové snažení se mi nepodařilo ho upravit tak, aby proměnnou dopis bral v pohodě, tedy aby ji vypsal v mailu správně s diakritikou – tedy ve správném kodování. neporadí mi někdo, co zde změnit? Buď se mi znaky vypisují pomocí symbolů nebo jsou projistotu rovnou vynechané.
petr
Pro 10, 2013 v 0:27Zdravím, mohl by mi někdo prosím poradit jak tento příklad předělat tak, aby odesílal více jak jednu přílohu? Předem děkuji.