Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

La funzione mail()

Inviare email con Php in modo semplice e veloce
Inviare email con Php in modo semplice e veloce
Link copiato negli appunti

Introduzione

A mio modesto avviso uno dei più interessanti ed utili aspetti di Internet è dato dalla possibilità di inviare e ricevere Email, la cosiddetta Posta Elettronica, una forma di comunicazione sempre più diffusa e, per varie ragioni, fra tutte la semplicità d'uso e l'immediatezza del messaggio.

Quando parliamo di mail probabilmente pensiamo subito ad un Client di Posta Elettronica (Outlook o Eudora, per citarne due tra i più diffusi), software grazie al quale riusciamo agevolmente a gestire la nostra corrispondenza telematica o, in alternativa, a quei servizi on-line con cui è possibile ottenere lo stesso risultato.

Quello che molti non sanno, invece, è che è possibile inviare email grazie a PHP, sempre in modo molto semplice, grazie a pochissime righe di codice, come vedremo immediatamente. I messaggi non saranno soltanto di puro testo ma anche in formato HTML e con allegati.

Ma cos'è una mail ? Volendo semplificare la massimo la definizione, una mail non è altro che un file di testo, composto da una serie di intestazioni (separate da loro dal carattere di Nuova Linea e che rappresentano delle istruzioni per un software di posta elettronica o danno particolari informazioni sulla struttura e la natura della mail stessa) e dal messaggio vero e proprio.

La funzione, l'unica, che PHP ci mette a disposizione per l'invio di email dal server è la funzione mail(), che prevede tre argomenti obbligatori e due facoltativi.
Prima di addentrarci nell'esame della funzione, è necessario fare un passo indietro, perchè possiamo utilizzare efficacemente mail(), dobbiamo infatti accertarci che PHP sia correttamente configurato. A questo scopo dobbiamo ovviamente dare un'occhiata al file di configurazione, php.ini, nella parte dedicata a questo argomento:

[mail function]
; For Win32 only.
SMTP = localhost

; For Win32 only.
sendmail_from = me@localhost.com

; For Unix only. You may supply arguments as well (default: "sendmail -t -i").
;sendmail_path =

Come si vede è necessario indicare un server SMTP (Simple Mail Transfer Protocol) ed un indirizzo email che costituirà il mittente di posta predefinito, soltanto nel caso in cui PHP venga eseguito su Windows; nel caso in cui si lavori su piattaforma UNIX, invece, sarà necessario solo verificare il corretto percorso del programma per l'invio di posta che sarà nel 90% dei casi, sendmail che è installato di default su quasi tutti i sistemi UNIX e che si preoccuperà di svolgere tutto il lavoro di invio del messaggio al mail server del destinatario.

Evidente quindi che la funzione mail() si limita semplicemente ad inviare al sistema di posta (locale o remoto),
il messaggio elettronico e restituisce TRUE quando il messaggio stesso è passato correttamente, a prescindere dal fatto che la mail sia stata inviata o ricevuta con successo.

La funzione mail()

La funzione mail(), si diceva, prevede tre argomenti obbligatori, essi sono:

  • l'indirizzo Email (o gli indirizzi, separati fra loro con una virgola) del destinatario
  • il soggetto della Mail
  • il corpo (il contenuto) della mail

Questi argomenti vanno indicati per la corretta esecuzione della funzione, ma è possibile comunque lasciare vuoti il secondo e terzo campo; ad esempio, questa riga di codice:

mail("mail@sito.it", "", "");

provvederà ad inviare una mail, senza soggetto e senza contenuto, all'indirizzo mail@sito.it.

La funzione prevede, inoltre, altri due parametri facoltativi: il primo destinato a contenere le intestazioni supplementari della mail, fra cui ricordiamo:

  • From - serve a specificare il mittente della mail stessa, in caso di mancata indicazione, verrà indicato il mittente di default del sistema. La sintassi di From è la seguente: From: mittente@sito.it

o, in alternativa

  • From: mittente<mittente@sito.it>
  • Reply-to: l'indirizzo (o gli indirizzi) di posta elettronica cui inviare le risposte
  • Cc: Carbon Copy (Copia Carbone), ossia un elenco di ulteriori indirizzi (separati da una virgola), destinatari della mail
  • Bcc: Blind Carbon Copy (Copia Carbone Nascosta), l'indirizzo ( o gli indirizzi) cui inviare la mail senza che lo stesso (o gli stessi) siano visualizzati tra i destinatari
  • La versione MIME (Multipurpose Internet Mail Extensions)
  • Il tipo di contenuto (text/html, text/plain, multipart/mixed)
  • La codifica di trasferimento dei contenuti
  • Il set di caratteri

Tutte le intestazioni vanno separate tra di loro da un carattere di ritorno (r) più uno di nuova riga (n), anche se a questo proposito va detto che il carattere n sarebbe sufficiente (sicuramente lo è sui sistemi UNIX), ma purtroppo si è ben lontani dall'affermarsi di uno standard universale che venga correttamente interpretato da tutti i client di posta e da tutti gli MTA (Mail Transfer Agent), per cui occorre regolarsi di volta in volta.

Alla luce di quanto detto, una mail un pò più "completa" potrebbe essere questa:

<?php

$headers = "From: mittente<mittente@sito.it>nCc: copy@sito.itnReply-to: reply@sito.it";
mail("mail@sito.it", "Soggetto", "Contenuto", $headers);

?>

Invio di una email in formato testo

Cerchiamo adesso di analizzare dei casi concreti di applicazione della funzione mail(); primo fra tutti, ovviamente, il classico "form to mail", ossia uno script che provveda ad inviare il contenuto di un modulo HTML ad un indirizzo Email specificato. Il form HTML potrebbe essere questo:

<form action="./mail.php" method="POST">
<table border="0">
  <tr>
    <td>Nome</td>
    <td><input type="text" name="Nome" size="30"></td>
  </tr>
  <tr>
    <td>Età</td>
    <td><input type="text" name="Anni" size="5"></td>
  </tr>
  <tr>
    <td>Città</td>
    <td><input type="text" name="City" size="30"></td>
  </tr>
  <tr>
    <td>Indirizzo</td>
    <td><input type="text" name="Address" size="30"></td>
  </tr>
  <tr>
    <td valign="top">Note</td>
    <td><textarea rows="6" name="Note" cols="50"></textarea></td>
  </tr>
  <tr>
    <td colspan="2" valign="bottom" align="center" height="30">
    <input type="submit" value="Invia">
    <input type="reset" value="Cancella"></td>
  </tr>
</table>
</form>

La pagina .php destinata a ricevere il contenuto del modulo (mail.php, nel nostro esempio) potrebbe essere la seguente:

<?php

// L'INDIRIZZO DEL DESTINATARIO DELLA MAIL
$to = "mail@sito.it";

// IL SOGGETTO DELLA MAIL
$subject = "Modulo proveniente dal sito www.miosito.it";

// COSTRUIAMO IL CORPO DEL MESSAGGIO
$body = "Contenuto del modulo:nn";
$body .= "Nome: " . trim(stripslashes($_POST["Nome"])) . "n";
$body .= "Età: " . trim(stripslashes($_POST["Anni"])) . "n";
$body .= "Città: " . trim(stripslashes($_POST["City"])) . "n";
$body .= "Indirizzo: " . trim(stripslashes($_POST["Indirizzo"])) . "n";
$body .= "Note: " . trim(stripslashes($_POST["Note"])) . "n";

// INTESTAZIONI SUPPLEMENTARI
$headers = "From: Modulo utenti<modulo@sito.it>";

// INVIO DELLA MAIL
if(@mail($to, $subject, $body, $headers)) { // SE L'INOLTRO È ANDATO A BUON FINE...

echo "La mail è stata inoltrata con successo.";

} else {// ALTRIMENTI...

echo "Si sono verificati dei problemi nell'invio della mail.";

}

?>

Poco o niente da dire sul codice (i commenti dovrebbero essere più che sufficienti), solo da notare come costruiamo il corpo del messaggio concatenando i vari elementi del modulo e, come prevediamo, di inviare in ogni caso messaggi personalizzati che indichino all'utente l'esito dell'invio del modulo (la @ anteposta alla funzione, impedisce la stampa a video dei messaggi di errore predefiniti di PHP).

Invio di un allegato

Nel caso in cui si volesse inviare la mail in formato HTML, è possibile usare il codice di cui sopra, cui è sufficiente aggiungere una intestazione (appena sotto $headers = ...), per specificare il tipo di contenuto ed il set di caratteri:

$headers .= "Content-Type: text/html; charset=iso-8859-1n";

Per concludere voglio spiegare brevemente, con il codice di esempio, come allegare un file ad una mail, argomento che è certamente tra i più interessanti in relazione all'invio di mail con PHP e che è sicuramente meno ostico di quanto potrebbe apparire, tenendo conto che un allegato non è altro che un insieme di dati che vengono codificati in un certo modo. È sufficiente indicare al sistema di posta che riceverà il messaggio il tipo di codifica utilizzata.

Ecco subito il codice necessario, anzitutto il modulo HTML:

<form action="sendmail.php" enctype="multipart/form-data" method="POST">
<table cellpadding="0" cellspacing="0">
  <tr>
    <td>Destinatario: </td>
    <td><input type="text" name="Destinatario" size="40"></td>
  </tr>
  <tr>
    <td>Soggetto:</td>
    <td><input type="text" name="Soggetto" size="40"></td>
  </tr>
  <tr>
    <td>Allegato:</td><td><input type="file" name="allegato" size="40"></td>
  </tr>
  <tr>
    <td valign="top">Contenuto:</td>
    <td><textarea name="Contenuto" rows="15" cols="50"></textarea></td>
  </tr>
  <tr>
    <td height="30" valign="bottom" colspan="2" align="center"><input type="submit" value="Invia la mail">
  </tr>
</table>
</form>

Voglio far notare l'attributo del form multipart/form-data, sulla cui spiegazione vi rimando al mio articolo sugli Upload in PHP.

Ecco il codice della pagina sendmail.php "puntata" dal form:

<?php

// RENDIAMO LO SCRIPT COMPATIBILE CON LE VERSIONI DI PHP < 4.1.0
if(!isset($_POST)) $_POST = $HTTP_POST_VARS;
if(!isset($_FILES)) $_FILES = $HTTP_POST_FILES;

// RIPULIAMO I VARI CAMPI DEL MODULO
$Destinatario = trim($_POST["Destinatario"]);
$Soggetto = trim(stripslashes($_POST["Soggetto"]));
$Contenuto = trim(stripslashes($_POST["Contenuto"]));

// ASSEGNIAMO A VARIABILI PIU' LEGGIBILI, LE PROPRIETA' DELL'ALLEGATO
$attach = $_FILES["allegato"]["tmp_name"];
$file_name = $_FILES["allegato"]["name"];
$file_type = $_FILES["allegato"]["type"];
$file_size = $_FILES["allegato"]["size"];

// DELIMITATORE
$boundary = md5(uniqid(microtime()));

// APRIAMO L'ALLEGATO PER LEGGERLO E CODIFICARLO
$file = @fopen($attach, "r");
$contents = @fread($file, $file_size);
$encoded_attach = chunk_split(base64_encode($contents));
@fclose($file);

// INTESTAZIONI DELLA MAIL
$mail_headers .= "MIME-version: 1.0n";
$mail_headers .= "Content-type: multipart/mixed; boundary="$boundary"";
$mail_headers .= "X-attachments: $file_namen";

// COSTRUIAMO IL CORPO DELLA MAIL
$mail_body = "--$boundaryn";
$mail_body .= "Content-Type: text/plain; charset=us-asciin";
$mail_body .= "Content-Transfer-Encoding: 7bitnn";
$mail_body .= "$Contenutonn";
$mail_body .= "--$boundaryn";
$mail_body .= "Content-type: $file_type; name="$file_name"n";
$mail_body .= "Content-Transfer-Encoding: base64n";
$mail_body .= "$encoded_attachn";
$mail_body .= "--$boundary--n";

// INVIO DELLA MAIL
if(@mail($Destinatario, $Soggetto, $mail_body, $mail_headers)) { // SE L'INVIO È ANDATO A BUON FINE...

echo "La mail è stata inoltrata con successo.";

} else {// ALTRIMENTI...

echo "Si sono verificati dei problemi nell'invio della mail.";

}

?>

Analizziamo il codice

Una breve spiegazione del codice si impone. Anzitutto, a differenza delle mail che contengono puro testo, qui entrano in gioco gli standard MIME (Multipurpose Internet Mail Extensions), che consentono di estendere le potenzialità delle mail consentendo, fra l'altro, di allegarvi dei file. Ecco quindi che la prima intestazione che abbiamo specificato è la versione MIME.

Sempre riguardo alle intestazioni, notiamo come il content-type sia multipart/mixed, questo perchè la mail è destinata a contenere dei dati non testuali.

Caratteristica dei messaggi di questo tipo è che il loro corpo deve essere diviso in uno o più parti, separate fra di loro da un delimitatore (boundary) specificato sempre nella stessa intestazione, che non deve assolutamente comparire all'interno delle parti che delimita. Ecco perchè abbiamo usato le funzioni md5(uniqid(microtime())) per costruirlo: esse generano una stringa alfanumerica casuale di 32 caratteri; in questo modo avremo così la certezza pressochè assoluta che la stringa risultante non sarà presente nel corpo della mail.

Ciascuna parte deve pertanto iniziare con il boundary preceduto da due trattini (--$boundary); l'ultima parte del messaggio deve invece essere seguita dal boundary preceduto e seguito da due trattini (--$boundary--), in questo modo si indica al programma di posta che il messaggio non contiene altre parti.

La successiva intestazione, specifica il nome del file allegato (contenuto nella variabile $file_name).
A questo punto iniziamo a costruire il corpo della mail suddiviso, come si diceva, in varie parti che iniziano con --$boundary; la prima parte è destinata a contenere il contenuto della textarea (puro testo), per cui vengono specificati il content-type ed il set di caratteri (rispettivamente text/plain e us-ascii), quindi il Content-transfer-encoding, ossia il tipo di codifica utilizzato sui dati e che verrà utilizzato dal sistema di posta che riceverà la mail per la relativa decodifica (7bit è la normale codifica utilizzata sui caratteri US ASCII); segue quindi il contenuto (testuale) vero e proprio del messaggio.

È la volta quindi dell'allegato. Dopo il boundary vengono indicati il tipo ed il nome del file, quindi il Content-transfer-encoding, base64 in questo caso, che è il tipo di codifica più affidabile per i dati non testuali. Segue infine l'allegato vero e proprio; a questo proposito è necessario fare un passo indietro, dopo che il file viene "letto" (con fread(), che salvaguarda la corrispondenza binaria), viene "trasformato" con la codifica base64 (funzione base64_encode()) e, al contempo, viene suddiviso (con la funzione chunk_split()) in chunks (pezzi) di 76 caratteri, questo perchè i dati codificati con base64 devono essere rappresentati in righe non superiori a 76 caratteri.

A conclusione del corpo della mail ($mail_body) viene quindi inserito il boundary di chiusura (--$boundary--) e la mail può quindi essere inviata.

Ti consigliamo anche