My name is
Jurgens du Toit.
Technology and Solving Problems are my passion. I'm a South African that loves my wife, life, and coding.
I'm writing a book!
The Swiftmailer library comes with a nifty feature where mails can be spooled to disk and sent later asynchronously instead of mailing them immediately. This results in quicker response times from your scripts, and by extension happier users. This post will explain how to set it up outside of the Symfony 2 framework.
Swiftmailer defines a number of Transports with which mails can be sent. A common one
Swift_SmtpTransport. To spool mails, we’ll use the
the initial sending, and then still use
Swift_SmtpTransport for the background sending.
The following comes (with some changes) from a post in the Swiftmailer Google Group:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <?php // Setup the spooler, passing it the name of the folder to spool to $spool = new Swift_FileSpool(__DIR__ . "/spool"); // Setup the transport and mailer $transport = Swift_SpoolTransport::newInstance($spool); $mailer = Swift_Mailer::newInstance($transport); // Create a message $message = Swift_Message::newInstance('Excellent Subject') ->setFrom(array('[email protected]' => 'John Doe')) ->setTo(array('[email protected]')) ->setBody('spool messages !!!'); // Send the message $result = $mailer->send($message); echo "SPOOLED $result emails";
This will spool the email to specified folder instead of sending it. At this stage, the actual sending of the mail hasn’t happened yet. You will need to flush the spooled messages using a cron or background script that calls the flashQueue method to do that.
The background script will use the
Swift_SmtpTransport to send the spooled mails:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <?php //create an instance of the spool object pointing to the right position in the filesystem $spool = new Swift_FileSpool(__DIR__."/spool"); //create a new instance of Swift_SpoolTransport that accept an argument as Swift_FileSpool $transport = Swift_SpoolTransport::newInstance($spool); //now create an instance of the transport you usually use with swiftmailer //to send real-time email $realTransport = Swift_SmtpTransport::newInstance( "smtp.gmail.com", "465", "ssl" ) ->setUsername("username") ->setPassword("password"); $spool = $transport->getSpool(); $spool->setMessageLimit(10); $spool->setTimeLimit(100); $sent = $spool->flushQueue($realTransport); echo "SENT $result emails";
And that’s it. All that’s left now is to call the background script periodically using something like cron.