Sending Email with Swift Mailer

Tweet

Sending emails programmatically is a common task that programmers must deal with often. Although you can use PHP’s native functions, they can be too low-level, especially when you want to attach one or more files to your message. If you don’t want to use the native functions, or if you want to send mail using an object-oriented approach, then this is the article for you. I’ll introduce you to Swift Mailer, a powerful component-based library that let’s you send emails easily.

Started in 2005, Swift Mailer is a library that provides several classes that allow you to send emails from within your PHP scripts or web applications. Swift Mailer has some requirements, however they’re minimal; the library needs PHP 5.2 or higher with the SPL extension and a minimum memory limit of 8MB.

Citing the official documentation, installing Swift Mailer is trivial. Usually it’s just a case of uploading the extracted source files to your web server. The simplest way to install the library is through PEAR or uploading the files using an FTP.

Installing from the PEAR channel is just a matter of type two commands:

pear channel-discover pear.swiftmailer.org
pear install swift/swift

The second method is probably the easiest one if you’re on a shared hosting and you don’t have access to the command shell. Just download the library from the official website and upload the lib folder.

The Swift Mailer Family of Classes

Swift Mailer is made of more than 150 classes and interfaces grouped together in several components. Each of them have a specific purpose.

  • Mailer: The mailer, which is realized by the Swift_Mailer class, is the central class in the library and the one that actually sends the email through the method send(). Its constructor accepts an instance of a class that implements the interface Swift_Transport which allows you to send email using a custom SMTP.
  • Transporters: They implement the interface Swift_Transport and their scope is to communicate with a service to deliver an email message. The main classes are Swift_SmtpTransport which uses the SMTP protocol, Swift_SendmailTransport which communicates with a local sendmail executable, and Swift_MailTransport that relies on the PHP native mail() function.
  • MIME Entities: This is a key component in the library. The class you’ll use to specify the receiver, the subject, the body and so on, called Swift_Message is made of several entities that are grouped together. Two example of entities are the attachments and the email header.
  • Encoders: This component isn’t something you’ll deal with because it acts behind the scenes. There are two types of Encoders: Base64 and Quoted-Printable. Their goal is to transform the contents into a format that conforms to RFC specifications.
  • Plugins: These are used to extend Swift Mailer’s basic functionality. Some of the plugins are AntiFlood, which allows you to limit the number of messages sent during a single SMTP connection, Logger, used to log what’s going on during the send process, and Decorator, an amazing plugin that allows you to use an email template and change just a few differences in the email text.

A Basic Example

With me so far? Good. Now that you’ve got an idea of how the components are organized in the library, let’s get our hands dirty and see how to take advantage of the power and flexibility of Swift Mailer. In this first and very simple example, I’ll show you the creation of an email that has two recipients, a subject, and a plain-text body. Once created, it’ll be sent to the recipients.

The following code uses three of the classes mentioned in the previous section: Swift_MailTransport, Swift_Mailer and Swift_Message. In addition, note the first line of the code, the require_once which pulls in Swift Mailer’s autoloader which is needed to use the library.

<?php
require_once 'lib/swift_required.php';

// Create the mail transport configuration
$transport = Swift_MailTransport::newInstance();

// Create the message
$message = Swift_Message::newInstance();
$message->setTo(array(
  "aurelioderosa@gmail.com" => "Aurelio De Rosa",
  "info@audero.it" => "Audero"
));
$message->setSubject("This email is sent using Swift Mailer");
$message->setBody("You're our best client ever.");
$message->setFrom("account@bank.com", "Your bank");

// Send the email
$mailer = Swift_Mailer::newInstance($transport);
$mailer->send($message);

As you can see, Swift_MailTransport is used to create an instance of a transport layer which will use the native PHP mail() function. Then I created a Swift_Message instance which you can think of as the email object. In the following lines I set the recipients using the setTo() method, the email subject using setSubject(), the email body using setBody(), and the sender using the setFrom() method. With the layer defined and the email created, it’s time to actually send the email, which is done using the send() method of the Swift_Mailer class.

An Example with Attachments

There is no doubt that attachments are a staple of today’s email systems. No one can live without them. This slightly more complicated example will show you how to send an email that not only has an attachment but also other features.

  • Two additional receivers, one in CC and the second in BCC using setCc() and setBcc().
  • One attachment retrieved from disk using the attach() method.
  • A custom SMTP configuration using the Swift_SmtpTransport class.
  • Know what recipients have not received the email using the second parameter of the send() method.
<?php
require_once 'lib/swift_required.php';

// Create the SMTP configuration
$transport = Swift_SmtpTransport::newInstance("smtp.audero.it", 25);
$transport->setUsername("Username");
$transport->setPassword("Password");

// Create the message
$message = Swift_Message::newInstance();
$message->setTo(array(
   "aurelioderosa@gmail.com" => "Aurelio De Rosa",
   "info@audero.it" => "Audero"
));
$message->setCc(array("a.derosa@audero.it" => "Aurelio De Rosa"));
$message->setBcc(array("boss@bank.com" => "Bank Boss"));
$message->setSubject("This email is sent using Swift Mailer");
$message->setBody("You're our best client ever.");
$message->setFrom("account@bank.com", "Your bank");
$message->attach(Swift_Attachment::fromPath("path/to/file/file.zip"));

// Send the email
$mailer = Swift_Mailer::newInstance($transport);
$mailer->send($message, $failedRecipients);

// Show failed recipients
print_r($failedRecipients);

I used a different transport layer, an SMTP one that is set using the Swift_SmtpTransport class. It accepts two parameters: the SMTP server and the connection port. You use the instance to set an appropriate username and password to access the server using the setUsername() and setPassword() methods. Then, just like the first example, I created an Swift_Message object and set the recipients, the subject, and so on. However, this time I also took advantage of the setCc() and the setBcc() methods that, as you might guess, allow you to set carbon copy and blind carbon copy recipients.

The key method of this example is attach() which attaches a file taken from the hard disk using the static method fromPath() that takes the path to the file you want to attach as its parameter. Note that this time I also print the number of failed recipients retrieved using the send() method’s second parameter.

Using a Template

The third and final example shows you how to use the Decorator plugin, ideal for things like sending newsletters to your subscribers. It allows you to send the same email to several recipients having small differences such as the recipient name inside the email body. The plugin will look inside the template (the body) and will replace the placeholders with the set values.

To use the plugin, you first need to register it using the registerPlugin() method and then build and use an array of replacement values. In the following code I’ll put two placeholders, username and transactions, which will be programmatically replaced by values referring to the user’s email.

<?php
require_once 'lib/swift_required.php';

// Usually you want to replace the following static array
// with a dynamic one built retrieving users from the database
$users = array(
  array(
    "fullname" => "Aurelio De Rosa",
    "operations" => 100,
    "email" => "aurelioderosa@gmail.com"
  ),
  array(
    "fullname" => "Audero",
    "operations" => 50,
    "email" => "info@audero.it"
  )
);

// Create the replacements array
$replacements = array();
foreach ($users as $user) {
  $replacements[$user["email"]] = array (
    "{fullname}" => $user["fullname"],
    "{transactions}" => $user["operations"]
  );
}

// Create the mail transport configuration
$transport = Swift_MailTransport::newInstance();

// Create an instance of the plugin and register it
$plugin = new Swift_Plugins_DecoratorPlugin($replacements);
$mailer = Swift_Mailer::newInstance($transport);
$mailer->registerPlugin($plugin);

// Create the message
$message = Swift_Message::newInstance();
$message->setSubject("This email is sent using Swift Mailer");
$message->setBody("You {fullname}, are our best client ever thanks " .
    " to the {transactions} transactions you made with us.");
$message->setFrom("account@bank.com", "Your bank");

// Send the email
foreach($users as $user) {
  $message->setTo($user["email"], $user["fullname"]);
  $mailer->send($message);
}

The Decorator plugin constructor accepts one parameter: an array of values to replace the placeholders. Each value of this array uses the user’s email for its key and a sub-array that contains placeholder-replacement pairs. This is exactly the aim of the $replacements array. In the example above, as placeholders I used a string inside two brackets (i.e. {fullname}) but you can use whatever you want. This time, I haven’t set all the recipients in the same statement as before and I used a for loop. This is done because the plugin intercepts the sending process, reads the recipient email, and replaces the placeholders using the values of the replacement array.

Conclusion

In this article I showed how you can easily send emails using Swift Mailer. This is a very powerful library that, as you’ve seen, allows you to do a lot of things using an OOP approach. Of course Swift Mailer has a lot of other methods and classes I’ve not covered in this article. You can study up on them in the official documentation, but this should be enough to get you started sending emails without hassle.

Image via Fotolia

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Chris Emerson

    What does this offer that PHPMailer doesn’t?

    • http://www.audero.it/ Aurelio De Rosa

      Probably nothing. SwiftMailer is the one I use, so I wrote about this one.

      • Chris Emerson

        Fair enough. I don’t know either all that well so was wondering what the key differences were and which one I would use!

  • http://www.propertyandturkey.com yusuf

    what is wrong with php mail() function you can add attachments and send as html emails anyway

    • http://www.audero.it/ Aurelio De Rosa

      Of course you can but it’s a real pain. With Swift Mailer you have a lot of high-level methods to do in a single line what in raw php would require a lot of code. Moreover you can use a Object Oriented approach which is a good thing.

  • Les

    It’s a good library in the sense of it has been written well enough internally however the public API sucks. When ever I see Class::function() style initialisation I smell something bad, if you are competent at PHP object orientation I would take the best parts of it and use your own public API.

    • Sebastiaan Stok

      This was done with a good reason, If you actually look at the code you will see Swiftmailer uses a DI for ease of use. In the past using the library required a lot of boilerplate to even create a message!! So Chris Corbyn created a DI for ease of use, but if want to you can still use the underlaying classes and construct them yourself ;) just remember that it will require a lot of coding to even create a message then.

      The difference with PHPMailer and Swiftmailer is that Swiftmailer is more decoupled and feature ridge, PHPMailer consists of one big class (with an extra class for STP) while Swiftmailer consists of multiple (smaller) classes.

      If your looking for good replacement for the mail() hassle PHPMailer is good enough, if your looking for something more and also need to deal with big attachments Swiftmailer is a better choice. PS. As of 4.3.0 Swiftmailer will also support S/MIME for signing and encrypting messages.

      • John M

        @Sebastiaan Stok – Thanks for your comment as I was wondering the same myself. I have been using PHPMailer for years without any issue but have recently been told I should try out Swiftmailer in place. Do you see any high intrinsic value in making the switch?

  • http://www.fuzzfree.com Antonis FuzzFree

    I use PHPMailer without any issue all these years and has all awesome features (attachments, embeds, dkim, smtp keep alive etc)… I find it easier to work with than SwiftMailer… In the past I had read around that SwiftMailer is supposed to be faster, I do not know what’s the case now with latest versions… but again, never needed to build the next mailchimp :)

  • Anthony

    I used swift mailer years ago and it was very easy to utilize with my limited php knowledge. I used it for a photography client who needed people to submit pictures via email from a form.

    With it I created a php form that:
    1. Only allowed image and zip file formats.
    2. Renamed the uploaded files so it was the firstname/lastname of the user: firstnameLastname.jpg
    3. Mailed the files to my client along with information they put in the form.
    4. I also implemented a captcha.

    Glad to know this is still around and people still use it.

  • http://www.xoogu.com/ Dave

    Would you recommend swift mailer over the PEAR Mail packages?

  • yaser

    Is there any limit to $useres size? and wath is $users["operations"] can set it allways as 50

  • l

    without Using a Template

    41 $message->setFrom(“account@bank.com”, “Your bank”);
    42
    43 // Send the email
    44 foreach($users as $user) {
    45 $message->setTo($user["email"], $user["fullname"]);
    $message->setBody(“You {fullname}, are our best client ever thanks ” .
    40 ” to the {transactions} transactions you made with us.”);
    46 $mailer->send($message);
    47 }