Advertisement
  1. Code
  2. PHP
  3. Laravel

How to Send Emails in Laravel

Scroll to top

In this article, we're going to explore the Mail API in the Laravel web framework. Laravel uses the popular Symfony Mailer component, which is easy to use and comes with a variety of email drivers to choose from.

Later on, I'll show you an in-depth demonstration of the concepts discussed in the first half of the article.

Setting Up the Prerequisites

Laravel implements a wrapper on top of the Symfony Mailer component that makes email management very easy to configure and use at the same time. You can find the default mail settings at config/mail.php.

1
<?php
2
3
return [
4
5
    /*

6
    |--------------------------------------------------------------------------

7
    | Default Mailer

8
    |--------------------------------------------------------------------------

9
    |

10
    | This option controls the default mailer that is used to send any email

11
    | messages sent by your application. Alternative mailers may be set up

12
    | and used as needed; however, this mailer will be used by default.

13
    |

14
    */
15
16
    'default' => env('MAIL_MAILER', 'smtp'),
17
18
    /*

19
    |--------------------------------------------------------------------------

20
    | Mailer Configurations

21
    |--------------------------------------------------------------------------

22
    |

23
    | Here you may configure all of the mailers used by your application plus

24
    | their respective settings. Several examples have been configured for

25
    | you, and you are free to add your own as your application requires.

26
    |

27
    | Laravel supports a variety of mail "transport" drivers to be used while

28
    | sending an email. You will specify which one you are using for your

29
    | mailers below. You are free to add additional mailers as required.

30
    |

31
    | Supported: "smtp", "sendmail", "mailgun", "ses",

32
    |            "postmark", "log", "array"

33
    |

34
    */
35
36
    'mailers' => [
37
        'smtp' => [
38
            'transport' => 'smtp',
39
            'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
40
            'port' => env('MAIL_PORT', 587),
41
            'encryption' => env('MAIL_ENCRYPTION', 'tls'),
42
            'username' => env('MAIL_USERNAME'),
43
            'password' => env('MAIL_PASSWORD'),
44
            'timeout' => null,
45
            'auth_mode' => null,
46
        ],
47
48
        'ses' => [
49
            'transport' => 'ses',
50
        ],
51
52
        'mailgun' => [
53
            'transport' => 'mailgun',
54
        ],
55
56
        'postmark' => [
57
            'transport' => 'postmark',
58
        ],
59
60
        'sendmail' => [
61
            'transport' => 'sendmail',
62
            'path' => '/usr/sbin/sendmail -bs',
63
        ],
64
65
        'log' => [
66
            'transport' => 'log',
67
            'channel' => env('MAIL_LOG_CHANNEL'),
68
        ],
69
70
        'array' => [
71
            'transport' => 'array',
72
        ],
73
    ],
74
75
    /*

76
    |--------------------------------------------------------------------------

77
    | Global "From" Address

78
    |--------------------------------------------------------------------------

79
    |

80
    | You may wish for all emails sent by your application to be sent from

81
    | the same address. Here, you may specify a name and address that is

82
    | used globally for all emails that are sent by your application.

83
    |

84
    */
85
86
    'from' => [
87
        'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
88
        'name' => env('MAIL_FROM_NAME', 'Example'),
89
    ],
90
91
    /*

92
    |--------------------------------------------------------------------------

93
    | Markdown Mail Settings

94
    |--------------------------------------------------------------------------

95
    |

96
    | If you are using Markdown-based email rendering, you may configure your

97
    | theme and component paths here, allowing you to customize the design

98
    | of the emails. Or you may simply stick with the Laravel defaults!

99
    |

100
    */
101
102
    'markdown' => [
103
        'theme' => 'default',
104
105
        'paths' => [
106
            resource_path('views/vendor/mail'),
107
        ],
108
    ],
109
110
];

When it comes to sending emails, Laravel supports a number of drivers to choose from. As you can see, the default MAIL_DRIVER is set to smtp. So if you want to change it to something else, you need to change the MAIL_MAILER variable in the .env file, since that's where the config/mail.php file reads the mailer value.

If you are going to use the smtp driver to send emails, then you're also required to set other related settings like MAIL_HOST, MAIL_PORT, MAIL_ENCRYPTION, MAIL_USERNAME, and MAIL_PASSWORD in the .env file.

On the other hand, if you are going to use the sendmail driver, then you want to make sure that the sendmail system path is set to the correct value in the config/mail.php file.

You can also set the from address that will be used while sending emails under the from key. And finally, if you want to use Markdown-based email rendering, you can specify those settings under the markdown key.

The cherry on top is that you could also use third-party email service providers like Mailgun, Postmark, SES, and more. If you are using one of those services, you need to make sure that you set the corresponding settings in the config/services.php file.

So that was a basic introduction to the mail API related settings in Laravel. From the next section onwards, we'll go through a custom example that shows you how to send emails.

Create the Mailable Class

In this section, we'll create the mailable class, which will be used to send emails. The mailable class is responsible for sending emails using a mailer that's configured in the config/mail.php file. In fact, Laravel already provides an artisan command that allows us to create a base template.

1
php artisan make:mail DemoEmail

That should create a blank email template at app/Mail/DemoEmail.php, as shown in the following snippet.

1
<?php
2
3
namespace App\Mail;
4
5
use Illuminate\Bus\Queueable;
6
use Illuminate\Contracts\Queue\ShouldQueue;
7
use Illuminate\Mail\Mailable;
8
use Illuminate\Queue\SerializesModels;
9
10
class DemoEmail extends Mailable
11
{
12
    use Queueable, SerializesModels;
13
14
    /**

15
     * Create a new message instance.

16
     *

17
     * @return void

18
     */
19
    public function __construct()
20
    {
21
        //

22
    }
23
24
    /**

25
     * Build the message.

26
     *

27
     * @return $this

28
     */
29
    public function build()
30
    {
31
        return $this->view('view.name');
32
    }
33
}

Let's replace the contents of that file with the following.

1
<?php
2
3
namespace App\Mail;
4
5
use Illuminate\Bus\Queueable;
6
use Illuminate\Contracts\Queue\ShouldQueue;
7
use Illuminate\Mail\Mailable;
8
use Illuminate\Queue\SerializesModels;
9
10
class DemoEmail extends Mailable
11
{
12
    use Queueable, SerializesModels;
13
     
14
    /**

15
     * The demo object instance.

16
     *

17
     * @var Demo

18
     */
19
    public $demo;
20
 
21
    /**

22
     * Create a new message instance.

23
     *

24
     * @return void

25
     */
26
    public function __construct($demo)
27
    {
28
        $this->demo = $demo;
29
    }
30
 
31
    /**

32
     * Build the message.

33
     *

34
     * @return $this

35
     */
36
    public function build()
37
    {
38
        return $this->from('sender@example.com')
39
                    ->view('mails.demo')
40
                    ->text('mails.demo_plain')
41
                    ->with(
42
                      [
43
                            'testVarOne' => '1',
44
                            'testVarTwo' => '2',
45
                      ])
46
                      ->attach(public_path('/images').'/demo.jpg', [
47
                              'as' => 'demo.jpg',
48
                              'mime' => 'image/jpeg',
49
                      ]);
50
    }
51
}

There are two important methods the mailable class generally implements: __construct and build. The __construct method is used to initialize objects that you're supposed to use in the email template. On the other hand, the build method is used to initialize more email-specific values like from, view template, and attachments.

In our case, we've passed the $demo object as a constructor argument, and it's assigned to the demo public property.

In the build method, we've initialized an email-specific configuration.

  • from is used to set an email address that'll be used as a from address.
  • Using the view method, you can set the email template that will be used while sending an email using this mailable. In our case, we've set it to mails.demo, and it means that you need to create a view template file at resources/views/mails/demo.blade.php.
  • Next, the text method is used to set up the plain text version of an email template.
  • As we've just discussed, the __construct method is used to set up objects that'll be used in the email template. You can also use the with method, which allows you to set the view data of a message.
  • Next, we've used the attach method to attach an image to a message. Please make sure that the image is available at public/images/demo.jpg.

Of course, we need to create email templates that we're supposed to use while sending emails. Go ahead and create a file resources/views/mails/demo.blade.php as shown in the following snippet.

1
Hello <i>{{ $demo->receiver }}</i>,
2
<p>This is a demo email for testing purposes! Also, it's the HTML version.</p>
3
 
4
<p><u>Demo object values:</u></p>
5
 
6
<div>
7
<p><b>Demo One:</b>&nbsp;{{ $demo->demo_one }}</p>
8
<p><b>Demo Two:</b>&nbsp;{{ $demo->demo_two }}</p>
9
</div>
10
 
11
<p><u>Values passed by With method:</u></p>
12
 
13
<div>
14
<p><b>testVarOne:</b>&nbsp;{{ $testVarOne }}</p>
15
<p><b>testVarTwo:</b>&nbsp;{{ $testVarTwo }}</p>
16
</div>
17
 
18
Thank You,
19
<br/>
20
<i>{{ $demo->sender }}</i>

Also, let's create the plain text version of that file at resources/views/mails/demo_plain.blade.php.

1
Hello {{ $demo->receiver }},
2
This is a demo email for testing purposes! Also, it's the HTML version.
3
 
4
Demo object values:
5
 
6
Demo One: {{ $demo->demo_one }}
7
Demo Two: {{ $demo->demo_two }}
8
 
9
Values passed by With method:
10
 
11
testVarOne: {{ $testVarOne }}
12
testVarOne: {{ $testVarOne }}
13
 
14
Thank You,
15
{{ $demo->sender }}

So that was the mailable class at your disposal, and we're not done yet as we need to use the Mail facade to actually send emails. In the very next section, we'll explore how you can use the Mail Facade to send emails using the DemoEmail Mailable class that was just created in this section.

How to Use the Mailable Class

In this section, we'll create an example to demonstrate how you can use the Mailable class that was created in the last section.

Let's create a controller with the following command.

1
php artisan make:controller MailController

That should create a blank controller file at app/Http/Controllers/MailController.php with the following contents.

1
<?php
2
3
namespace App\Http\Controllers;
4
5
use Illuminate\Http\Request;
6
7
class MailController extends Controller
8
{
9
    //

10
}

Let's replace it with the following contents.

1
<?php
2
namespace App\Http\Controllers;
3
 
4
use App\Http\Controllers\Controller;
5
use App\Mail\DemoEmail;
6
use Illuminate\Support\Facades\Mail;
7
 
8
class MailController extends Controller
9
{
10
    public function send()
11
    {
12
        $objDemo = new \stdClass();
13
        $objDemo->demo_one = 'Demo One Value';
14
        $objDemo->demo_two = 'Demo Two Value';
15
        $objDemo->sender = 'SenderUserName';
16
        $objDemo->receiver = 'ReceiverUserName';
17
 
18
        Mail::to("receiver@example.com")->send(new DemoEmail($objDemo));
19
    }
20
}

It's important to note that we've included the Illuminate\Support\Facades\Mail Facade that will be used to send an email. In the send method, the following statement is responsible for sending an email by initializing the App\Mail\DemoEmail Mailable in the first place.

1
Mail::to("receiver@example.com")->send(new DemoEmail($objDemo));

The to method of the Illuminate\Support\Facades\Mail Facade returns an instance of the \Illuminate\Mail\PendingMail class, which already contains an appropriate mailer configured in the config/mail.php file.

And finally, we use the send method of the \Illuminate\Mail\PendingMail class that sends an actual email.

To test it, let's add an associated route in the routes/web.php file.

1
// Email related routes

2
Route::get('mail/send', 'MailController@send');

And with that in place, you can visit the https://your-laravel-site.com/mail/send URL to see if it works as expected.

On the other hand, if you want to test your email templates quickly, without sending actual emails, there's a provision in Laravel that allows you to log all outgoing emails.

To achieve that, you need to set the value of MAIL_DRIVER to log in the config/mail.php file. Next, you could run the aforementioned URL and inspect the log file to check if the email template was logged there.

If everything goes fine, you should see an email being logged to the storage/logs/laravel.log file.

That's pretty much it as far as the mail feature is concerned in Laravel, and that concludes this article as well.

Conclusion

Today, we went through the mail API that comes built into Laravel, and it supports a variety of drivers as well.

Starting with basic concepts, we implemented the mailable class that is an essential element in the mail API in Laravel as we moved on. At the end, we also tested the mailable class by creating a custom controller to see if it actually works.

If you're just getting started with Laravel or looking to expand your knowledge, site, or application with extensions, we have a variety of things you can study on Envato Market.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.