E-maile w PHP
Obecnie funkcja wysyłania e-maili jest używana praktycznie w większości większych serwisów opartych na systemie dynamicznego generowania stron. W tym artykule opiszemy w jaki sposób posługiwać się funkcją mail() standardowo dostępną w PHP jak i bardziej zaawansowanym systemem - mianowicie gniazdkami.
Wysyłanie e-maili z poziomu PHP jest niesamowicie proste. Wystarczy bowiem użyć wbudowanej funkcji mail(), która upraszcza całą sprawę. Oto sposób jej użycia:
Oznaczenie parametrów:
Przykładowe użycie funkcji mail() wygląda tak:
Jest to najprostsze z możliwych wywołań tej funkcji. Spowoduje wysłanie e-maila o treści 'Treść' z tematem 'Temat' pod adres 'mail@serwer.com'.
Co do nagłówków: aby dokładnie zrozumieć zasadę dodawnia nagłówków należy zapoznać się ze specyfikacją
wysyłania e-maili np. tutaj: http://www.faqs.org/rfcs/rfc1896.
Przykładowo: możesz dodać nagłówek 'From', który oznacza nadawce listu.
W powyższej instrukcji do e-maila zostaną dołączone nagłówki 'From' oraz 'Reply-To' (adres zwrotny). Nie zaszkodzi
także ustawić nagłówka 'Return-Path' czyli adresu na który zostanie odesłany list w razie, gdy np. skrzynka
odbiorcy nie istnieje. Uwaga! Poszczególne nagłówki e-maili muszą być oddzielone od siebie znakami \r\n
aczkolwiek na systemach typu Unix może działać także, gdy nagłówki będą oddzielone znakiem \n.
Na wielu serwerach funkcja mail() jest blokowana przez administratorów. Z różnych względów - np. ze względu na obciązania serwera, w przypadku wysyłania dużej ilości listów lub możliwość rozsyłania spamu. Dobrym
sposobem jest wykorzystanie gniazdek w celu przesłania listu. Chociaż jest to metoda bardziej czasochłonna, ale
pozwala na połączenie się z dowolnym serwerem i wysłanie z tego serwera listu. W artykule przedstawimy prostą klasę, która umożliwi połączenie się z serwerem i wysłania e-maila.
Aby wysłać e-maila z konkretnego serwera należy się z nim połączyć (najczęściej na porcie 25) oraz przekazać mu zrozumiałe dla niego komendy - np.
Dla przykładu powyższe instrukcje umożliwią wysłanie listu do odbiorca@sewer.pl.
Ale przejdźmy do rzeczy: połączenie z serwerem może odbyć się za pomocą funkcji fsockopen().
Pierwszym parametrem tej funkcji musi być nazwa hosta; drugim port. Trzeci i czwarty parametr to opis błędu oraz numer błędu. Ostatni parametr to TimeOut (ilość sekund przez jakie skrypt bedzie próbował połączyć
się z serwerem).
Wysyłanie komendy odybwa się za pośrednictwem funkcji fwrite():
Pierwszym parametrem musi być uchwyt do gniazdka (uzyskany jako rezultat działania funkcji fsockopen()). Drugi parametr to treść wysyłanej komendy.
Równie prosto można odczytać tekst, który został zwrócony przez serwer (funkcja fgets()).
Pierwszym parametrem musi być oczywiście uchwyt, a drugim ilość znaków jakie zostaną odczytane. Funkcja fgets() zwraca łańcuch (string), który zawiera treść zwróconą przez serwer. To chyba wszystko co trzeba wiedzieć na temat łączenia się z serwerem i wysyłaniem do niego komend. Nie należy oczywiście zapominać o tym, aby na końcu zamknąć połączenie (funkcja fclose()).
Na podstawie tego, co napisaliśmy można napisać klasę, która uprości cały proces przesyłania wiadomości. Kod źródłowy całego skryptu przedstawia się następująco:
Na samym końcu następuje skorzystanie z tej klasy oraz z serwera mail.pf.pl do wysłania listu. Na końcu powinien zostać wyświetlony log z działania klasy (log sporządzony na podstawie komunikatów zwracanych przez serwer).
Funkcja mail()
Wysyłanie e-maili z poziomu PHP jest niesamowicie proste. Wystarczy bowiem użyć wbudowanej funkcji mail(), która upraszcza całą sprawę. Oto sposób jej użycia:
bool mail ( string to, string subject, string message [, string additional_headers
[, string additional_parameters]])
[, string additional_parameters]])
Oznaczenie parametrów:
- to - adres e-mail odbiorcy e-maila
- subject - temat wiadomości
- message - treść wiadomości
- additional_headers - dodatkowe nagłówki (parametr opcjonalny)
- additional_parameters - dodatkowe parametry przekazywane do SendMaila (parametr opcjonalny)
Przykładowe użycie funkcji mail() wygląda tak:
Jest to najprostsze z możliwych wywołań tej funkcji. Spowoduje wysłanie e-maila o treści 'Treść' z tematem 'Temat' pod adres 'mail@serwer.com'.
Co do nagłówków: aby dokładnie zrozumieć zasadę dodawnia nagłówków należy zapoznać się ze specyfikacją
wysyłania e-maili np. tutaj: http://www.faqs.org/rfcs/rfc1896.
Przykładowo: możesz dodać nagłówek 'From', który oznacza nadawce listu.
mail('mail@serwer.com', 'Temat', 'Treść',
'From: Adam Boduch <adam@boduch.net>\r\n
Reply-To: Adam Boduch <adam@boduch.net>\r\n');
'From: Adam Boduch <adam@boduch.net>\r\n
Reply-To: Adam Boduch <adam@boduch.net>\r\n');
W powyższej instrukcji do e-maila zostaną dołączone nagłówki 'From' oraz 'Reply-To' (adres zwrotny). Nie zaszkodzi
także ustawić nagłówka 'Return-Path' czyli adresu na który zostanie odesłany list w razie, gdy np. skrzynka
odbiorcy nie istnieje. Uwaga! Poszczególne nagłówki e-maili muszą być oddzielone od siebie znakami \r\n
aczkolwiek na systemach typu Unix może działać także, gdy nagłówki będą oddzielone znakiem \n.
Używanie gniazdek
Na wielu serwerach funkcja mail() jest blokowana przez administratorów. Z różnych względów - np. ze względu na obciązania serwera, w przypadku wysyłania dużej ilości listów lub możliwość rozsyłania spamu. Dobrym
sposobem jest wykorzystanie gniazdek w celu przesłania listu. Chociaż jest to metoda bardziej czasochłonna, ale
pozwala na połączenie się z dowolnym serwerem i wysłanie z tego serwera listu. W artykule przedstawimy prostą klasę, która umożliwi połączenie się z serwerem i wysłania e-maila.
Aby wysłać e-maila z konkretnego serwera należy się z nim połączyć (najczęściej na porcie 25) oraz przekazać mu zrozumiałe dla niego komendy - np.
HELO mail.swerer.pl\r\n
MAIL FROM: <adres@serwer.pl>\r\n
RCPT TO: <odbiorca@serwer.pl>\r\n
DATA\r\n
Subject: Temat\r\n
From: Adam Boduchrn\r\n
Wiadomość\r\n
.\r\n
QUIT\r\n
MAIL FROM: <adres@serwer.pl>\r\n
RCPT TO: <odbiorca@serwer.pl>\r\n
DATA\r\n
Subject: Temat\r\n
From: Adam Boduchrn\r\n
Wiadomość\r\n
.\r\n
QUIT\r\n
Dla przykładu powyższe instrukcje umożliwią wysłanie listu do odbiorca@sewer.pl.
Ale przejdźmy do rzeczy: połączenie z serwerem może odbyć się za pomocą funkcji fsockopen().
/* otwarcie gniazdka (laczenie sie z serwerem poczty) */
$this->socket = fsockopen($this->host, 25, $errno, $error, 30);
if (!$this->socket)
{
Error("$error ($errno)");
}
$this->socket = fsockopen($this->host, 25, $errno, $error, 30);
if (!$this->socket)
{
Error("$error ($errno)");
}
Pierwszym parametrem tej funkcji musi być nazwa hosta; drugim port. Trzeci i czwarty parametr to opis błędu oraz numer błędu. Ostatni parametr to TimeOut (ilość sekund przez jakie skrypt bedzie próbował połączyć
się z serwerem).
Wysyłanie komendy odybwa się za pośrednictwem funkcji fwrite():
Pierwszym parametrem musi być uchwyt do gniazdka (uzyskany jako rezultat działania funkcji fsockopen()). Drugi parametr to treść wysyłanej komendy.
Równie prosto można odczytać tekst, który został zwrócony przez serwer (funkcja fgets()).
Pierwszym parametrem musi być oczywiście uchwyt, a drugim ilość znaków jakie zostaną odczytane. Funkcja fgets() zwraca łańcuch (string), który zawiera treść zwróconą przez serwer. To chyba wszystko co trzeba wiedzieć na temat łączenia się z serwerem i wysyłaniem do niego komend. Nie należy oczywiście zapominać o tym, aby na końcu zamknąć połączenie (funkcja fclose()).
Klasa Mail
Na podstawie tego, co napisaliśmy można napisać klasę, która uprości cały proces przesyłania wiadomości. Kod źródłowy całego skryptu przedstawia się następująco:
<?php
function Error($msg)
{
/* funkcja wyswietla komunikat bledu pocztym konczy dzialanie programu. Wlasciwie stanowi niejako alias do funkcji die() */
echo $msg;
exit;
}
error_reporting (E_ERROR | E_WARNING | E_PARSE); // wyswietlaj bledy
set_time_limit(30); // time-out na 30 sek.
class Mail
{
var $host; // host, z ktorym bedziemy sie laczyc
var $socket; // uchwyt
var $mail_subject; // temat listu
var $mail_sender; // nadawca
var $mail_recipient; // odbiorca
var $mail_content; // treść
var $log; // log
function Mail($server_host)
{
if (empty($server_host))
{
Error('Nie wpisałeś hosta, z którym mam się połączyć');
}
$this->host = $server_host;
}
function connect()
{
/* otwarcie gniazdka (laczenie sie z serwerem poczty) */
$this->socket = fsockopen($this->host, 25, $errno, $error, 30);
if (!$this->socket)
{
Error("$error ($errno)");
}
/* wyslanie tekstu przywitalnego */
$this->send_cmd("HELO " . $this->host . "\r\n");
}
function disconnect()
{
/* rozlaczenie z serwerem; przed tym nalezy jednak wyslac polecenie QUIT */
$this->send_cmd("QUIT\r\n");
fclose($this->socket);
}
function send_cmd($var_command)
{
/* funkcja wysyla do gniazdka polecenie z parametru $var_command oraz odczytuje odpowiedz
z serwera i przypisuja ja do zmiennej $log */
if ( fwrite($this->socket, $var_command) )
{
$this->log .= fgets($this->socket, 100) . '<br>';
}
}
function set_mail_sender($var_sender)
{
$this->mail_sender = $var_sender;
}
function set_mail_recipient($var_recipient)
{
$this->mail_recipient = $var_recipient;
}
function set_mail_subject($var_subject)
{
$this->mail_subject = $var_subject;
}
function set_mail_content($var_content)
{
$this->mail_content = $var_content;
}
function send_mail()
{
if (empty($this->mail_recipient) ||
empty($this->mail_sender)) Error('Nie wpisałeś nadawcy lub odbiorcy e-maila!');
/* nadawca wiadomosci */
$this->send_cmd("MAIL FROM: <" . $this->mail_sender . ">\r\n");
/* odbiorca wiadomosci */
$this->send_cmd("RCPT TO: <" . $this->mail_recipient . ">\r\n");
/* informuje, ze zaraz rozpoczniemy wysylanie danych */
$this->send_cmd("DATA\r\n");
/* temat wiadomosci */
$this->send_cmd("Subject: " . $this->mail_subject . "\r\n");
/* kodowanie */
$this->send_cmd("Content-type: text/html; charset=iso-8859-2\r\n");
/* naglowki */
$this->send_cmd("From: " . $this->mail_sender . "\r\n");
$this->send_cmd("Reply-To: " . $this->mail_sender . "\r\n");
$this->send_cmd("Return-Path: " . $this->mail_sender . "\r\n\r\n");
/* tresc wiadomosci */
$this->send_cmd($this->mail_content . "\r\n");
$this->send_cmd(".\r\n"); // koniec wiadomosci
}
}
$mail = new Mail('mail.pf.pl');
$mail->set_mail_sender('bald@pf.pl');
$mail->set_mail_recipient('root@localhost.localdomain');
$mail->set_mail_subject('Testowy temat');
$mail->set_mail_content('Jakas tresc');
$mail->connect();
$mail->send_mail();
$mail->disconnect();
echo $mail->log;
?>
function Error($msg)
{
/* funkcja wyswietla komunikat bledu pocztym konczy dzialanie programu. Wlasciwie stanowi niejako alias do funkcji die() */
echo $msg;
exit;
}
error_reporting (E_ERROR | E_WARNING | E_PARSE); // wyswietlaj bledy
set_time_limit(30); // time-out na 30 sek.
class Mail
{
var $host; // host, z ktorym bedziemy sie laczyc
var $socket; // uchwyt
var $mail_subject; // temat listu
var $mail_sender; // nadawca
var $mail_recipient; // odbiorca
var $mail_content; // treść
var $log; // log
function Mail($server_host)
{
if (empty($server_host))
{
Error('Nie wpisałeś hosta, z którym mam się połączyć');
}
$this->host = $server_host;
}
function connect()
{
/* otwarcie gniazdka (laczenie sie z serwerem poczty) */
$this->socket = fsockopen($this->host, 25, $errno, $error, 30);
if (!$this->socket)
{
Error("$error ($errno)");
}
/* wyslanie tekstu przywitalnego */
$this->send_cmd("HELO " . $this->host . "\r\n");
}
function disconnect()
{
/* rozlaczenie z serwerem; przed tym nalezy jednak wyslac polecenie QUIT */
$this->send_cmd("QUIT\r\n");
fclose($this->socket);
}
function send_cmd($var_command)
{
/* funkcja wysyla do gniazdka polecenie z parametru $var_command oraz odczytuje odpowiedz
z serwera i przypisuja ja do zmiennej $log */
if ( fwrite($this->socket, $var_command) )
{
$this->log .= fgets($this->socket, 100) . '<br>';
}
}
function set_mail_sender($var_sender)
{
$this->mail_sender = $var_sender;
}
function set_mail_recipient($var_recipient)
{
$this->mail_recipient = $var_recipient;
}
function set_mail_subject($var_subject)
{
$this->mail_subject = $var_subject;
}
function set_mail_content($var_content)
{
$this->mail_content = $var_content;
}
function send_mail()
{
if (empty($this->mail_recipient) ||
empty($this->mail_sender)) Error('Nie wpisałeś nadawcy lub odbiorcy e-maila!');
/* nadawca wiadomosci */
$this->send_cmd("MAIL FROM: <" . $this->mail_sender . ">\r\n");
/* odbiorca wiadomosci */
$this->send_cmd("RCPT TO: <" . $this->mail_recipient . ">\r\n");
/* informuje, ze zaraz rozpoczniemy wysylanie danych */
$this->send_cmd("DATA\r\n");
/* temat wiadomosci */
$this->send_cmd("Subject: " . $this->mail_subject . "\r\n");
/* kodowanie */
$this->send_cmd("Content-type: text/html; charset=iso-8859-2\r\n");
/* naglowki */
$this->send_cmd("From: " . $this->mail_sender . "\r\n");
$this->send_cmd("Reply-To: " . $this->mail_sender . "\r\n");
$this->send_cmd("Return-Path: " . $this->mail_sender . "\r\n\r\n");
/* tresc wiadomosci */
$this->send_cmd($this->mail_content . "\r\n");
$this->send_cmd(".\r\n"); // koniec wiadomosci
}
}
$mail = new Mail('mail.pf.pl');
$mail->set_mail_sender('bald@pf.pl');
$mail->set_mail_recipient('root@localhost.localdomain');
$mail->set_mail_subject('Testowy temat');
$mail->set_mail_content('Jakas tresc');
$mail->connect();
$mail->send_mail();
$mail->disconnect();
echo $mail->log;
?>
Na samym końcu następuje skorzystanie z tej klasy oraz z serwera mail.pf.pl do wysłania listu. Na końcu powinien zostać wyświetlony log z działania klasy (log sporządzony na podstawie komunikatów zwracanych przez serwer).



Fakt, że technicznie wyczerpuje specyfikację, ale to jedyne co można o niej powiedzieć. Może poza tym, że tak jak sam PHP jest ona sklejką niezbyt powiązanych ze sobą metod różnych autorów.
Informacje: [url]http://www.faqs.org/rfcs/rfc1896[/url]
[url]http://www.zend.com/zend/spotlight/sendmimeemailpart1.php[/url]