Guida Php – Classi per inviare email

In questo capitolo costruiremo una libreria che ci consentirà di inviare email complesse, ad esempio in HTML con uno o più allegati, in modo molto trasparente e veloce.

Questa libreria non è completa anche se funziona correttamente. Non ho infatti implementato alcuna gestione delle eccezioni che vi consiglio pertanto di aggiungere qualora decidiate di usarla nello sviluppo di applicazioni reali.
Inoltre sarebbe stato utile interfacciare la libreria con la classe “File” vista nei capitoli precedenti, ma ho preferito comunque non inserire altre classi esterne essendo lo scopo di questa libreria puramente didattico.

Vediamo ora le Classi che compongono questa nuova libreria e il loro scopo :

  • MIMEClasse usata come contenitore di costanti per definire i tipi MIME supportati dall’applicazione
  • MailBlockRappresenta un sottoblocco del messaggio email, quest ultimo sarà quindi composto da una o più istanze di MailBlock
  • AllegatoDerivata da MailBlock, rappresenta un file allegato ossia un sottoblocco più complesso con codifica Base64
  • EmailClasse principale creata per fornire un’interfaccia fra tutte le altre classi, costruendo il messaggio email completo e inviandolo

Classe : “MIME”
Nome file : “MIME.php”

<?php</p>
class MIME
{
const HTML = "text/html";
const TEXT = "text/plain";
const MULTI = "multipart/mixed";</p>
const GIF = "image/gif";
const JPEG = "image/jpeg";
const PNG = "image/png";
const PSD = "image/psd";
const BMP = "image/bmp";
const TIFF = "image/tiff";
const FLASH = "application/x-shockwave-flash";
}</p>
?>

Classe : “MailBlock”
Nome file : “MailBlock.php”

<?php</p>
define("EOL", "rn");</p>
class MailBlock
{
protected $content_type;
protected $charset;
protected $content_transfer_encoding;</p>
public $content;
protected $boundary;</p>
public function MailBlock($content_type, $boundary, $content, $charset = "iso-8859-1", $c_t_encoding = "8bit")
{
$this->content_type = $content_type;
$this->charset = $charset;
$this->content_transfer_encoding = $c_t_encoding;</p>
$this->content = $content;
$this->boundary = $boundary;
}</p>
public function __toString()
{
$content = "--" . $this->boundary . EOL;
$content .= "Content-Type: " . $this->content_type . "; charset=" . $this->charset . EOL;
$content .= "Content-Transfer-Encoding: " . $this->content_transfer_encoding . EOL;
$content .= $this->content . EOL;
$content .= "--" . $this->boundary . EOL;

return $content;
}
}

?>

La classe proposta è piuttosto semplice, non fa altro che collezionare i dati necessari a rappresentare un sottoblocco e ad organizzarli attraverso il metodo __toString().
Il codice che segue inizializza correttamente un sottoblocco in formato HTML :

<?php

require_once("MIME.php");
require_once("MailBlock.php");

$boundary = "fa0s7u98hg87ngf0hgk05695j";
$contenuto = "<ul><li>Linea uno</li><li>Linea due</li></ul>";

$blocco = new MailBlock(MIME::HTML, $boundary, $contenuto);

echo $blocco; // Richiama "__toString()" stampando il sottoblocco con la sintassi corretta

?>

Classe : “Allegato”
Nome file : “Allegato.php”

<?php</p>
require_once("MailBlock.php");</p>
class Allegato extends MailBlock
{
public $url;
public $name;
public $description;</p>
public function Allegato($name, $url, $content_type, $boundary, $description = NULL)
{
$this->url = $url;
$this->name = $name;
$this->boundary = $boundary;
$this->description = $description;</p>
$this->content = $this->leggi();
parent::MailBlock($content_type, $boundary, $this->content, "utf-8", "base64");
}</p>
private function leggi()
{
$file = @fopen($this->url, "r");
$allegato = fread($file, filesize($this->url));
return base64_encode($allegato);
}</p>
public function __toString()
{
$content = "--" . $this->boundary . EOL;
$content .= "Content-Type: " . $this->content_type . "; name="" . $this->name . """ . EOL;
$content .= "Content-Transfer-Encoding: " . $this->content_transfer_encoding . EOL;
$content .= "Content-Description: " . $this->description . EOL;
$content .= "Content-Disposition: attachment; filename="" . $this->name . """ . EOL;
$content .= $this->content . EOL;
$content .= "--" . $this->boundary . EOL;

return $content;
}
}

?>

La classe soprastante deriva dalla precendente MailBlock, aggiungendo però tre importanti parametri necessari per gestire il file allegato, ossia l’url, il nome del file che sarà visualizzato dal destinatario e infine una descrizione facoltativa.

Il metodo privato leggi() si occupa invece di leggere il file specificato, per poi inserirlo nel sottoblocco in questione usando la codifica Base64.

Il metodo pubblico __toString() si comporta come il suo genitore, organizzando però il sottoblocco con i tre parametri aggiuntivi e inserendo alla fine il contenuto del file specificato.

Nel prossimo capitolo vedremo l’oggetto Email, l’ultima classe della nostra libreria con del codice d’esempio.

In questa lezione vedremo la classe Email, analizzandone brevemente metodi e attributi ed infine un esempio per l’utilizzo della nuova libreria con l’invio di due allegati.

Attributi

  • private $to_mailArray contenente la lista dei destinatari.
  • private $objectOggetto dell’email.
  • private $messageArray contenente tutti i sottoblocchi che formeranno il messaggio, ossia istanze di “MailBlock” e “Allegato“.
  • public $mimeVersione MIME utilizzata per lo standard dell’email.
  • public $content_typeContent-Type per identificare il contenuto del messaggio (es. “text/html” oppure “multipart/mixed” …).
  • private $boundaryDelimitatore boundary generato criptando il timestamp Unix corrente.
  • public $ccStringa contenente gli indirizzi per l’invio dell’email in copia carbone. Consiglio di rendere private l’attributo e di trasformarlo in un array, costruendo un metodo per un inserimento controllato.
  • public $bccStringa contenente gli indirizzi per l’invio dell’email in copia carbone. Anche qui consiglio di agire come con l’attributo $cc.
  • public $dateData di invio email (tipo stringa).
  • public $fromIndirizzo email del mittente, consiglio anche qui di effettuare la stessa modifica descritta per l’attributo $cc.
  • public $reply_toSpecifica l’email predefinita a cui il destinatario dell’email potrà rispondere. Anche qui stesso consiglio.
  • public $xmailerStringa che identifica il software utilizzato per l’invio dell’email.

Metodi

  • public Email()Costruttore della classe. Inizializza $object, $content_type e altri attributi.
  • public blocco()Aggiunge un sottoblocco standard al corpo del messaggio, ossia un’istanza MailBlock.
  • public allegato()Aggiunge un sottoblocco più complesso al corpo del messaggio che rappresenterà un file allegato, ossia un’istanza di Allegato.
  • public destinatario()Aggiunge un indirizzo alla lista dei destinatari.
  • private header()Metodo privato che costruisce l’header dell’email basandosi sui parametri memorizzati negli attributi della classe.
  • public invia()Metodo per l’invio dell’email. Restituisce true o false per identificare se l’invio è avvenuto con successo.

Classe : “Email”
Nome file : “Email.php”

<?php</p>
require_once("MIME.php");
require_once("Allegato.php");</p>
class Email
{
private $to_mail;
private $object;
private $message;</p>
public $mime = "1.0";
public $content_type;
private $boundary = NULL;</p>
public $cc = NULL;
public $bcc = NULL;
public $date = NULL;
public $from = NULL;
public $replyto = NULL;
public $xmailer = NULL;</p>
public function Email($object, $content_type = MIME::TEXT)
{
$this->to_mail = array();
$this->object = $object;
$this->message = array();</p>
$this->boundary = md5(time());
$this->content_type = $content_type;
}

public function blocco($content_type, $content, $charset = "iso-8859-1", $c_t_encoding = "8bit")
{
$succ = count($this->message);
$this->message[$succ] = new MailBlock($content_type, $this->boundary, $content, $charset, $c_t_encoding);
}

public function allegato($name, $url, $mime_type, $description = NULL)
{
$succ = count($this->message);
$this->message[$succ] = new Allegato($name, $url, $mime_type, $this->boundary, $description);

/* Se questo metodo viene richiamato significa che è stato inserito almeno un
allegato quindi per sicurezza modifico il Content-Type a "multipart/mixed" */
$this->content_type = MIME::MULTI;
}

public function destinatario($to_mail)
{
array_push($this->to_mail, $to_mail);
}

private function header()
{
$header = "MIME-Version: " . $this->mime . EOL;
$header .= "Content-Type: " . $this->content_type . "; boundary="" . $this->boundary . """ . EOL;
$header .= "Content-Transfer-Encoding: 8bit" . EOL;

if ($this->from != NULL) { $header .= "From: " . $this->from . EOL; }
if ($this->replyto != NULL) { $header .= "Reply-To: " . $this->replyto . EOL; }
if ($this->cc != NULL) { $header .= "Cc: " . $this->cc . EOL; }
if ($this->bcc != NULL) { $header .= "Bcc: " . $this->bcc . EOL; }
if ($this->date != NULL) { $header .= "Date: " . $this->date . EOL; }
if ($this->xmailer != NULL) { $header .= "X-Mailer: " . $this->xmailer; }

return $header;
}

public function invia()
{
$message = "";
$blocchi = count($this->message);

for ($i = 0; $i < $blocchi; $i++)
$message .= $this->message[$i]; // Richiama il metodo __toString() di "Allegato" o "MailBlock"

$to = implode(", ", $this->to_mail);
return mail($to, $this->object, $message, $this->header());
}
}

?>

Come potete vedere anche la classe Email è piuttosto semplice dovendo principalmente fungere da interfaccia unendo i dati.

Con questa classe la nostra libreria è al completo. Per ultimo vedremo un piccolo foglio PHP come esempio di utilizzo della libreria, inviando un’email con un blocco di testo, un blocco in HTML e 2 file allegati.

test.php

<?php

require_once("Email.php");

$mail = new Email("Mail con allegati", MIME::MULTI);

/* Codice per aggiungere i destinatari */
$mail->destinatario("RS Staff <posta@realizzazione-sito.info>");
//$mail->destinatario("Utente1 <utente1@dominio.it>");
//$mail->destinatario("Utente2 <utente2@dominio.it>");

$mail->from = "Mittente <email_di_invio@gmail.com>";
$mail->replyto = "Risposta <email_per_risposta@gmail.com>";

$mail->blocco(MIME::TEXT, "Iniziamo con un pò di testo nel primo blocco!!");

/* Memorizzo l'html per il secondo blocco in una
variabile per favorire la leggibilità del codice */
$html = "<ul><li>Linea uno</li><li>Linea due</li></ul>";
$html .= "<table border="1"><tr><td>topolino<td><td>minnie</td></tr></table>";

$mail->blocco(MIME::HTML, $html);
$mail->allegato("litfiba.jpg", "allegati/file.jpg", MIME::JPEG);
$mail->allegato("220 volts.jpg", "allegati/220v.jpg", MIME::JPEG);

$inviata = $mail->invia();

if ($inviata) { echo "Mail inviata con successo!!"; }
else { echo "Mail non inviata!!"; }

?>

Il risultato ottenuto.

Anche in questo caso ho testato il codice solo con GMail, non escludo quindi problemi di compatibilità con altri siti o client di posta (Outlook, Eudora …), e dovendo riscontrarne vi consiglio di provare a modificare l’EOL o il boundary di chiusura.

Versione originale dell’articolo

Lezione Precedente -> Guida Php – Inviare email con allegati

Lezione Successiva -> Guida Php – I Database

Tags: , ,

Lascia un Commento

Connect with Facebook