Implement mail configuration, preview and sending in Larravel
brief introduction
Larave is based on SwiftMailer The library provides a set of clean and refreshing mail APIs. Larravel is a service provider for SMTP, Mailgun, SparkPost, Amazon SES and PHP mail
Functions, and sendmail
Provides a driver that allows you to quickly send mail through local or cloud services. Pre knowledge of mail drive
API based drivers such as Mailgun and SparkPost are usually simpler and faster than SMTP servers, so if possible, use these services as much as possible. All API drivers require that the application has installed the Guzzle HTTP library. You can install it through the Composer package manager:
composer require guzzlehttp/guzzle
Mailgun driver
To use the Mailgun driver (the first 10000 mails of Mailgun are free of charge, and the subsequent charges are charged), first install Guzzle, and then install the configuration file config/mail.php
Set in driver
Options are mailgun
。 Next, verify the configuration file config/services.php
The following options are included:
'mailgun' => [ 'domain' => 'your-mailgun-domain', 'secret' => 'your-mailgun-key', ],
SparkPost Drive
To use the SparkPost driver, first install Guzzle, and then click the configuration file config/mail.php
Set in driver
The option value is sparkpost
。 Next, verify the configuration file config/services.php
The following options are included:
'sparkpost' => [ 'secret' => 'your-sparkpost-key', ],
SES drive
To use the Amazon SES driver (charging), first install the Amazon AWS PHP SDK. You can add the following composer.json
Filed require
Part then run composer update
Command to install the library:
"aws/aws-sdk-php": "~3.0"
Next, set the configuration file config/mail.php
In driver
Options are ses
。 Then, verify the configuration file config/services.php
The following options are included:
'ses' => [ 'key' => 'your-ses-key', 'secret' => 'your-ses-secret', 'region' => 'ses-region', // e.g. us-east-1 ],
Note: The bad news is that none of the above drivers is applicable to applications developed by domestic developers for domestic users, so they can be ignored.
Generate Mailable Class
In Larravel, every email sent by the application can be expressed as a "mailable" class, which is stored in the app/Mail
catalog. If you don't see this directory, don't worry, it will be used by you make:mail
Generated when the command creates the first mailable class:
php artisan make:mail OrderShipped
The template code generated by default is as follows:
Write Mailable Class
All mailable configurations are in the build
Method. In this method, you can call multiple methods, such as from
、 subject
、 view
and attach
To configure the content and sending of messages. Configure sender
use from
method
Let's take a look at the configuration of the mail sender, or, in other words, who the mail comes from. There are two ways to configure the sender. The first way is in the mailable class build
Called in method from
method:
/** *Build message * * @return $this */ public function build() { return $this->from(' example@example.com ') ->view('emails.orders.shipped'); }
Use global from
address
However, if your application uses the same sending address in all mails, call it in each generated mailable class from
The method is cumbersome. Instead, you can use the config/mail.php
Specify a global sending address in the. This address can be used when no other sending address is specified in all mailable classes (that is, as the default sender):
'from' => ['address' => ' example@example.com ', 'name' => 'App Name'],
Configure View
You can mail build
Method view
Method to specify which view template to use when rendering message content. Because each message usually uses Blade template To render the content, you can use all the functions provided by the Blade template engine when building the email HTML:
/** *Build message * * @return $this * @translator laravelacademy.org */ public function build() { return $this->view('emails.orders.shipped'); }
Note: You can create a resources/views/emails
Directory to store all mail templates. Of course, you can also place mail templates in resources/views
Any other location under the directory.
Plain text message
If you want to define a plain text message, you can use text
method. and view
In the same way, text
Method receives a template name used to render mail content. You can define both plain text messages and HTML messages:
/** *Build message * * @return $this */ public function build() { return $this->view('emails.orders.shipped') ->text('emails.orders.shipped_plain'); }
View Data
Through public properties
Usually, we need to pass some data to the HTML view of the rendered mail for use. There are two ways to transfer data to the view. The first is that the public attribute of the mailable class automatically takes effect in the view. For example, we pass the data to the constructor of the mailable class and set the data to the public attribute of the class:
<? php namespace App\Mail; use App\Order; use Illuminate\Bus\Queueable; use Illuminate\Mail\Mailable; use Illuminate\Queue\SerializesModels; class OrderShipped extends Mailable { use Queueable, SerializesModels; /** *Order instance * * @var Order */ public $order; /** *Create a new message instance * * @return void */ public function __construct(Order $order) { $this->order = $order; } /** *Build message * * @return $this */ public function build() { return $this->view('emails.orders.shipped'); } }
After the data is set to the public attribute, it will automatically take effect in the view, so you can access them as you access other data in the Blade template:
Price: {{ $order->price }}
adopt with
method
If you want to customize the format of mail data before sending the data to the template, you can use with
Method to manually transfer data to the view. Generally, you still need to pass data through the mailable constructor, but this time you need to set the data to protected
or private
Property, so that these data will not automatically take effect in the view. Then, when the with
Method, the array data is passed to the method so that the data takes effect in the view template:
<? php namespace App\Mail; use App\Order; use Illuminate\Bus\Queueable; use Illuminate\Mail\Mailable; use Illuminate\Queue\SerializesModels; class OrderShipped extends Mailable { use Queueable, SerializesModels; /** *Order instance * * @var Order */ protected $order; /** *Create a new instance * * @return void */ public function __construct(Order $order) { $this->order = $order; } /** *Build message * * @return $this */ public function build() { return $this->view('emails.orders.shipped') ->with([ 'orderName' => $this->order->name, 'orderPrice' => $this->order->price, ]); } }
Data via with
After the method is transferred to the view, it will automatically take effect in the view, so you can also access the transferred data as you access other data in the Blade template:
Price: {{ $orderPrice }}
enclosure
To add an attachment to an email, you can click the build
Method attach
method. attach
Method receives the complete file path as the first parameter:
/** *Build message * * @return $this */ public function build() { return $this->view('emails.orders.shipped') ->attach('/path/to/file'); }
When attaching files to messages, you can also pass an array as attach
Method to specify the file display name or MIME type:
/** *Build message * * @return $this */ public function build() { return $this->view('emails.orders.shipped') ->attach('/path/to/file', [ 'as' => 'name.pdf', 'mime' => 'application/pdf', ]); }
Native Data Attachment
attachData
Method can be used to add a native byte string as an attachment. If you want to generate a PDF in memory and add it to an email as an attachment without saving it to disk, you can use this method. attachData
The method receives data bytes as the first parameter, the file name as the second parameter, and the optional array as the third parameter:
/** *Build message * * @return $this */ public function build() { return $this->view('emails.orders.shipped') ->attachData($this->pdf, 'name.pdf', [ 'mime' => 'application/pdf', ]); }
Inline attachment
Nesting an inline image into an email is usually cumbersome. For this reason, Laravel provides a convenient way to attach an image to an email and obtain the corresponding CID. To embed an inline image, use it in the email view $message
On variable embed
Method. Larave injects in all mail views $message
Variable and make it effective automatically, so you don't need to care about how to manually transfer this variable to the view: Here is an image: <img src="{{ $message->embed($pathToFile) }}">
Note: $message
Variables are not applicable to markdown messages.
Embed native data attachments
If you already have a native data string that you want to embed in the mail template, you can use $message
On variable embedData
method:
Here is an image from raw data: <img src="{{ $message->embedData($data, $name) }}">
Customize SwiftMailer messages
Mailable
On the base class withSwiftMessage
Method allows you to register a callback that can be called by the native SwiftMailer message instance before sending a message. This gives us the opportunity to customize messages before sending them:
/** * Build the message. * * @return $this */ public function build() { $this->view('emails.orders.shipped'); $this->withSwiftMessage(function ($message) { $message->getHeaders() ->addTextHeader('Custom-Header', 'HeaderValue'); }); }
Markdown mail class
Markdown mail messages allow you to use preset templates and mail notification components in mailable classes. Because these messages are written in Markdown format, Laravel can also render high color, responsive HTML templates for them, and automatically generate plain text copies. Generate Markdown mail class
To generate a mailable class with a corresponding Markdown template, you can use the Artisan command make:mail
Time band --markdown
Options:
php artisan make:mail OrderShipped --markdown=emails.orders.shipped
Then, configure the mailable build
Method, use markdown
Method substitution view
method. markdown
Method receives the name of the Markdown template and an optional array data in effect in the template:
/** *Build message * * @return $this */ public function build() { return $this->from(' example@example.com ') ->markdown('emails.orders.shipped'); }
Write Markdown message
The Markdown mail class uses the Blade component and Markdown syntax in combination, so that you can easily build mail messages without breaking away from the Laravel preset components:
@component('mail::message') # Order Shipped Your order has been shipped! @component('mail::button', ['url' => $url]) View Order @endcomponent Thanks,
{{ config('app.name') }} @endcomponent
Note: Don't use extra indentation when writing Markdown emails. Markdown parsers will render the indentation into code blocks.
Button components
The button component renders a centered button link. This component receives two parameters, url
And optional color
, supported colors are blude
, green
and red
。 You can add any number of button components to the message:
@component('mail::button', ['url' => $url, 'color' => 'green']) View Order @endcomponent
PANEL AS
The panel component renders the given text block into a panel with a faint background color to distinguish it from the surrounding messages. For text blocks requiring attention:
@component('mail::panel') This is the panel content. @endcomponent
Table Components
The table component allows you to convert a Markdown table into an HTML table. This component receives the Markdown table as its content. Table column alignment supports the use of the default Markdown table column alignment syntax:
@component('mail::table') | Laravel | Table | Example | | ------------- |:-------------:| --------:| | Col 2 is | Centered | $10 | | Col 3 is | Right-Aligned | $20 | @endcomponent
Custom Components
You can export all Markdown mail components to your own application for customization, using Artisan commands vendor:publish
To publish laravel-mail
Resource tag:
php artisan vendor:publish --tag=laravel-mail
This command will issue the Markdown mail component to resources/views/vendor/mail
catalog. mail
Directory contains html
and markdown
Directory, and each subdirectory contains all its own valid components. You can edit these components according to your own needs.
Custom CSS
After exporting components, resources/views/vendor/mail/html/themes
The directory will contain a default default.css
File, you can customize CSS in this file, so that the HTML style of Markdown mail messages will be automatically adjusted.
If you want to build a new theme for Markdown components, just click html/themes
Write a new CSS file in the directory and modify it mail
Profile's theme
Option.
Preview the message in the browser
When designing the template of an email, it is convenient to quickly preview the rendered email like a normal Blade template. Therefore, Laravel allows you to return mailable classes directly from routing closures or controllers. When the mailable class returns, it will be rendered and displayed in the browser, so that you can quickly preview it without actually sending an email to view:
Route::get('/mailable', function () { $invoice = App\Invoice::find(1); return new App\Mail\InvoicePaid($invoice); });
Send Mail
To send a message, use the Mail
Facade On to
method. to
Method receives the mailbox address, user instance, or user collection as parameters. If objects or object collections are delivered, mail will automatically use them when setting mail recipients email
and name
Property, so make sure these properties are valid on the corresponding class in advance. After specifying the recipient, deliver an instance of the mailable class to send
method:
<? php namespace App\Http\Controllers; use App\Order; use App\Mail\OrderShipped; use Illuminate\Http\Request; use Illuminate\Support\Facades\Mail; use App\Http\Controllers\Controller; class OrderController extends Controller { /** *Process incoming orders * * @param Request $request * @param int $orderId * @return Response * @translator laravelacademy.org */ public function ship(Request $request, $orderId) { $order = Order::findOrFail($orderId); //Process Order Mail::to($request->user())->send(new OrderShipped($order)); } }
Of course, sending email messages is not limited to specifying a single recipient. You can set "to", "cc" and "bcc" through a single method chain call:
Mail::to($request->user()) ->cc($moreUsers) ->bcc($evenMoreUsers) ->send(new OrderShipped($order));
Mail Queue
Mail Message Queue
Because sending mail messages may significantly extend the response time of applications, many developers choose to send the mail to the queue and send it in the background. Larvel can use the built-in Unified Queue API To realize this function. To push mail messages to the queue, you can use the Mail
On the facade queue
method:
Mail::to($request->user()) ->cc($moreUsers) ->bcc($evenMoreUsers) ->queue(new OrderShipped($order));
This method automatically pushes the mail task to the queue for sending in the background. Of course, you need to use this feature before Configure Queue 。
Delay Message Queuing
If you want to delay the sending of mail messages in the queue, you can use later
method. later
The first parameter of the method receives a DateTime
Instance to indicate the mail sending time:
$when = Carbon\Carbon::now()->addMinutes(10); Mail::to($request->user()) ->cc($moreUsers) ->bcc($evenMoreUsers) ->later($when, new OrderShipped($order));
Push to the specified queue
By passing make:mail
All mailable classes generated by the command use Illuminate\Bus\Queueable
Trait, so you can call the onQueue
and onConnection
Method to specify the connection and queue name for the message:
$message = (new OrderShipped($order)) ->onConnection('sqs') ->onQueue('emails'); Mail::to($request->user()) ->cc($moreUsers) ->bcc($evenMoreUsers) ->queue($message);
Default Queue
If your mailable class always wants to be pushed to the queue, you can implement it on this class ShouldQueue
Covenants. This way, even if you call send
Method, the mailable class will still be pushed to the queue because it implements the contract:
use Illuminate\Contracts\Queue\ShouldQueue; class OrderShipped extends Mailable implements ShouldQueue { // }
Mail&Local Development
When developing email sending applications in the local environment, you may not really want to send email to a valid email address, but just want to do a test. To this end, Laravel provides several ways to "cancel" the actual sending of mail.
Log driven
One solution is to use log
Mail driven. The driver writes all mail information to the log file for viewing. If you want to know more about the application configuration of each environment, check Configuration Document 。
General configuration
Another solution provided by Laravel is to set a universal recipient for all mails sent by the framework. In this way, all emails generated by the application will be sent to the specified address instead of the address specified by the actual sending email. This can be done by config/mail.php
Set in to
Options to implement:
'to' => [ 'address' => ' example@example.com ', 'name' => 'Example' ],
Mailtrap
Finally, you can use Mailtrap Services and smtp
Drive to send mail information to a "virtual" mailbox. This method allows you to view the final mail in the Mailtrap message viewer.
event
Larave will trigger two events before sending the mail message, MessageSending
The event is triggered before the message is sent, MessageSent
The event is triggered after the message is sent. It should be noted that these two events are triggered before and after the mail is sent, rather than pushed to the queue EventServiceProvider
Register the corresponding event listener in:
/** * The event listener mappings for the application. * * @var array */ protected $listen = [ 'Illuminate\Mail\Events\MessageSending' => [ 'App\Listeners\LogSendingMessage', ], 'Illuminate\Mail\Events\MessageSent' => [ 'App\Listeners\LogSentMessage', ], ];