E-mailový klient pre webmail v PHP – základná štruktúra

27. února 2004

V tejto trojdielnej sérii článkov si vytvoríme e-mailového klienta (webmail). Náš e-mailový klient bude schopný všetkých úkonov, ktoré sa s poštou bežne robia. Jeho konfigurácia bude úplne jednoduchá a preto ho budete môcť hneď po stiahnutí a jednoduchom nakonfigurovaní začať používať.

V tomto seriály bude klient pevne nakonfigurovaný na jeden účet, pripravil som ho ale takým spôsobom, aby sa dal prerobiť pre viacerých užívateľov s prihlasovacím systémom. Vzhľad je ľahko zmeniteľný a preto je v tejto aplikácií robený provizórne, keďže predpokladám, že asi každý si ho rád upraví tak, ako chce.

Webmail je kompletne robený prostredníctvom funkcií, ktoré si tu ukážeme. S funkciami budem pridávať aj jednotlivé stránky, ktoré k nim patria. Aplikácia pracuje s databázou MySQL.

V tomto článku si ukážeme nasledovné súbory:

  • index.php – hlavná stránka, obsahuje prijaté správy
  • functions.php – v tomto súbore sú všetky funkcie
  • new.php – stránka pre napísanie novej správy
  • reply.php – stránka pre odpísanie na došlú správu
  • forward.php – stránka pre preposlanie došlej správy
  • style.css – kaskádové štýly pre jednoduchý grafický vzhľad

MySQL databáza:

# MySQL databáza – Webmail
# tabuľka účty
create table accounts
(
  id int not null auto_increment primary key, # id číslo záznamu
  userid int not null, # id užívateľa
  name varchar(150) not null, # meno ktoré sa zobrazí príjemcovi správy
  address varchar(150) not null, # e-mailová adresa
  user varchar(100), # login pre prístup ku schránke
  pass varchar(100), # heslo pre prístup ku schránke
  servername varchar(100), # názov servera
  port varchar(10), # port
  type varchar(10) # typ
);
# tabuľka odoslaná pošta
create table sent
(
  id int not null auto_increment primary key, # id záznamu
  userid int not null, # id užívateľa
  to_address varchar(150), # príjemca
  subject varchar(150), # predmet
  message text, # text správy
  date int # dátum a čas
);
# tabuľka adresár
create table address
(
  id int not null auto_increment primary key, # id záznamu
  userid int not null, # id užívateľa
  name varchar(150), # meno
  mail varchar(150) # e-mailová adresa
);

Do výpisu som nepridal tabuľku užívatelia, keďže tu nieje prihlasovací systém. Táto tabuľka pri jednom užívateľovi navyše ani nieje nevyhnutne potrebná. Tabuľka accounts uchováva informácie potrebné pre spojenie so serverom a teda je nevyhnutná i pre príjem správ. Zároveň v tejto tabuľke nechýba ani meno a adresa, ktoré sa zobrazia príjemcovi správy, ktorá je z tohoto webmailu odosielaná. Ďalšou tabuľkou je sent, ktorá zaznamenáva odoslané správy. Takto máte vo webmaile aj archív všetkých správ, ktoré z neho boli odosielané. Poslednou tabuľkou je address, ktorá slúži ako adresár pri posielaní správ. Záznamy sú pre jednotlivých užívateľov rozlišované na základe userid, ktoré je samozrejme pre každého užívateľa jedinečné.

Výpis nových správ (index.php)

Na hlavnej stránke (index.php) sa zobrazia došlé správy. Samotné súbory su veľmi jednoduché:

<?php
  session_start();
  require „./functions.php“;
  html_header();
  list_of_messages();
  html_footer();
?>

Hneď na začiatku každého súboru si vkladáme stránku s funkciami. Potom zavoláme funkciu html_header();, ktorá nám vytvára vrch stránky. Táto funkcia je bližšie rozpísaná pod týmto textom. Hneď po tejto funkcii zavoláme funkciu, ktorá hrá v danom súbore vždy hlavnú rolu. V tomto je to list_of_messages();, ktorá nám zobrazí všetky došlé správy. Na konci súboru je to html_footer();, ktorá nám tento koniec aj vytvára (viď nižšie).

Funkcia html_header(); vyzerá nasledovne:

function html_header()
{
  ?>
  <!DOCTYPE HTML PUBLIC „-//W3C//DTD HTML 4.01 Transitional//EN“>
  <html>
  <head>
  <title>Webmail</title>
  <meta http-equiv=“Content-Type“ content=“text/html; charset=windows-1250″ />
  <link rel=“stylesheet“ href=“style.css“ type=“text/css“ />
  </head>
  <body bgcolor=“#FFFFFF“ text=“#000000″>
  <div class=“middle“>
    <a href=“new.php“>Nová správa</a>   &middot;
    <a href=“index.php“>Došlé správy</a> &middot;
    <a href=“sent.php“>Odoslané správy</a> &middot;
    <a href=“select_address.php“>Nová správa – výber adries</a>   &middot;
    <a href=“insert_address.php“>Adresár</a>   &middot;
    <a href=“delete_address.php“>Vymazať kontakt</a>
  </div>
  <?php
}

Funkcia html_header(); vytvára aj jednoduché menu. Po upravení tejto funkcie si môžete jednoducho zmeniť vzhľad. Funkcia obsahuje kompletné HTML hlavičky vrátane vloženia súboru style.css, ktorý obsahuje kaskádové štýly. Menu obsahuje nasledujúce položky:

  • Nová správa – zobrazí formulár pre napísanie novej správy
  • Došlé správy – kliknutím na tento odkaz sa dostaneme na hlavnú stránku, kde je zoznam došlých správ
  • Nový správa – výber adries – umožňuje vybrať i viacerých adresátov pre novú správu
  • Adresár – vstúpime do adresára
  • Vymazať kontakt – vymažeme kontakt z adresára

Funkcia, ktorá vytvára koniec stránky, sa volá html_footer();, je najjednoduchšia z celej aplikácie:

function html_footer()
{
  ?>
  </body>
  </html>
  <?php
}

Nasleduje spomínaná funkcia list_of_messages();. Vytvára zoznam došlých správ, tak isto ako v iných webmailoch:

function list_of_messages()
{
  global $userid;
  $imap = open();
  if(!$imap) return false;
  $sorted = imap_sort($imap, SORTARRIVAL, 1); // zoradíme správy
  $headers = imap_headers($imap);
  $count = count($headers);
  echo „<div class=’middle‘>Počet správ: „.$count.“</div><br />“;
  if($count>0):
    ?>
    <form action=“delete.php“ method=“post“>
    <table cellpadding=“4″ cellspacing=“0″ border=“0″ width=“725″>
    <tr>
      <td></td>
      <td></td>
      <td width=“250″><div class=“middle“ align=“left“>Odosielateľ</div></td>
      <td width=“175″><div class=“middle“ align=“left“>Predmet</div></td>
      <td width=“150″><div class=“middle“ align=“left“>Dátum</div></td>
      <td width=“25″><div class=“middle“ align=“left“>Re</div></td>
      <td width=“25″><div class=“middle“ align=“left“>Fw</div></td>
      <td width=“50″><div class=“middle“ align=“left“>Kontakty</div></td>
      </tr>
      <?php
      for($i=0;$i<$count;$i++)
      {
        $id = $sorted[$i];
        $header = imap_header($imap, $id);
        $from = $header->from[0];
        $adresa = $from->mailbox.“@“.$from->host;
        $message[‚udate‘] = $header->udate;
        $message[‚size‘] = $header->size;
        $subject = imap_mime_header_decode($header->Subject);
        $subject = $subject[0]->text;
        $from = imap_mime_header_decode($header->fromaddress);
        $from = $from[0]->text;
        // zistíme, či mail obsahuje aj prílohy
        $structure = imap_fetchstructure($imap, $id);
        $parts = $structure->parts;
        $num_parts = sizeof($parts);
        if($num_parts>0) $attachment = 1; // príloha existuje
        else $attachment = 0; // príloha neexistuje
        if(($i%2)==1) echo „<tr bgcolor=’DDDDDD‘>“;
        else echo „<tr bgcolor=’AAAAAA‘>“;
        echo „<td><input type=’checkbox‘ name=’id[]‘ value=’$id‘ /></td>“;
        echo $attachment == 1 ? „<td><a title=’príloha‘><img src=’images/attachment.gif‘ /></a></td>“ : „<td></td>“; // ak je príloha, zobrazíme ikonu
        echo „<td><div align=’left‘ class=’middle‘><a href=’read.php?id=“.$id.“‚ title=’$adresa‘>“.$from.“</a></div></td>“;
        echo „<td><div align=’left‘ class=’middle‘><a href=’read.php?id=“.$id.“‚>“.$subject.“</a></div></td>“;
        echo „<td><div align=’left‘ class=’middle‘><a href=’read.php?id=“.$id.“‚>“.date(„j.n.Y H:i“,$message[‚udate‘]).“</a></div></td>“;
        echo „<td><div align=’left‘ class=’middle‘><a href=’reply.php?id=“.$id.“‚ title=’odpovedať‘>Re</a></div></td>“;
        echo „<td><div align=’left‘ class=’middle‘><a href=’forward.php?id=“.$id.“‚ title=’preposlať‘>Fw</a></div></td>“;
        echo „<td><div align=’left‘ class=’middle‘><a href=’insert_address.php?mail=“.$adresa.“‚>pridať</a></div></td>“;
        echo „</tr>“;
      }
      ?>
      </table>
      <br />
      <button type=“submit“ class=“button“>Vymazať</button>
      </form>
      <?php
    endif;
}

Tu už nájdete prvé IMAP funkcie:

  • array imap_sort(int spojenie, int kritériá, int zostupne, int možnosti); – vracia zoznam zoradených správ
  • array imap_headers(int spojenie); – vracia hlavičky všetkých správ v e-mailovej schránke
  • object imap_header(int spojenie, int číslo_správy, int dĺžka_from, int dĺžka_subject, string defaultná_doména); – prečíta hlavičku správy
  • array imap_mime_header_decode(string text); – dekóduje prvky MIME hlavičky
  • object imap_fetchstructure(int spojenie, int číslo_správy, int možnosti); – zistí štruktúru správy

Vo funkcii najprv vytvoríme spojenie s IMAP serverom a id spojenia uložíme do premennej $imap. V prípade, že je spojenie neúspešné, funkciu okamžite ukončíme príkazom return. Následne správy zoradíme a vyberieme hlavičky správ. Prostredníctvom funkcie count() spočítame počet správ v schránke. Hlavičky správ zobrazíme v tabuľke. V základnej podobe sa zobrazí odosielateľ, predmet, dátum, možnosť odpísať, možnosť preposlať a možnosť vložiť do kontaktov. Výpis správ sa uskutočňuje vo formulári, ktorý umožňuje správy hromadne vymazať. Pri každej správe je zaškrtávacie políčko checkbox, ktorého názvom name je id[]. Hodnotou value každého políčka je id správy. Hranaté zátvorky v názve vytvoria v PHP pole správ, ktoré chceme spracovať (v tomto prípade vymazať).

Písanie nových správ (new.php)

Ďalším súborom je new.php, ktorý slúži pre písanie nových správ:

<?php
  session_start();
  require „./functions.php“;
  html_header();
  show_form();
  html_footer();
?>

Ako som už spomínal, všetky súbory sú veľmi podobné, mení sa v nich len jedna funkcia. V tomto je to show_form();. Táto funkcia zobrazí formulár pre napísanie novej správy:

function show_form($to = „“, $subject = „“, $message = „“)
{
  global $userid;
  ?>
  <table cellpadding=“0″ cellspacing=“0″ border=“0″>
  <form action=“send.php“ method=“post“ enctype=“multipart/form-data“>
  <tr><td width=“100″><div align=“left“ class=“middle“>Komu:</div></td><td align=“left“><input type=“text“ name=“to“ value=“<?php echo $to?>“ class=“textinput“ />
  <select name=“to2″ class=“select“>
    <option value=“false“>–vyber–</option>
    <?php
    db_connect();
    $query = „select * from address where userid = ‚$userid'“;
    $result = mysql_query($query);
    $num_result = mysql_num_rows($result);
    if($num_result>0):
      for($i=0;$i<$num_result;$i++):
        $name = mysql_result($result,$i,“name“);
        $address = mysql_result($result,$i,“mail“);
        echo „<option value=’$address‘>$name &lt;“.$address.“&gt;</option>“;
      endfor;
    endif;
    ?>
  </select>
  </td></tr>
  <tr><td><div align=“left“ class=“middle“>Predmet:</div></td><td align=“left“><input type=“text“ name=“subject“ value=“<?php echo $subject?>“ class=“textinput“ /></td></tr>
  <tr><td height=“10″></td></tr>
  <tr><td><div align=“left“ class=“middle“>1. príloha:</div></td><td align=“left“><input type=“file“ name=“priloha1″ class=“textinput“ /></td></tr>
  <tr><td><div align=“left“ class=“middle“>2. príloha:</div></td><td align=“left“><input type=“file“ name=“priloha2″ class=“textinput“ /></td></tr>
  <tr><td><div align=“left“ class=“middle“>3. príloha:</div></td><td align=“left“><input type=“file“ name=“priloha3″ class=“textinput“ /></td></tr>
  <tr><td colspan=“3″>
  <textarea name=“message“ class=“textarea“ rows=“13″ cols=“71″>
    <?php
    echo $message;
    ?>
  </textarea><br />
  <center><button type=“submit“ class=“button“>Odoslať</button></center>
  </td></tr>
  </form>
  </table>
  <?php
}

Formulár pre napísanie správy umožňuje okrem priameho napísania správy vybrať adresáta aj zo zoznamu (tabuľka address). V tejto jednoduchej časti skriptu, kde sa to celé odohráva, sa najprv pripojíme k databáze pomocou funkcie db_connect() a napíšeme query príkaz, ktorý uložíme do premennej $query. Následnej príkaz prevedieme pomocou MySQL funkcie mysql_query. Počet záznamov, ktorý sme našli (počet adries, ktoré má prihlásený užívateľ vložených), uložíme do premennej $num_result pomocou funkcie mysql_num_rows(). V prípade, že má užívateľ vloženú aspoň jednu adresu, vyberieme v cykle for všetky potrebné informácie a adresu zobrazíme ako <option> v HTML prvku <select>. Funkcia nám umožňuje vložiť tri súbory ako prílohu k mailovej správe. Túto funkciu využijeme aj pri preposielaní a odpisovaní na správu, preto sa v jednotlivých formulárových prvkoch, ako napríklad input typu text, nachádza malá časť PHP kódu pre vypísanie premennej. V prípade, že chceme napísať novú správu, sú tieto políčka samozrejme prázdne.

Odpovedanie na správy (reply.php)

Ďaľším súborom je reply.php:

<?php
  session_start();
  require „./functions.php“;
  html_header();
  $message = reply($_GET[‚id‘]);
  show_form($message[‚fromaddress‘], $message[‚subject‘], $message[‚body‘]);
  html_footer();
?>

V tomto súbore nájdete až dve hlavné funkcie. Prvá reply(); získa informácie zo správy s daným $_GET[‚id‘] a uloží ich do premennej typu pole $message. Toto pole sa potom odovzdá už zobrazenej funkcii show_form();. Tejto funkcii predáva adresu, na ktorú chceme odpísať, predmet a text samotnej správy.

function reply($id)
{
  $imap = open();
  $header = imap_header($imap, $id);
  $message[‚body‘] = „\n\n>“.quoting(imap_fetchbody($imap,$id,1));
  $from = $header->from[0];
  $adresa = $from->mailbox.“@“.$from->host;
  $subject = imap_mime_header_decode($header->Subject);
  $subject = $subject[0]->text;
  $message[‚fromaddress‘] = $adresa;
  $message[‚subject‘] = „Re: „.$subject;
  return $message;
}

Funkcia reply() vyberie dôležité údaje ako text správy, adresu a predmet na základe id správy. Tieto informácie vráti v podobe pola vo funkcii $message. Tu môžete vidieť ďalšiu IMAP funkciu – string imap_fetchbody(int spojenie, int číslo_správy, string časť, int možnosti); (prečítanie jednej časti tela správy).

Preposielanie správ (forward.php)

Ďalší je súbor forward.php a jeho funkcia forward();:

<?php
  require „./functions.php“;
  html_header();
  $message = forward($_GET[‚id‘]);
  show_form(“, $message[‚subject‘], $message[‚body‘]);
  html_footer();
?>
function forward($id)
{
  $imap = open();
  $header = imap_header($imap, $id);
  $subject = imap_mime_header_decode($header->Subject);
  $subject = $subject[0]->text;
  $message[‚body‘] = „\n\n>“.quoting(imap_fetchbody($imap,$id,1));
  $message[‚subject‘] = „Fwd: „.$subject;
  return $message;
}

Funkcia forward() umožňuje preposlať správu. Funguje na podobnom princípe ako funkcia reply().

Spoločné funkcie

Ešte pred koncom si ukážeme funkcie db_connect();, open(); a quoting();, ktoré ste si mohli všimnúť v predchádzajúcich funkciách.

function db_connect()
{
  $result = mysql_connect(„localhost“); // pripojíme sa
  if(!$result)
    return false;
  if(!mysql_select_db(„databaza“)) // vyberieme databázu
    return false;
  return $result;
}
function open()
{
  global $userid;
  db_connect();
  $query = „select * from accounts where userid = ‚$userid'“;
  $result = mysql_query($query);
  $num_result = mysql_num_rows($result);
  if($num_result>0):
    $user = mysql_result($result,0,“user“);
    $password = mysql_result($result,0,“pass“);
    $servername = mysql_result($result,0,“servername“);
    $port = mysql_result($result,0,“port“);
    $type = mysql_result($result,0,“type“);
    $mailbox = „{„.$servername.“/“.$type.“:“.$port.“}INBOX“;
    $open = imap_open($mailbox,$user,$password);
    return $open;
  else:
    echo „<div class=’warning‘ align=’center‘>Nepodarilo sa pripojiť.</div>“;
    return;
  endif;
}
function quoting($text)
{
  return str_replace(„\n“, „\n> „, $text);
}

Funkciou db_connect() vytvoríme spojenie s databázou. V tejto funkcii sa nastavujú aj údaje pre spojenie s databázou (adresa, login, heslo, názov databáze).

Funkcia open() vytvorí spojenie s IMAP serverom. Údaje čerpá na základe užívateľského id $userid z tabuľky accounts. V tejto funkcií sa vyskytuje ďalšia IMAP funkcia – int imap_open(string schránka, string užívateľ, string heslo, int možnosti); (otvorí spojenie so serverom).

Poslednou funkciou v tomto článku je funkcia quoting(), ktorá upraví text pre preposielanie alebo odpísanie na správu.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Štítky: Články

Mohlo by vás také zajímat

Nejnovější

4 komentářů

  1. masterpawn

    Srp 17, 2009 v 0:53

    muze mi nekdo poradit? delam vse tak jak tu je ale nemuzu se pripojit co mam napsat do mysql_connect

    Odpovědět
  2. Čvn 7, 2010 v 17:14

    PhP se mi zobrazilo jako pouhý text..

    Odpovědět
  3. Skillercs

    Lis 14, 2010 v 21:34

    Kdyz se na to pozorni podivate tak to tak či tak neni cele tak proč se tim vubec zabyvate.

    Mozna mi to uniklo ale scripty :
    sent.phpselect_address.php
    insert_address.php
    delete_address.php

    Nejaky chybi ?? :-D
    Doplnit to neni problem ze ale pokud tohle ma pomoct nekomu kdo to moc neovlada tak je to knicemu ..

    Dyt to s email klientem nema vubec nic spolecneho .-D … ale vklidu ze :-D

    Odpovědět
  4. Miroslav Kucera

    Lis 15, 2010 v 8:22

    Skillercs: kdyz budete ale pozorny i vy, mozna si na zacatku povsimnete vety: „V tejto trojdielnej sérii článkov…“ :-)

    Dalsi clanky jsou:

    http://interval.cz/clanky/e-mailovy-klient-pre-webmail-v-php-adresar-a-doplnkove-funkcie/

    http://interval.cz/clanky/e-mailovy-klient-pre-webmail-v-php-odosielanie-citanie-a-stahovanie/

    Odpovědět

Napsat komentář

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