cult3

Sending Email with Laravel 4

Apr 14, 2014

Table of contents:

  1. Getting set up
  2. Sending email
  3. Queuing email
  4. Delaying email
  5. Developing and Testing using email
  6. Conclusion

An extremely common requirement of modern web applications is the ability to send email. The need to send email ranges from resetting passwords to delivering receipts. In any case, sending email usually ends up being a pretty critical requirement in just about every type of web application these days.

A couple of years ago, sending email could be a bit of a headache, however these days you can be up and running with email in your application in just a couple of hours.

In today’s tutorial I’m going to look at sending email in Laravel 4.

Getting set up

Laravel’s mailer implementation is built on the excellent SwiftMailer package. You can think of SwiftMailer as an abstraction between actually sending the email and what you write in PHP. By using SwiftMailer, Laravel already takes a huge amount of the headache of trying to send email through your application.

As with a lot of the driver based components of Laravel, the mailer class has a configuration file that can located at app/config/mail.php. In this file you will find a number of configuration options that you will need to use in order to send email through your chosen mechanism. Personally I use SendGrid, so sending email is as simple as filling in the username and password.

Sending email

Now that we’ve got everything configured we can start sending email. As with all Laravel components, the mailer class can be used through a facade, in this case Mail.

The basic way of sending an email through Laravel is to use the send method:

Mail::send("emails.welcome", $data, function ($message) {
    //
});

The first argument passed to the send method is the name of the email. Normally you would store your emails in the same way you store your view files as an email is essentially the same as a view file. This means that emails.welcome refers to a file called welcome.blade.php under the views/emails directory.

The second argument is the data that you want to make available to your email. This is exactly the same as passing data to a view. So if you wanted to pass the name of the person you are sending this email to, you would make sure it was in the $data variable.

And the third option is a closure with an instance of $message. This allows you to specify a couple of different things on the email such as who to send it to and the subject of the message:

Mail::send("emails.welcome", $data, function ($message) {
    $message
        ->to("name@domain.com", "Philip Brown")
        ->subject("Welcome to Cribbb!");
});

If you want to pass data to be used in conjunction with the $message instance, you should pass it using the use keyword on the closure.

Mail::send("emails.welcome", $data, function ($message) use ($user) {
    $message->to($user->email, $user->name)->subject("Welcome to Cribbb!");
});

If you remember back to What are PHP Lambdas and Closures?, closures can access variables outside the scope of what they were created.

If you want to dig into the source code of the $message instance to see what is available to you, take a look at this file.

Queuing email

One of the bad things about sending emails in applications is that it can make the page hang.

For example, whenever a new user signs up you would like to send them a confirmation welcome email. However, when the new user submits their details, they are greeted with a page that hangs due to sending the email. That’s not a very good first impression!

Instead, a better solution would be to add the email to a background queue. This means that the request won’t send the email immediately. Instead, the email will be delegated to a background task that will send the email when it reaches the top of the queue. This is particularly useful if certain actions in your application trigger multiple emails.

To queue an email, rather than sending it straight away, you can use the queue method on the mailer class:

Mail::queue("emails.welcome", $data, function ($message) use ($user) {
    $message->to($user->email, $user->name)->subject("Welcome to Cribbb!");
});

I haven’t covered Laravel’s excellent queue system so far in this series, but I definitely will in the coming weeks. For now, if you want to get started with queues in your application, take a look at IronMQ.

Delaying email

Another useful method on the mailer class is the ability to send email later. For example, when a user signs up to your application, you might not want to immediately send them an email. Instead you can queue the email to be delivered after a preset amount of time.

For example,

Mail::later(3600, "emails.welcome", $data, function ($message) use ($user) {
    $message->to($user->email, $user->name)->subject("Welcome to Cribbb!");
});

In the example above, the welcome email would not be sent for 3600 seconds (1 hour) after the user has signed up. This would be a good way to not bombard the new user straight away, but instead give them a little nudge once they have started to explore your product.

Developing and Testing using email

An interesting problem with sending email as part of your application is, how do you deal with unit tests? You wouldn’t want email be sent out whenever you ran your unit tests as this would be really annoying.

Laravel has a nice little configuration option that allows you to set the mailer class to “pretend” to send email. This means instead of actually sending the email, it will go to your log file instead.

You have two options for setting the mailer class to pretend mode. First you can simply call the pretend method on the class:

Mail::pretend();

Secondly, you can set the pretend configuration option in app/config/mail.php to true. This is probably a better solution because it will cover your arse if you forget to call the method in your tests for the entire environment.

Conclusion

The one consistent thing with people who use the internet is email. Not everyone uses, Twitter, Facebook or IM, but everyone uses email.

Email is a really important component in just about any web application. It’s almost hard to think of any type of application that wouldn’t require email in some form or another.

Dealing with sending email really should not be a headache. Email will be a critical aspect of your application for your customers and for your success. Dealing with sending email in Laravel is exactly how it should be, simple.

This is a series of posts on building an entire Open Source application called Cribbb. All of the tutorials will be free to web, and all of the code is available on GitHub.

Philip Brown

@philipbrown

© Yellow Flag Ltd 2024.