Własna klasa do wysyłki e-maili

Autor: Wojciech Kocjan, dodano: 02-07-2009
Kategoria: Programowanie i tworzenie

Maile w php można wysyłać stosunkowo prosto, używając wbudowanej funkcji mail(). Mało kto jednak wie, iż funkcję tą, stosując kilka prostych rozwiązań, można znacznie rozbudować i posłużyć się nią do wysyłania złożonych wiadomości.

W pierwszej części tutorialu zajmiemy się zbudowaniem szkieletu klasy do wysyłki maili, tak aby obsługiwała ona podstawowe nagłówki wiadomości, a także dała możliwość dołączania do maila dowolnej liczby załączników. Zaczynamy od zdefiniowania klasy o nazwie eMail, jak i podstawowych zmiennych w niej używanych:

 

<?php class eMail { var $to; // odbiorca wiadomosci var $subject; // temat wiadomosci var $content; // tresc wiadomosci var $headers; // naglowki wiadomosci var $marker; // znacznik oddzielajacy zalaczniki var $type; // typ e-maila var $xMailer = "Webinside Mail"; // nazwa programu mailowego

 

Zmienne $to, $subject, $content i $headers zawierają podstawowe dane niezbędne do wysłania każdego maila, a więc odbiorcę, temat, treść i nagłówki (informujące np. o kodowaniu znaków) e-maila. Należy się zapewne wyjaśnienie zmiennej $marker - otóż przy wysyłce maila z załącznikami, poszczególne bloki tekstu zawierające każdy z załączników oddzielone są specjalną linią, wyglądającą tak:

 

--___ZNACZNIK==--n

 

Linia ta informuje program pocztowy odbiorcy o tym, iż w tym momencie zaczyna/kończy się załącznik. Jak nie trudno się domyślić owy ZNACZNIK jest w naszym przypadku odpowiednikiem zmiennej $marker, która to zawierać będzie wylosowany (w dalszej części klasy) ciąg tekstu. Zmienna $type określa typ/format e-maila. Na początek wystarczą nam 2 typy: 1 - zwykły mail tekstowy, bez załącznika, 2 - mail w formacie txt, ale zawierający załącznik. Musimy rozróżnić te 2 typy, gdyż wymagają one osobnych nagłówków w mailu. Gdy wysyłamy wiadomość z załącznikami, należy poinformować o tym program pocztowy, dokładając odpowiednie linijki właśnie w nagłówkach e-maila. Pozostaje jeszcze zmienna $xMailer - zawiera ona nazwę naszego 'programu' mailowego, która zawarta będzie w odpowiednim nagłówku wysyłanych wiadomości. Przejdźmy teraz do głównej części klasy, mianowicie funkcji eMail, która zostanie automatycznie wywołana wraz z zainicjonowaniem klasy:

 

function eMail($type = "1", $from = "Webinside.pl <test@webinside.pl>", $replyto = "Webinside.pl <test@webinside.pl>") { $this->type = $type; $this->headers .= "From: " . $from . "n"; $this->headers .= "Reply-to: " . $replyto . "n"; $this->headers .= "X-Mailer: " . $this->xMailer . "n"; $this->headers .= "MIME-Version: 1.0n"; if ($type == 1) { // text/plain $this->headers .= "Content-Type: text/plain; charset=iso-8859-2n"; } else { // text/plain with attachment's srand((double)microtime() * 1000000); $this->marker = md5(uniqid(rand())); $this->headers .= "Content-Type: multipart/mixed;n"; $this->headers .= "tboundary="___" . $this->marker . "=="nn"; $this->content = "--___" . $this->marker . "==n"; $this->content .= "Content-Type: text/plain; charset="iso-8859-2"n"; $this->content .= "Content-Transfer-Encoding: 8bitnn"; } }

 

Wraz z napisaniem kodu $wysylka=new eMail(); zostanie wywołana ta funkcja, gdyż ma taką samą nazwę jak cała klasa. Przyjrzyjmy się zatem bliżej co dokładniej skrypt wykona. Funkcja nie ma żadnego wymaganego argumentu, w przypadku ich braku skrypt domyślnie uzna, że chcemy wysłać wiadomość w formacie txt bez załączników (type=1), o adresie nadawcy "Webinside.pl <test@webinside.pl>" i takim samym adresie zwrotnym (Reply-To). Pierwsza linijka funkcji przypisuje wewnętrznej zmiennej klasy typ wiadomości, następnie definiowane są nagłówki From, Reply-to, X-mailer oraz MIME-Version. Teraz w zależności od typu wiadomości ustawiany jest jedynie nagłówek informujący o kodowaniu e-maila (w przypadku, gdy typ=1), bądź też dodawane są nagłówki informujące o tym że wiadomość zawierać będzie załączniki. W tym drugim przypadku losujemy także znacznik, który będzie służył do rozdzielania poszczególnych części maila ($marker). Zatem po zainicjonowaniu klasy mamy już ustalone główne nagłówki wiadomości, teraz konieczne jest wprowadzenie tematu i treści wiadomości. Napiszemy w tym celu specjalną funkcję, która nazwiemy eMailContent()

 

function eMailContent($subject, $content) { $this->subject = $subject; $this->content .= $content; }

 

Jak widać jest to bardzo prosta funkcja, przypisuje zmiennej subject temat wiadomości, do zmiennej $content z kolei dopisuje treść wiadomości (wcześniej zmienna ta zawierała już nagłówki wiadomości). Pozostaje nam jeszcze napisanie funkcji odpowiedzialnych za dodawanie załączników oraz za samą wysyłkę przygotowanego maila. Zacznijmy od tego pierwszego... Oto funkcja eMailAttachment()

 

function eMailAttachment($mimeType, $fileName, $data) { if ($this->type != 1) { $this->content .= "nn--___" . $this->marker . "==n"; $this->content .= "Content-Type: " . $mimeType . "; name="" . $fileName . ""n"; $this->content .= "Content-Transfer-Encoding: base64n"; $this->content .= "Content-Disposition: attachment; filename="" . $fileName . ""nn"; $this->content .= chunk_split(base64_encode($data)); } }

 

Funkcja ta wywoływana jest z trzema argumentami, kolejno: typem MIME załącznika (w przypadku zwykłego tekstu będzie to text/plain), nazwą załączanego pliku jaki ujrzy odbiorca oraz zawartością tego pliku. Jak działa funkcja? Najpierw sprawdzamy czy typ wiadomości jest różny od 1 (czyli zwykłego maila w .txt, bez załączników), następnie dopisujemy linię ze znacznikiem informującym, że w tym miejscu zaczyna się załącznik. Dalej dopisujemy nagłówek mówiący o typie załącznika, nazwie pliku, kodowania oraz dyspozycji dla programu pocztowego, mówiący iż powinien on potraktować tą część jako załącznik o podanej nazwie. Ostatnia linijka odpowiada za zakodowanie treści załącznika za pomocą algorytmu base64 oraz przekonwertowanie jej zgodnie z RFC 2045 (konieczne do poprawnego wysłania maila, ucina tekst do 76 znaków, dodaje znaczniki r i n na końcu linii). Na koniec pozostaje obsługa samej wysyłki e-maila, zajmie się tym funkcja eMailSend().

 

function eMailSend($to) { if ($this->type != 1) { $this->content .= "--___" . $this->marker . "==--nn"; // close marker } mail ($to, $this->subject, $this->content, $this->headers); } }

 

Wywoływana ona jest z jednym argumentem, mianowicie adresem e-mail odbiorcy maila. Jak łatwo się domyśleć, jest to argument obowiązkowy. Funkcja sprawdza jeszcze czy konieczne jest zamknięcie otwartego znacznika (w przypadku typu różnego od 1) - jest to wymagane do poprawnego wysłania wiadomości. Na koniec korzystamy z podstawowej funkcji mail(), której chyba nie trzeba przedstawiać. Pierwsza wersja naszej klasy, umożliwiająca wysyłanie maili w formacie .txt z dowolną liczbą załączników jest już gotowa. Możemy teraz z niej bardzo prosto korzystać. Przykładowo, jeśli chcemy wysłać zwykłego maila w formacie .txt, robimy to za pomocą kodu:

 

$wysylka = new eMail(); $wysylka->eMailContent("Temat wiadomości testowe", "To tylko test"); $wysylka->eMailSend("Automat Testowy <test@webinside.pl>");

 

Wystarczą trzy linijki kodu, a mamy pewność, że wiadomość zostanie poprawnie wyświetlona na komputerze odbiorcy, będzie ona zawierała nadawcę wiadomości, adres zwrotny, a także nazwę programu użytego do jej wysłania. Nasza klasa napisana została jednak przede wszystkim do wysyłki maili z załącznikami, co stało się teraz bardzo proste:

 

$handle = fopen ("logo.gif", "r"); $logo = fread($handle, filesize("logo.gif")); fclose($handle); $wysylka = new eMail('2'); // zwroc uwage na ustawienie typu 2 $wysylka->eMailContent("Kolejny test", "Zobacz załączniki!"); $wysylka->eMailAttachment("text/plain", "test1.txt", "zawartość testowa"); $wysylka->eMailAttachment("image/gif", "logo.gif", $logo); $wysylka->eMailSend("test@webinside.pl");

 

Kod ten wyśle wiadomość do użytkownika test@webinside.pl, o temacie "Kolejny test", treści "Zobacz załączniki!" oraz dwóch załącznikach: - test1.txt, zawierający jedynie tekst "zawartość testowa"; - logo.gif - zawierające plik graficzny "logo.gif" Możemy w ten sposób dodać dowolną liczbę załączników, o dowolnym typie i zawartości. Bez klasy zajęłoby to nam o wiele więcej niż tylko 6 linijek...

 

Na tym kończymy pierwszą wersję tutorialu, w kolejnej dopiszemy do naszej klasy funkcje odpowiedzialne za wysyłkę maili w formacie html. Gotowa klasa znajduje się pod tym adresem. W razie pytań, bądz problemów z jej funkcjonowaniem prosimy o kontakt na forum.

Ocena 2.63/5 (52.69%) (454 głosów)

Komentarze:

  • mail z załącznikiem
    Dodał: Gość data: 2009-11-12
    Może mi ktoś powiedzie co mam zmienić w tej funkcji abym mógł wysyłać załącznik nie link
    function send_msg() {
    global $list_name, $list_file, $owner_email, $plik, $_FILES;



    $plik_tmp = $_FILES['plik']['tmp_name'];
    $plik_nazwa = $_FILES['plik']['name'];
    $plik_rozmiar = $_FILES['plik']['size'];

    $plik_upload = false;

    if(is_uploaded_file($plik_tmp)) {

    $nazwa_pliku2 = date("YmdHi"). "_". $plik_nazwa;
    $link = "http://marana-tha.pl/fu/". $nazwa_pliku2;

    move_uploaded_file($plik_tmp, $_SERVER["DOCUMENT_ROOT"] . "/fu/". $nazwa_pliku2);

    $plik_upload = true;
    }


    // Sends the message to all subscribers on the list.


    $subject = stripslashes($GLOBALS[subject]);
    $message = stripslashes($GLOBALS[message]);
    $subject = str_replace("%%", "\"", $subject);
    $message = str_replace("%%", "\"", $message);

    $headers = "From: \"$list_name\" <$owner_email>\r\nReply-To: $owner_email\r\nX-Sender: $owner_email\r\nX-UnsubscribeURL: http://$GLOBALS[HTTP_HOST]$GLOBALS[SCRIPT_NAME]\r\nX-Mailer: PHPMailList V$GLOBALS[version] http://php.warpedweb.net/\r\nX-AntiSpam: PHPMailList did not send you this email, review below for sender info.\r\nX-AntiSpam: Sent by $GLOBALS[REMOTE_ADDR]\r\n";

    if ($GLOBALS[SERVER_ADMIN]) $headers .= "X-AntiSpam: Server Administrator $GLOBALS[SERVER_ADMIN]\r\n";

    if ( $plik_upload == true)
    {
    $message .= "\n\nDo wiadomosci dodano zalacznik, kliknij na ponizszy link, aby go pobrac:\n$link ";
    }

    if ($GLOBALS['use_sig'] == "on") $message .= $GLOBALS['sig'];

    $sucess_count = 0;
    $fail_count = 0;

    $addresses = @file($list_file) or die("<center><b>Nie mogę otworzyć pliku z danymi.</b><br>SprawdĽ ¶cieżkę lub prawa dostępu.</center>");
    $addresses[] = $owner_email;




    foreach ($addresses as $email) {
    $email = trim($email);
    if (mail($email, $subject, $message, $headers, $wysylka)) $sucess_count++;
    else $fail_count++;
    }
  • eh
    Dodał: Gość data: 2009-11-12
    nie lepiej skorzystać z klasy w artykule? LOL


Dodaj komentarz:


Temat:
Twój nick:
Komentarz:
 

Prosimy o kulturę wypowiedzi. Komentarze zawierające niecenzuralne zwroty, bądź obrażające inne osoby będą usuwane. Kod HTML w wypowiedziach jest niedozwolony. Wydawca nie odpowiada za treść komentarzy.