Jak v PHP poslat e-mail s přílohou

21. srpna 2001

Vedle uploadu souboru na server se mi v e-mailové schránce objevovaly i dotazy na poslání nějakého souboru e-mailem. Dnešním článkem se pokusím všem, co mi psali, dát odpověď. Uvedu jednoduchý skript, který uživateli umožní vedle zadání e-mailové adresy, také výběr souboru, který bude chtít poslat. Vybraný soubor se zadaným textem zprávy bude odeslán na danou e-mailovou adresu.

Nejprve malé zopakování

Standardní funkcí pro odeslání e-mailu ze skriptu je funkce mail. Její syntaktický zápis vypadá následovně:

bool mail (string to, string subject, string message [, string additional_headers [, string additional_parameters]])

První tři argumenty jsou povinné. Jsou jimi adresa, komu se e-mail posílá (To), druhý představuje název dopisu (Subject) a třetí vlastní tělo dopisu (Message). Další dva parametry jsou již nepovinné. Prvním jsou přídavné hlavičky (např. X-Web, X-Office, X-Mailer, apod.) a posledním parametry. Příklad použití funkce mail je následující:

if (mail (‚jaromir.skrivan@interval.cz‘, ‚Testovací příklad‘, ‚Toto je pokusná zpráva‘)) {
  print „E-mail byl úspěšně odeslán!\n“;
}

Když chceme s e-mailem poslat i přílohu

Pokud chceme poslat i přílohu, pak nám jenom funkce mail nestačí. Nejprve musíme použít funkci imap_mail_compose pro sestavení MIME dopisu. Funkce vypadá následovně:

string imap_mail_compose (array envelope, array body)

Funkce má dva parametry. Prvním z nich jsou hlavičky (Envelope) a druhý parametr je vlastní tělo (Body) specifikující jednotlivé části dopisu. Oba argumenty jsou typu pole.

Formulář

Nejprve uvedu formulář, který bude sloužit uživateli k tomu, aby mohl napsat dopis a připojit k němu jeden soubor.

<FORM ACTION=“send.php“ METHOD=“post“ ENCTYPE=“multipart/form-data“>
Odesílatel: <INPUT TYPE=“text“ NAME=“odesilatel“ VALUE=““ SIZE=50 MAXLENGTH=50><BR>
Příjemce: <INPUT TYPE=“text“ NAME=“prijemce“ VALUE=““ SIZE=50 MAXLENGTH=50><BR>
<BR>
Text:<BR>
<TEXTAREA NAME=“dopis“ COLS=“50″ ROWS=“10″></TEXTAREA><BR>
Soubor: <INPUT TYPE=“file“ NAME=“soubor“> <BR>
<INPUT TYPE=“submit“ NAME=“akce“ VALUE=“Odeslat“><BR>
</FORM>

Uvedený kód zobrazí na stránce následující formulář:

Skript send.php

Uživatel vyplní odesílatele a příjemce, napíše vlastní obsah zprávy a vybere soubor jako přílohu. Po stisku tlačítka Odeslat skript send.php vytvoří pomocí funkce imap_mail_compose MIME dopis, a teprve poté s použitím funkce mail pošleme e-mail i s vybranou přílohou. Skript samozřejmě ošetří i případ, že žádna příloha vybrána nebyla. Následuje celý kód skriptu send.php, bližší popis uvedu formou komentářů přímo ve skriptu.

<HTML>
<HEAD>
<TITLE>Mail s prilohou</TITLE>
</HEAD>
<BODY>
<?
if ($akce == „Odeslat“) { /* Bylo stisknuto tlacitko Odeslat */
  if ($soubor_name == „“) { /* nebyla vybrana priloha, posleme e-mail obycejne */
    if (mail („$prijemce“, ‚Zpráva z webu‘, „$dopis“, „From: $odesilatel“)) {
      print „<h3>E-mail byl úspěšně odeslán!</h3>“;
    }
    else {
      print „<h3>E-mail se nepodařilo odeslat!</h3>“;
    }
  }
  else { /* priloha byla vybrana */
    /* nejprve sestrojime hlavicky */

    $envelope[„from“] = „$odesilatel“;
    $envelope[„to“] = „$prijemce“;

    /* nyni sestrojime nekolik casti dopisu */
    /* 1. cast – uvodni, tou rekneme, ze dopis ma vice casti s ruznymi typy dat */

    $part1[„type“] = TYPEMULTIPART;
    $part1[„subtype“] = „mixed“;

    /* 2. cast – do dopisu pripojime prilohu */
    /* nejprve zadany soubor nacteme */

    Copy($soubor, $soubor_name); /* uploadnuty soubor zkopirujeme z docasneho adresare */

    $f = fopen ($soubor_name, „r“); /* otevren pro cteni */
    $obsah = fread ($f, filesize($soubor_name)); /* nacteme obsah do promenne */
    fclose ($f);

    $part2[„type“] = TYPEAPPLICATION;
    $part2[„encoding“] = ENCBINARY;
    $part2[„subtype“] = „octet-stream“;
    $part2[„description“] = basename($soubor_name);
    $part2[„contents.data“] = „$obsah“;

    /* 3. cast – do dopisu vlozime zadany text */
    $part3[„type“] = TYPETEXT;
    $part3[„subtype“] = „plain“;
    $part3[„description“] = „text“;
    $part3[„contents.data“] = $dopis;

    /* Cely dopis ulozime do pole body */
    $body[1] = $part1;
    $body[2] = $part2;
    $body[3] = $part3;

    /* celou zpravu vytvorime a ulozime do promenne $zprava: */
    $zprava = imap_mail_compose ($envelope, $body);

    /* drive nez posleme zpravu funkci Mail musime rozdelit
       zvlast hlavicku a zvlast telo: */

    $pom = StrPos($zprava, „\r\n\r\n“);
    $hlavicka = SubStr($zprava, 0, $pom+2);
    $telo = SubStr($zprava, $pom, StrLen($zprava) – $pom);

    if (mail („$prijemce“, ‚Zpráva z webu‘, $telo, $hlavicka)) {
       print „<h3>E-mail byl úspěšně odeslán!</h3>“;
    }
    else {
       print „<h3>E-mail se nepodařilo odeslat!</h3>“;
    }
  }
}
?>
<HR SIZE=1 NOSHADE>
<FORM ACTION=“send.php“ METHOD=“post“ ENCTYPE=“multipart/form-data“>
Odesílatel: <INPUT TYPE=“text“ NAME=“odesilatel“ VALUE=““ SIZE=50 MAXLENGTH=50><BR>
Příjemce: <INPUT TYPE=“text“ NAME=“prijemce“ VALUE=““ SIZE=50 MAXLENGTH=50><BR><BR>
Text:<BR>
<TEXTAREA NAME=“dopis“ COLS=“50″ ROWS=“10″></TEXTAREA><BR>
Soubor: <INPUT TYPE=“file“ NAME=“soubor“> <BR>
<INPUT TYPE=“submit“ NAME=“akce“ VALUE=“Odeslat“><BR>
</FORM>
</BODY>
</HTML>

Spuštění skriptu

Tento skript jsem zprovoznil a otestoval na IIS 5.0 a PHP 4.0.6. Ke stažení je k  dispozici zde. Pokud se vám stane, že vám skript nebude fungovat (bude se vypisovat hláška, že nezná funkci imap_mail_compose), zkontrolujte si nejprve nastavení v souboru php.ini:

  • zdali máte nastaveny správně direktivy SMTP a sendmail_from v bloku „mail function“. (důležité pro funkci Mail)
  • dále si zkontrolujte a případně nastavte direktivu file_uploads=On
  • v bloku „Paths and Directories“ nastavte direktivu extension_dir na adresář, ve kterém máte rozšiřující DLL knihovny, zpravidla extension_dir=“C:\PHP\extensions“ – kdyby jste pochybovali o jaký adresář jde, je to ten, v němž se vyskytuje soubor php_imap.dll – to je právě knihovna, bez níž vám nebude fungovat funkce imap_mail_compose.
  • ve stejném bloku nastavte (pokud již tak není) direktivu enable_dl=On
  • nakonec najděte odstavec Windows extensions a odkomentujte řádek s textem extension=php_imap.dll (tj. odstraňte středník ze začátku řádku)

Po splnění všech kroků by vám měla ve skriptu fungovat funkce imap_mail_compose. Příloha se pošle jako binární bez ohledu na to, jestli je poslán text, nebo obrázek. Skript se dá samozřejmě rozšířit – podle MIME typu přiloženého souboru (zjistili byste v proměnné $soubor_type) byste mohli rovnou nastavit správný MIME typ přílohy. Toto je nejjednodušší skript, který posílá jen jednu přílohu. Pokud byste chtěli poslat příloh více, pak je řadíte za sebou do pole $body.

Upozorňuji, že ve skriptu není ošetřen uživatelský vstup a tedy dříve, než data ve skriptu zpracujete do e-mailové zprávy, je potřeba vstupní data zkontrolovat, zdali neobsahují nevhodná či nebezpečná data.

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ší

4 komentářů

  1. eliska

    Říj 17, 2010 v 18:39

    mohl bys te skontrolovat email jestli by sel ?

    Odpovědět
  2. MaSo

    Čvn 5, 2011 v 20:34

    Hmm, tento popis je orientován na Windows, PHP však většinou běží na unix systémech, např. Linux… Jak tedy tam s imap_mail_compose?

    Odpovědět
  3. radek david

    Pro 3, 2011 v 21:43

    ahoj jsem radek rad bych vas lepe poznal chodim na lide nebo fc pod adresou radekhunka75@seznam.cz pokud mate zajem tak se ozvete dekuji

    Odpovědět
  4. sasa

    Dub 10, 2012 v 20:14

    Byť je v povědomí velké části čtenářů komiks fenoménem až od 20. století, dají se předchůdci komiksu, které odpovídají jeho dnešnímu chápání, najít už v umění starověkého Egypta. Byly nalezeny nástěnné malby, pocházející ze 2. tisíciletí př. n. l., zaznamenávající pásem obrázků a textů proběhlé děje. Kresby podobného typu jsou známy i z předkolumbovské Ameriky.

    Už od raně křesťanských dob se objevují iluminované rukopisy, jejichž charakter má ke komiksu velmi blízko. Výrazné ilustrace měly již Koptské a Irské rukopisy, velké bohatství iluminací se objevuje po přelomu tisíciletí. Významným středověkým komiksem je krumlovská Liber depictus, kde je text doprovodem obrazu, nikoli naopak jako v jiných manuskriptech. Čitelné originální řazení do panelů je vidět na tzv. Pařížském zlomku Dalimilovy kroniky, jinak je obvyklé řadit panely na šířku řádků pod sebe.

    Za svého druhu komiks lze považovat například i tapisérii z Bayeux – rozsáhlé dílo vykreslující metodou kontinuální ilustrace (známou z Trajánova sloupu či egyptských a mezopotamských záznamů) příběh dobytí Británie Normany roku 1066. Tapisérie obsahuje kromě obrazu také doplňující texty, které byly i v knižní produkci obvyklé a často na sebe braly podobu tzv. mluvících pásek, svitků s přímou řečí vycházejících z hovořících postav.

    Masové rozšíření kreslených seriálů bylo umožněno až vynálezem knihtisku. Už v roce 1460 vychází kreslené Utrpení svatého Erasma[zdroj?]. Ve své době bylo velmi oblíbené. Možná i proto, že brutalitou si nezadalo s dnešní undergroundovou produkcí.
    obraz ze série Dráha prostitutky

    Dalším mezníkem byly příběhy William Hogartha, jehož série obrazů Dráha prostitutky (1731) a Dráha zhýralce, později přepracované na série rytin, patřily k nejpopulárnějším tiskům své doby. Ochrana práv autora byla popudem k vývoji copyrightu.
    Yellow Kid, titulní postava prvního moderního komiksu

    O spojení sekvencí obrazů a písma, a vytvoření základu moderního komiksu se zasloužil Rodolphe Töpffer. Vydával přibližně v polovině 19. století řadu kreslených satirických příběhů. Své dílo bral ale jen jako zábavu a rozptýlení, nikoliv jako převratný vynález.

    První moderní komiks však stvořil až v roce 1896 Richard Outcault, když publikoval v časopise New York World svůj strip Yellow Kid (Žluté dítě). Datum 16.2.1896 se také počítá jako „Den zrození komiksu“.

    Odpovědět

Napsat komentář: MaSo Zrušit odpověď na komentář

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