Inviare una singola email non richiede particolari attenzioni, ma nel caso in cui volessimo inviare lo stesso messaggio a una lista di più di 10.000 indirizzi email, allora dovremmo pensare ad un sistema che eviti il sovraccarico del web server, ammesso che quest'ultimo funzioni anche da server di posta.
Per ovviare a questo problema è necessario prevedere un sistema di suddivisione della lista di email, cioè suddividere la lista di indirizzi email in tanti blocchi, in modo da definire quante email inviare per volta, ed effettuare una pausa di tot secondi tra l'invio di un blocco e l'altro per non far sovraccaricare il web server.
In questo articolo vedremo come creare un'applicazione che ci consente di inviare un numero consistente di email, in particolare usando la libreria phpmailer per l'invio.
La prima cosa da fare è di disporre di un modulo web
Codice HTML
<form method="post" action="send.php?block=1">
<div>
<label>Oggetto della Email</label>
<input type="text" name="object">
</div>
<div>
<label>Testo della Email</label>
<textarea name="text" rows="3"></textarea>
</div>
<button type="submit">Invia</button>
</form>
in questo caso il modulo web è costituito solo da due campi, uno per inserire l'oggetto e l'altro per inserire il corpo del messaggio, i dati vengono inviati tramite metodo POST ad un ipotetico file send.php con una query block ugule a 1 ad indicare che la prima volta che il file send.php riceve i dati dal modulo web invierà il primo blocco di email.
Per inserire una pausa tra l'invio di un blocco di email e l'altro possiamo utilizzare un particolare meta tag che ci permetterà di effettuare il refresh della pagina in modo automatico
Codice HTML
<meta http-equiv="refresh" content="5;url=send.php?block=n">
send.php è il file per l'invio delle email, http-equiv="refresh" è l'istruzione che ci permette di aggiornare la pagina corrente del browser, l'attributo content contiene le informazioni relative al tempo di attesa prima di aggiornare la pagina, in questo caso 5 secondi (5) e l'indirizzo al quale effettuare il redirect, che in questo caso è lo stesso file send.php con una query block (url=send.php?block=n) che corrisponde al numero del blocco di email da inviare (n), tale valore è un valore dinamico che vedremo in seguito come verrà definito.
In questo modo la pagina verrà aggiornata 12 volte in un minuto (60/5), e se per esempio in ogni blocco invieeremo 50 email, in un minuto verrannno inviate 600 email (12*50), e quindi 3600 email in circa un'ora, potendo così stabilire anche un tempo stimato per l'invio di tutte le email.
Poichè dopo l'invio del primo blocco di email, il file send.php si aggiornerà dopo 5 secondi (refresh) e quindi non avremo più disponibile i dati inviati tramite POST dal modulo web, dovremo memorizzare l'oggetto e il testo del messaggio o in un cookie o in una sessione oppure un file di testo, ecc, in modo da averli disponibili anche dopo l'aggiornamento della pagina.
Ciò premesso, incominciamo a scrivere il file send.php per l'invio delle email, in particolare in questo esempio uso una sessione
Codice PHP
<?php
/* send.php */
session_start();
/* PHPMailer */
require_once '/vendor/autoload.php';
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
$phpmailer = new PHPMailer(true);
/* oggetto contenete gli indirizzi email da inviare */
$emails=[...];
if (isset($_POST['object']) && isset($_POST['text']))
{
$object = $_POST['object'];
$text = $_POST['text'];
$_SESSION['object'] = $object;
$_SESSION['text'] = $text;
}
else
{
$object = $_SESSION['object'];
$text = $_SESSION['text'];
}
/* invio 50 email per ogni blocco */
$block = $_GET['block'];
$newblock = $block + 1;
$lastEmail = $block * 50;
$firstEmail = $lastEmail - 50 + 1;
$end = 1;
$counter = 0;
/* echo "Invio da $firstEmail a $lastEmail"; */
in questa prima parte di codice l'oggetto $emails contiene tutte le email da inviare, in questo caso ho ipotizzato di evere tutti gli indirizzi email memorizzati in un array ma ovviamente posso ipotizzare di averli memorizzati in una sorgente esterna come un database, un file di testo, ecc.., tramite una condizione if verifico l'esistenza dei dati provenienti dal modulo web
- $_POST['object']
- $_POST['text']
che sono rispettivamente l'oggetto e il testo del messaggio, in caso di condizione vera li memorizzo in una sessione per poterli avere disponibili durante l'invio dei blocchi successivi al primo, recupero il valore della query block ($_GET['block']) e lo memorizzo in una variabile $block, definisco il valore del blocco successivo con la variabile $newblock, $lastEmail e $firstEmail sono rispettivamente l'ultima e la prima email del blocco corrente $end e $counter sono due variabili inizializzate con valore 1 e 0 rispettivamente.
Successivamente andiamo a scrivere il codice per l'invio delle email con phpmailer
Codice PHP
<?php
/* send.php */
/*
......
......
*/
$phpmailer->isSMTP();
$phpmailer->Host = 'smtp1.example.com';
$phpmailer->SMTPAuth = true;
$phpmailer->Username = 'user@example.com';
$phpmailer->Password = 'secret';
$phpmailer->SMTPSecure = 'tls';
$phpmailer->Port = 587;
$phpmailer->FromName = "Mailer";
$phpmailer->From = "from@example.com";
/* se è previsto codice html nel corpo del messaggio */
/* $phpmailer->IsHTML(true); */
$phpmailer->Subject = "$object";
$phpmailer->Body = "$text";
Host, Username, Password, SMTPSecure, Port, FromName, From sono i dati relativi all'account email con il quale inviamo le email.
Codice PHP
<?php
/* send.php */
/*
.......
.......
*/
for ($i = 0;$i < count($emails);$i++)
{
$counter = $counter + 1;
if (($counter >= $firstEmail) && ($counter <= $lastEmail))
{
$end = 0;
$recipient = $emails[$i];
$phpmailer->AddAddress($recipient);
$phpmailer->Send();
$phpmailer->clearAddresses();
}
}
if ($end)
{
header("Location: success.php");
exit();
}
?>
<html>
<head>
<meta http-equiv="refresh" content="5;url=send.php?block=<?=$newblock?>">
</head>
<body>
<!-- Contenuto body -->
</body>
</html>
la condizione if nel ciclo for ci consente di inviare le email del blocco corrente, quando la variabile $end sarà vera allora evremmo inviato tutte le email e visualizzeremo un messaggio apposito in un ipotetico file success.php, notare inoltre la variabile $newblock valorizzata dinamicamente per poter passare al blocco successivo.