3 Sep 2011 13 commenti
L'invio di email con php è relativamente semplice. Esiste a tale scopo un'unica funzione mail() della quale ho già parlato in un precedente articolo.
Essa è semplice da usare se si tratta di semplici email di testo ma nei casi in cui le nostre esigenze sono più complesse conviene ricorrere a librerie che consentono di semplificarci notevolmente il lavoro. A questo scopo ve ne sono diverse ma quella che personalmente preferisco, e che utilizzerò nel presente tutorial, è Switmailer.
Si tratta di una libreria particolamente potente e ricca di funzionalità fra le quali la possibilità di allegare un file alle email che andremo ad inviare attraverso il nostro sito web.
Nel seguente tutorial vedremo l'utilizzo di Swiftmailer per la realizzazione di un form contatti. Ma le linee guida illustrate hanno, ovviamente, valenza generale.
Il contact form
Un banale contact form che non richiede nessun particolare commeto. Giova solo evidenziale l'enctype utilizzato (enctype="multipart/form-data").
La validazione del form è stata eseguita con il plugin Jquery validation di cui ho già parlato in un precedente articolo e a cui rimando per i dattagli.
Lo style è minimalista dato che esula dagli scopi del seguente tutorial e lascio a voi tutte le personalizzzazioni.
Le poche righe di codice php ci serviranno per ottenere il messaggio di successo o insuccesso dal nostro script.
<html> <head> <title>Contact form with attachment</title> <style> input, label, textarea{ display: block; font-size: 15px; } label{ margin-top: 20px; margin-bottom: 0px;} input, textarea{ margin: 0px; padding: 0px;} label.error{color: red; margin: 0px; font-size: 12px;} p.msg_script{ font-size: 20px; color: blue; } </style> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> <script type="text/javascript" src="http://ajax.microsoft.com/ajax/jquery.validate/1.7/jquery.validate.js"></script> <script type="text/javascript"> $(document).ready(function() { $("#contact_form").validate( { rules: { 'nome':{ required: true }, 'oggetto':{ required: true }, 'email':{ required: true, email: true }, 'messaggio':{ required: true, minlength: 5 } }, messages: { 'nome':{ required: "Il campo username è obbligatorio!" }, 'oggetto':{ required: "Il campo username è obbligatorio!" }, 'email':{ required: "Il campo email è obbligatorio!", email: "Inserisci un valido indirizzo email!" }, 'messaggio':{ required: "Il campo messaggio è obbligatorio!", minlength: "Il tuo messaggio è eccessivamente breve!" } } }); }); </script> </head> <body> <?php $msg = isset($_GET['msg']) ? '<p class="msg_script">' . urldecode($_GET['msg']) . '</p>' : ''; echo $msg; ?> <form action="send.php" method="post" enctype="multipart/form-data" id="contact_form"> <fieldset> <label for="nome">Nome*</label> <input type="text" id="nome" name="nome" /> <label for="oggetto">Oggetto*</label> <input type="text" id="oggetto" name="oggetto" /> <label for="email">Email*</label> <input type="text" id="email" name="email" /> <label for="messaggio">Messaggio*</label> <textarea rows="10" cols="60" id="messaggio" name="messaggio"></textarea> <label for="allegato">Allega un file (doc, xls, pdf, jpg, jpeg, png, gif, zip, rar)</label> <input type="file" name="allegato" id="allegato" /> <br /> <input type="submit" name="invia" value="invia" /> </fieldset> </form> </body> </html>
File di configurazione
Nel file di configurazione (config.php) andremo ad impostare alcuni valori. In particolare il server SMTP, la porta che utilizzeremo e le credenziali di accesso alla nostra email.
<?php /************************/ /* SETTING DELLO SCRIPT */ /************************/ define('HOST_SMTP', 'out.alice.it'); define('PORT_SMTP', 25); // FALSE, 25, 465, 587 define('SECUTITY_SMTP', FALSE); // FALSE, ssl, tsl define('EMAIL_SMTP', 'vostraemail@alice.it'); define('PASSWORD_SMTP', '********'); define('EMAIL_DESTINATARIO', 'destinatario@email.it'); define('MAX_DIM_FILE', 1048576); // 1mb = 1048576 byte ?>
I dati SMTP e la porta ci sono forniti, ovviamente, dal nostro provider di posta elettronica. La costante SECURITY_SMTP ci servirà per impostare il protocollo di trasmissione dei dati (se si utilizza la porta 25 impostate come valore FALSE).
A titolo puramente esemplificativo, in base hai test che ho condotto, riporto qualcuno dei più diffusi nella seguente tabella.
SMPT | Port | |
---|---|---|
vostraemail@gmail.com | smtp.gmail.com | 465 (ssl) |
vostraemail@yahoo.com vostraemail@yahoo.it |
smtp.mail.yahoo.com smtp.mail.yahoo.it |
465 (ssl) |
vostraemail@hotmail.com vostraemail@hotmail.it |
Non sono riuscito a far funzionare Swiftmailer con hotmail. Sono ben accetti commenti che possano rispondere alla questione. | |
vostraemail@alice.it | out.alice.it | 25 |
Infine, evitate assolutamente di impostare valori troppo alti per la dimensione massima degli allegati. Personalmente consiglio di non superare i 2-3 Mb. Infatti, ciò rallenta di molto l'operazione di invio e nei casi peggiori (con file pittosto grandi) si rischia superare il tempo massimo di esecuzione dei file (direttiva max_execution_time del php.ini) e andrà a generarvi il seguente errore:
Fatal error: Maximum execution time of 60 seconds exceeded ...
Invio email tramite Swiftmailer
Il file send.php si occuperà di inviare l'email.
// se il form e' stato inviato... if(isset($_POST['invia'])){ /************************************/ /* VARIABILE PER GESTIRE GLI ERRORI */ /************************************/ // la impostiamo FALSE // se durante la procedura diventa vera la modifichiamo in TRUE $error = FALSE; /********************************/ /* RICEVIAMO GLI INPUT DAL FORM */ /********************************/ $nome = isset($_POST['nome']) ? trim( (string) $_POST['nome']) : ''; $oggetto = isset($_POST['oggetto']) ? trim( (string) $_POST['oggetto']) : ''; $email = isset($_POST['email']) ? trim( (string) $_POST['email']) : ''; $messaggio = isset($_POST['messaggio']) ? trim( (string) $_POST['messaggio']) : ''; /************************************/ /* VERIFICHIAMO I CAMPI OBBLIGATORI */ /************************************/ if( $nome=='' ) { $error = TRUE; $msg = 'Il campo nome è obbligatorio!'; } else if( $oggetto=='' ){ $error = TRUE; $msg = 'Il campo oggetto è obbligatorio'; } else if( !preg_match('/^[_a-zA-Z0-9-]+(.[_a-zA-Z0-9-]+)*@[a-zA-Z0-9-]+(.[a-zA-Z0-9-]+)+$/', $email) ){ $error = TRUE; $msg = 'Il campo email è obbligatorio. Verifica di averlo digitato correttamente.'; } else if( $messaggio=='' ){ $error = TRUE; $msg = 'Il campo messaggio è obbligatorio'; } // siccome i campi obbligatori sono ok possiamo procedere a comporre lemail else{ /************************************************************/ /* INCLUDIAMO SWIFTMAILER E IL NOSTRO FILE DI CONFIGURAZIONE*/ /************************************************************/ require_once('lib/swift_required.php'); require_once('config.php'); /*****************************************************************/ /* IMPOSTIAMO IL SERVER SMTP CHE SI OCCUPERA' DI INVIARE L'EMAIL */ /*****************************************************************/ // i dati SMTP presenti nel config if( (PORT_SMTP != FALSE) AND ( SECUTITY_SMTP != FALSE ) ){ $transport = Swift_SmtpTransport::newInstance(HOST_SMTP, PORT_SMTP, SECUTITY_SMTP); } else if( PORT_SMTP != FALSE ){ $transport = Swift_SmtpTransport::newInstance(HOST_SMTP, PORT_SMTP); } else{ $transport = Swift_SmtpTransport::newInstance(HOST_SMTP); } $transport->setUsername(EMAIL_SMTP); $transport->setPassword(PASSWORD_SMTP); $mailer = Swift_Mailer::newInstance($transport); /***************************/ /* COMPONIAMO IL MESSAGGIO */ /***************************/ $message = Swift_Message::newInstance($oggetto); // oggetto $message->setFrom(array($email => $nome)); // email e nome di provenienza $message->setTo(array(EMAIL_DESTINATARIO)); // destinatario/i soto forma di array $message->setBody($messaggio,'text/html'); // corpo del messaggio // http://forums.devnetwork.net/viewtopic.php?f=52&t=98225&p=531623 $message->setReturnPath(EMAIL_SMTP); /************/ /* ALLEGATO */ /************/ // se esiste l'allegato if( (isset($_FILES["allegato"])) AND ($_FILES["allegato"]['name'] != '') ){ // indichiamo le tipologie di file consentiti $tipologie_consentite = array('jpg', 'jpeg', 'png', 'gif', 'doc', 'pdf', 'xls', 'zip', 'rar'); // tutto minuscolo $path_info = pathinfo($_FILES["allegato"]['name']); // se si e' verificato un errore nell'upload... if(!is_uploaded_file($_FILES["allegato"]['tmp_name'])){ $error = TRUE; $msg = 'Si è verificato un errore durante il caricamento del file!'; } else if(!in_array(strtolower($path_info['extension']), $tipologie_consentite)){ $error = TRUE; $msg = 'Il file non è fra i tipi consentiti!'; } // se supera la dimensione massima consentita else if($_FILES["allegato"]['size'] > MAX_DIM_FILE){ // supera la dimensione massima consentita... $error = TRUE; $msg = 'Il file allegato eccede la dimensione massima consentita!'; } // altrimenti andiamo ad allegare il file else{ $attachment = Swift_Attachment::fromPath($_FILES["allegato"]['tmp_name']); $attachment->setFilename($_FILES["allegato"]['name']); $message->attach($attachment); } } } /**************************************************/ /*SE NON SI SONO VERIFICATI ERRORI INVIAMO L'EMAIL*/ /**************************************************/ if($error === FALSE){ $result = $mailer->send($message); if($result>0){ $msg = "Email inviata. Presto sarai ricontattato."; } else{ $msg = "Problemi nell'invio della email!"; } } /*********************************/ /* REDIRECT ALLA PAGINA DEL FORM */ /*********************************/ $get_var = urlencode($msg); header('location: contact.php?msg=' . $get_var); exit; } ?>
Come potete notare il codice è ampiamente commentato ed autoesplicativo.
Considerazioni finali
La prima considerazione che occorre fare è che non tutti gli hosting (in particolare quelli gratuiti) consentono di inviare email in modalità SMTP (ed in particolare uno di questi è Altervista). In quel caso lo script vi andrà a generare un FATAL ERROR.
Questione piuttosto complessa riguarda l'indirizzamento delle email nella cartella di posta indesiderata: a questo proposito non esiste una soluzione definitiva. Infatti, tutto dipenderà del provider destinatario della email. Lo stesso messaggio potrebbe essere considerato spam da hotmail metre potrebbe essere considerato perfettamente valido per gmail e viceversa. Vi sono a tal proposito delle linee guida che si consiglia di seguire all'interno della documentazione ufficiale di Swiftmailer.
Infine, ponete attenzione agli allegati che vi vengono inviati tramite il vostro contact form eseguendo una scansione del file con un antivirus.
Per qualsiasi problema o dubbio non esitate a lasciare un commento.
Olimpio Romanella
Sono un appassionato di Web Developing con un particolare debole per php. Mi dedico principalmente dello sviluppo back-end ed in particolare programmazione lato server con php, sviluppo di database relazionali MySql e progettazione di CMS di piccole e medie dimensioni.
Mi avvalgo del framework javascript Jquery, utilizzando molti dei suoi plugin e nei dei miei progetti utilizzo spesso il framework MVC Codeigniter.
13 Commenti presenti
I have to agree with your statement with this issue and dfeabcgfdabc
Buongiorno.. sempre io :-P. Ho riscaricato lo script. Reinstallato, risettato e niente.. fa sempre uguale. Se invio la mail senza l allegato non arriva.. nessuna idea? grazie di nuovo..
In pratica compilando il form nei suoi campi ma tralasciando di caricare l'allegato mi dice comunque: mail inviata... solo che non arriva nessuna mail a meno che non si inserisca l'allegato..
http://www.0571foto.com/contatti/contactform/contact.php
grazie per l'aiuto ;-)
@alessio: ciao. ho risto lo script e mi sembra strano quanto dici. Mi sapresti dire quale messaggio di restituisce?
ciao ho provato ad utilizzare questo script. E' possibile che se non inserisco il file alegato non invii la mail? A me da questo problema..
@Alessia: che errore ti restituisce?
Ciao,
ho provato ad utilizzare lo script, tuttavia genera errore quando prova a caricare la pagina send.php... any ideas???
Ciao, vorrei sapere solo una cosa: ho scaricato "contact_form_with_attachment"! Dunque, ora per averlo perfettamente funzionante, mi basta curarmi del FILE DI CONFIGURAZIONE e seguire, naturalmente, tutti i tuoi preziosi consigli sulla sicurezza e le CONSIDERAZIONI FINALI ?
Grazie per il tuo cortese aiuto.
Fabio
Michela
01 February 2018 ore 10:02