Может войдёшь?
Черновики Написать статью Профиль

Работа с e-mail

перевод документация 5.х

  1. 1. Введение
    1. 1.1. Требования для драйверов
  2. 2. Создание отправляемых объектов
  3. 3. Написание отправляемых объектов
    1. 3.1. Настройка отправителя
    2. 3.2. Настройка представления
    3. 3.3. Данные представления
    4. 3.4. Вложения
    5. 3.5. Строчные вложения
  4. 4. Отправка почты
  5. 5. Очереди отправки
  6. 6. Почта и локальная разработка
  7. 7. События
Этот перевод актуален для англоязычной документации на (ветка 5.3) , (ветка 5.2) , (ветка 5.1) и (ветка 5.0). Опечатка? Выдели и нажми Ctrl+Enter.

Введение

Laravel предоставляет простой API к популярной библиотеке SwiftMailer c драйверами для SMTP, Mailgun, Mandrill (для Laravel 5.2 и ранее), SparkPost, Amazon SES, функции PHP mail, и sendmail, поэтому вы можете быстро приступить к рассылке почты с помощью локального или облачного сервиса на ваш выбор.

Требования для драйверов

Драйверы на основе API, такие как Mailgun и SparkPost, зачастую работают проще и быстрее, чем SMTP-серверы. По возможности лучше использовать именно их. Для работы таких драйверов необходима HTTP-библиотека Guzzle, которую можно установить через менеджер пакетов Composer:

shcomposer require guzzlehttp/guzzle

Драйвер Mailgun

Для использования драйвера Mailgun установите Guzzle и задайте для параметра driver значение mailgun в конфигурационном файле config/mail.php. Затем проверьте, что в конфигурационном файле config/services.php есть следующие параметры:

PHP
'mailgun' => [
  
'domain' => 'your-mailgun-domain',
  
'secret' => 'your-mailgun-key',
],
+ 5.2 5.1 5.0

добавлено в 5.2 () 5.1 () 5.0 ()

Драйвер Mandrill

Для использования драйвера Mandrill установите Guzzle и задайте для параметра driver значение mandrill в конфигурационном файле config/mail.php. Затем проверьте, что в конфигурационном файле config/services.php есть следующие параметры:

PHP
'mandrill' => [
  
'secret' => 'your-mandrill-key',
],
+ 5.3 5.2

добавлено в 5.3 () 5.2 ()

Драйвер SparkPost

Для использования драйвера SparkPost установите Guzzle и задайте для параметра driver значение sparkpost в конфигурационном файле config/mail.php. Затем проверьте, что в конфигурационном файле config/services.php есть следующие параметры:

PHP
'sparkpost' => [
  
'secret' => 'your-sparkpost-key',
],

Драйвер SES

Чтобы использовать драйвер Amazon SES, сначала установите Amazon AWS SDK для PHP. Вы можете установить эту библиотеку, добавив следующую строку в раздел require файла composer.json и выполнив команду shcomposer update:

PHP
"aws/aws-sdk-php""~3.0"

Затем задайте для параметра driver значение ses в конфигурационном файле config/mail.php и проверьте, что в конфигурационном файле config/services.php есть следующие параметры:

PHP
'ses' => [
    
'key' => 'your-ses-key',
    
'secret' => 'your-ses-secret',
    
'region' => 'ses-region',  // например, us-east-1
],
+ 5.3

добавлено в 5.3 ()

Создание отправляемых объектов

В Laravel каждый отправляемый приложением тип email-сообщения представлен «отправляемым» классом. Эти классы хранятся в папке app/Mail. Если у вас нет такой папки, она будет сгенерирована при создании первого отправляемого класса командой shmake:mail:

shphp artisan make:mail OrderShipped

Написание отправляемых объектов

Все настройки отправляемого класса происходят в методе PHPbuild(). В этом методе вы можете вызывать различные другие методы, такие как PHPfrom(), PHPsubject(), PHPview() и PHPattach(), для настройки содержимого и доставки email-сообщения.

Настройка отправителя

Используя метод PHPfrom()

Сначала давайте рассмотрим настройку отправителя email. Другими словами — от кого будет приходить email. Есть два способа настроить отправителя. Первый — с помощью метода PHPfrom() в методе PHPbuild() вашего отправляемого класса:

PHP
/**
 * Создание сообщения.
 *
 * @return $this
 */
public function build()
{
  return 
$this->from('example@example.com')
              ->
view('emails.orders.shipped');
}

Используя глобальный адрес from

Если ваше приложение использует одинаковый адрес отправителя для всех своих email-сообщений, то будет излишне вызывать метод PHPfrom() в каждом генерируемом классе. Вместо этого вы можете указать глобальный адрес from в файле настроек config/mail.php. Этот адрес будет использован тогда, когда в отправляемом классе не указан никакой другой адрес отправителя:

PHP
'from' => ['address' => 'example@example.com''name' => 'App Name'],

Настройка представления

В методе PHPbuild() отправляемого класса вы можете использовать метод PHPview() для указания шаблона для построения содержимого email-сообщения. Поскольку обычно для построения содержимого всех email-сообщений используется Blade-шаблон, вам доступна вся мощь и всё удобство шаблонизатора Blade для создания HTML-кода ваших email-сообщений:

PHP
/**
 * Создание сообщения.
 *
 * @return $this
 */
public function build()
{
  return 
$this->view('emails.orders.shipped');
}

Вы можете создать папку resources/views/emails для размещения всех ваших email-шаблонов, или любую другую папку в каталоге resources/views.

Текстовые email-сообщения

Если вы хотите определить текстовую версию вашего email, используйте метод PHPtext(). Подобно методу PHPview() метод PHPtext() принимает имя шаблона, который будет использован для построения содержимого email-сообщения. Вы можете определить обе версии вашего сообщения — HTML и текстовую:

PHP
/**
 * Создание сообщения.
 *
 * @return $this
 */
public function build()
{
  return 
$this->view('emails.orders.shipped')
              ->
text('emails.orders.shipped_plain');
}

Данные представления

Через общедоступные свойства

Обычно необходимо передать какие-либо данные в представление, которые можно использовать при построении HTML-кода email-сообщения. Есть два способа сделать данные доступными для вашего представления. Первый — любое общедоступное (public) свойство, определённое в вашем отправляемом классе, автоматически станет доступным для представления. Например, вы можете передать данные в конструктор вашего отправляемого класса и поместить эти данные в общедоступные свойства, определённые в классе:

PHP
<?php

namespace App\Mail;

use 
App\Order;
use 
Illuminate\Bus\Queueable;
use 
Illuminate\Mail\Mailable;
use 
Illuminate\Queue\SerializesModels;

class 
OrderShipped extends Mailable
{
  use 
QueueableSerializesModels;

  
/**
   * Экземпляр заказа.
   *
   * @var Order
   */
  
public $order;

  
/**
   * Создание нового экземпляра сообщения.
   *
   * @return void
   */
  
public function __construct(Order $order)
  {
    
$this->order $order;
  }

  
/**
   * Создание сообщения.
   *
   * @return $this
   */
  
public function build()
  {
    return 
$this->view('emails.orders.shipped');
  }
}

Когда данные помещены в общедоступное свойство, они автоматически станут доступны в вашем представлении, и вы можете обращаться к ним как к любым другим данным Blade-шаблонах:

PHP
<div>
  
Price: {{ $order->price }}
</
div>

Через метод PHPwith()

Если вы хотите настроить формат данных вашего email-сообщения до того, как они будут отправлены в шаблон, вы можете вручную передать данные в представление методом PHPwith(). Вы будете по-прежнему передавать данные через конструктор отправляемого класса, но вам надо поместить эти данные в свойства protected или private, чтобы данные не были автоматически доступны шаблону. Затем при вызове метода PHPwith() передайте массив данных, которые должны быть доступны шаблону:

PHP
<?php

namespace App\Mail;

use 
App\Order;
use 
Illuminate\Bus\Queueable;
use 
Illuminate\Mail\Mailable;
use 
Illuminate\Queue\SerializesModels;

class 
OrderShipped extends Mailable
{
  use 
QueueableSerializesModels;

  
/**
   * Экземпляр заказа.
   *
   * @var Order
   */
  
protected $order;

  
/**
   * Создание нового экземпляра сообщения.
   *
   * @return void
   */
  
public function __construct(Order $order)
  {
    
$this->order $order;
  }

  
/**
   * Создание сообщения.
   *
   * @return $this
   */
  
public function build()
  {
    return 
$this->view('emails.orders.shipped')
                ->
with([
                  
'orderName' => $this->order->name,
                  
'orderPrice' => $this->order->price,
                ]);
  }
}

После передачи данных в метод PHPwith() они автоматически станут доступны для вашего представления, и вы сможете обращаться к ним как к любым другим данным Blade-шаблонах:

PHP
<div>
  
Price: {{ $orderPrice }}
</
div>

Вложения

+ 5.3

добавлено в 5.3 ()

Для добавления к письму вложений используйте метод PHPattach() в методе PHPbuild() отправляемого класса. Метод PHPattach() принимает первым аргументом полный путь к файлу:

PHP
/**
 * Создание сообщения.
 *
 * @return $this
 */
public function build()
{
  return 
$this->view('emails.orders.shipped')
              ->
attach('/path/to/file');
}
+ 5.2 5.1 5.0

добавлено в 5.2 () 5.1 () 5.0 ()

Для добавления к письму вложений служит метод PHPattach() на объекте PHP$message, переданном в ваше замыкание. Метод PHPattach() принимает первым аргументом полный путь к файлу:

PHP
Mail::send('emails.welcome'$data, function ($message) {
  
//

  
$message->attach($pathToFile);
});

При добавлении файлов можно указать их MIME-тип и/или отображаемое имя, передав массив вторым аргументом метода PHPattach():

+ 5.3

добавлено в 5.3 ()

PHP
/**
 * Создание сообщения.
 *
 * @return $this
 */
public function build()
{
  return 
$this->view('emails.orders.shipped')
              ->
attach('/path/to/file', [
                
'as' => 'name.pdf',
                
'mime' => 'application/pdf',
              ]);
}
+ 5.2 5.1 5.0

добавлено в 5.2 () 5.1 () 5.0 ()

PHP
$message->attach($pathToFile, ['as' => $display'mime' => $mime]);
+ 5.3

добавлено в 5.3 ()

Вложение «сырых» данных

Метод PHPattachData() можно использовать для добавления «сырой» строки байтов в качестве вложения. Например, вы можете использовать этот метод, если вы сгенерировали PDF в памяти и хотите прикрепить его к письму, не записывая на диск. Метод PHPattachData() принимает «сырые» данные первым аргументом, имя файла вторым аргументом, и массив параметров третьим аргументом:

PHP
/**
 * Создание сообщения.
 *
 * @return $this
 */
public function build()
{
  return 
$this->view('emails.orders.shipped')
              ->
attachData($this->pdf'name.pdf', [
                
'mime' => 'application/pdf',
              ]);
}
+ 5.2

добавлено в 5.2 ()

Метод PHPattachData() можно использовать для добавления «сырой» строки байтов в качестве вложения. Например, вы можете использовать этот метод, если вы сгенерировали PDF в памяти и хотите прикрепить его к письму, не записывая на диск:

PHP
$message->attachData($pdf'invoice.pdf');

$message->attachData($pdf'invoice.pdf', ['mime' => $mime]);

Строчные вложения

Обычно добавление строчных вложений — утомительное занятие, однако Laravel делает его проще, позволяя вам добавлять изображения и получать соответствующие CID.

Строчные вложения — файлы, не видимые получателю в списке вложений, но используемые внутри HTML-тела сообщения; CID — уникальный идентификатор внутри данного сообщения, используемый вместо URL в таких атрибутах, как srcприм. пер.

Для вставки строчного изображения используйте метод PHPembed() на переменной PHP$message в шаблоне вашего email. Laravel автоматически делает переменную PHP$message доступной для всех шаблонов ваших сообщений, поэтому вам не надо передавать их вручную:

+ 5.3

добавлено в 5.3 ()

PHP
<body>
  
Вот какая-то картинка:

  <
img src="{{ $message->embed($pathToFile) }}">
</
body>
+ 5.2 5.1 5.0

добавлено в 5.2 () 5.1 () 5.0 ()

PHP
<body>
  Вот какая-то картинка:

  <img src="<?php echo $message->embed($pathToFile); ?>">
</body>

Вставка файла из потока данных
Если у вас уже есть строка сырых данных для вставки в шаблон email-сообщения, вы можете использовать метод PHPembedData() на переменной PHP$message:

+ 5.3

добавлено в 5.3 ()

PHP
<body>
  
А вот картинкаполученная из строки с данными:

  <
img src="{{ $message->embedData($data$name) }}">
</
body>
+ 5.2 5.1 5.0

добавлено в 5.2 () 5.1 () 5.0 ()

PHP
<body>
  А вот картинка, полученная из строки с данными:

  <img src="<?php echo $message->embedData($data$name); ?>">
</body>

Отправка почты

+ 5.3

добавлено в 5.3 ()

Для отправки сообщений используйте метод PHPto() фасада Mail. Метод PHPto() принимает email-адрес, экземпляр пользователя или коллекцию пользователей. Если вы передадите объект или коллекцию объектов, то обработчик почты автоматически использует их свойства email и name для настройки получателей email-сообщения, поэтому эти атрибуты должны быть доступны в ваших объектах. После настройки получателей вы можете передать экземпляр вашего отправляемого класса в метод PHPsend():

PHP
<?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
{
  
/**
   * Доставка данного заказа.
   *
   * @param  Request  $request
   * @param  int  $orderId
   * @return Response
   */
  
public function ship(Request $request$orderId)
  {
    
$order Order::findOrFail($orderId);

    
// Доставка заказа...

    
Mail::to($request->user())->send(new OrderShipped($order));
  }
}

Само собой при отправке сообщений вы можете указать не только получателей to. Вы можете задать получателей to, cc и bcc одним сцепленным вызовом метода:

PHP
Mail::to($request->user())
    ->
cc($moreUsers)
    ->
bcc($evenMoreUsers)
    ->
send(new OrderShipped($order));
+ 5.2 5.1 5.0

добавлено в 5.2 () 5.1 () 5.0 ()

Laravel позволяет хранить почтовые сообщения в представлениях. Например, вы можете расположить свои сообщения в папке emails, создав её в папке resources/views.

Для отправки сообщения используется метод PHPsend() фасада Mail. Этот метод принимает три аргумента. Первый — имя представления, которое содержит текст сообщения. Второй — массив данных, передаваемых в представление. Третий — функция-замыкание, получающая экземпляр сообщения, и позволяющая вам настроить различные параметры сообщения, такие как получатели, тема и т.д.:

PHP
<?php

namespace App\Http\Controllers;

use 
Mail;
use 
App\User;
use 
Illuminate\Http\Request;
use 
App\Http\Controllers\Controller;

class 
UserController extends Controller
{
  
/**
   * Отправка пользователю напоминания по e-mail.
   *
   * @param  Request  $request
   * @param  int  $id
   * @return Response
   */
  
public function sendEmailReminder(Request $request$id)
  {
    
$user User::findOrFail($id);

    
Mail::send('emails.reminder', ['user' => $user], function ($m) use ($user) {
      
$m->from('hello@app.com''Your Application');

      
$m->to($user->email$user->name)->subject('Your Reminder!');
    });
  }
}

Поскольку в этом примере мы передаём массив с ключом user, мы можем отобразить имя пользователя в нашем представлении с помощью такого PHP-кода:

PHP
<?php echo $user->name?>

Переменная PHP$message всегда передаётся в представления и позволяет вам прикреплять вложения. Поэтому вам не стоит передавать одноимённую переменную с данными для представления.

Построение сообщения

Как уже было сказано, третий аргумент метода PHPsend() — замыкание, которое позволяет указать различные настройки для самого сообщения. С помощью этого замыкания вы можете задать другие атрибуты сообщения, такие как явная рассылка на несколько адресов, скрытая рассылка на несколько адресов, и т.д.:

PHP
Mail::send('emails.welcome'$data, function ($message) {
  
$message->from('us@example.com''Laravel');

  
$message->to('foo@example.com')->cc('bar@example.com');
});

Ниже приведён список доступных методов для экземпляра построителя сообщения PHP$message:

PHP
$message->from($address$name null);
$message->sender($address$name null);
$message->to($address$name null);
$message->cc($address$name null);
$message->bcc($address$name null);
$message->replyTo($address$name null);
$message->subject($subject);
$message->priority($level);
$message->attach($pathToFile, array $options = []);

// Прикрепить файл из сырой $data string...
$message->attachData($data$name, array $options = []);

// Получить низкоуровневый экземпляр сообщения SwiftMailer...
$message->getSwiftMessage();

Экземпляр сообщения, передаваемый замыканию метода PHPMail::send(), наследует класс сообщения SwiftMailer, что позволяет вам вызывать любые методы этого класса для создания своего сообщения.

Отправка простого текста

По умолчанию ожидается, что передаваемое в метод PHPsend() представление содержит HTML. Но передавая первым аргументом метода PHPsend() массив, вы можете указать простое текстовое представление вдобавок к HTML-представлению:

PHP
Mail::send(['html.view''text.view'], $data$callback);

А если вам надо отправить только простой текст, вы можете указать это при помощи ключа text в массиве:

PHP
Mail::send(['text' => 'view'], $data$callback);

Отправка сырых строк

Если вам надо отправить непосредственно простую строку, используйте метод PHPraw():

PHP
Mail::raw('Text to e-mail', function ($message) {
  
//
});

Очереди отправки

Помещение сообщения в очередь отправки

Из-за того, что отправка сообщений может сильно повлиять на время обработки запроса, многие разработчики помещают их в очередь на фоновую отправку. Laravel позволяет легко делать это, используя единое API очередей. Для помещения сообщения в очередь просто используйте метод PHPqueue() фасада Mail после настройки получателей сообщения:

+ 5.3

добавлено в 5.3 ()

PHP
Mail::to($request->user())
    ->
cc($moreUsers)
    ->
bcc($evenMoreUsers)
    ->
queue(new OrderShipped($order));
+ 5.2 5.1 5.0

добавлено в 5.2 () 5.1 () 5.0 ()

PHP
Mail::queue('emails.welcome'$data, function ($message) {
  
//
});

Этот метод автоматически позаботится о помещении задачи в очередь, поэтому сообщение будет отправлено в фоне. Не забудьте настроить механизм очередей перед использованием данной возможности.

Задержка отправки сообщения

Вы можете задержать отправку сообщения на нужное число секунд методом PHPlater(). Первый аргумент метода — экземпляр DateTime, указывающий, когда необходимо отправить сообщение:

+ 5.3

добавлено в 5.3 ()

PHP
$when Carbon\Carbon::now()->addMinutes(10);

Mail::to($request->user())
    ->
cc($moreUsers)
    ->
bcc($evenMoreUsers)
    ->
later($when, new OrderShipped($order));
+ 5.2 5.1 5.0

добавлено в 5.2 () 5.1 () 5.0 ()

PHP
Mail::later(5'emails.welcome'$data, function ($message) {
  
//
});

Помещение сообщения в определённую очередь

+ 5.3

добавлено в 5.3 ()

Поскольку все генерируемые командой shmake:mail отправляемые классы используют типаж Illuminate\Bus\Queueable, вы можете вызывать методы PHPonQueue() и PHPonConnection() на любом экземпляре отправляемого класса, что позволяет вам указывать название подключения и имя очереди для сообщения:

PHP
$message = (new OrderShipped($order))
                ->
onConnection('sqs')
                ->
onQueue('emails');

Mail::to($request->user())
    ->
cc($moreUsers)
    ->
bcc($evenMoreUsers)
    ->
queue($message);

Помещение в очередь по умолчанию

Если у вас есть отправляемые классы, которые необходимо всегда помещать в очередь, вы можете реализовать контракт ShouldQueue в классе. Тогда даже при вызове метода PHPsend() отправляемый объект будет помещаться в очередь, поскольку он реализует контракт ShouldQueue:

PHP
use Illuminate\Contracts\Queue\ShouldQueue;

class 
OrderShipped extends Mailable implements ShouldQueue
{
  
//
}
+ 5.2 5.1 5.0

добавлено в 5.2 () 5.1 () 5.0 ()

Если вы хотите поместить сообщение в определённую очередь отправки, то используйте методы PHPqueueOn() и PHPlaterOn():

PHP
Mail::queueOn('queue-name''emails.welcome'$data, function ($message) {
  
//
});

Mail::laterOn('queue-name'5'emails.welcome'$data, function ($message) {
  
//
});

Почта и локальная разработка

На стадии разработки приложения обычно предпочтительно отключить доставку отправляемых сообщений. В Laravel есть несколько способов «отключить» реальную отправку почтовых сообщений во время разработки.

Драйвер Log

Вместо отправки сообщений почтовый драйвер log будет заносить все сообщения в ваши журналы для возможности их просмотра. Подробнее о настройке различных окружений для приложения читайте в документации по настройке.

+ 5.0

добавлено в 5.0 ()

Вы можете либо вызывать метод PHPMail::pretend(), либо установить параметр pretend в значение PHPtrue в файле настроек config/mail.php. Когда это сделано, сообщения будут записываться в журнал вашего приложения, вместо отправки получателю.

Универсальный получатель

Другой вариант — задать универсального получателя для всех сообщений от фреймворка. при этом все сообщения, генерируемые вашим приложением, будут отсылаться на заданный адрес, вместо адреса, указанного при отправке сообщения. Это можно сделать с помощью параметра to в файле настроек config/mail.php:

PHP
'to' => [
      
'address' => 'example@example.com',
      
'name' => 'Example'
],

Mailtrap

И наконец, вы можете использовать сервис MailTrap и драйвер smtp для отправки ваших почтовых сообщений на фиктивный почтовый ящик, где вы сможете посмотреть их при помощи настоящего почтового клиента. Преимущество этого вариант в том, что вы можете проверить то, как в итоге будут выглядеть ваши почтовые сообщения, при помощи средства для просмотра сообщений Mailtrap.

События

+ 5.3 5.2

добавлено в 5.3 () 5.2 ()

Laravel генерирует событие непосредственно перед отправкой почтовых сообщений. Учтите, это событие возникает при отправке сообщения, а не при помещении его в очередь. Вы можете зарегистрировать слушатель для этого события в своём EventServiceProvider:

PHP
/**
 * Отображения слушателя событий для приложения.
 *
 * @var array
 */
protected $listen = [
  
'Illuminate\Mail\Events\MessageSending' => [
    
'App\Listeners\LogSentMessage',
  ],
];
+ 5.1 5.0

добавлено в 5.1 () 5.0 ()

Laravel генерирует событие mailer.sending непосредственно перед отправкой почтовых сообщений. Учтите, это событие возникает при отправке сообщения, а не при помещении его в очередь. Вы можете зарегистрировать слушатель события в своём EventServiceProvider:

PHP
/**
 * Регистрация всех остальных событий для вашего приложения.
 *
 * @param  \Illuminate\Contracts\Events\Dispatcher  $events
 * @return void
 */
public function boot(DispatcherContract $events)
{
  
parent::boot($events);

  
$events->listen('mailer.sending', function ($message) {
    
//
  
});
}

Комментарии (8)

Levon

Здравствуйте ! У меня один небольшой вопрос. Можно ли средствами Laravel 5 отправить e-mail с помощью сервиса Mandrill, при этом используя шаблоны сервиса Mandrill, а не шаблоны blade?

Буду очень благодарен за помощь.

Sawa4

Блин так и не понял ничего... как это все работает((

A62407100

Заробрались ? Подскажите порядок действий ?

otjog

Какой момент именно вам не понятен?

olko

поддерживаю комментатора выше

A62407100

Смотрел видосы по установке Auth — стандартный компонент регистрации , делал так как и они , но письма не отправляются , кроме писем при сбросе пароля. Грешил на сервак почтовый , но письма при сбросе приходят , а при регистрации нет . Подскажите как решили , по пунктам , можно видео или статьью записать .

crash

Вылезла ошибка при использование сервиса Mailgun. cURL error 60: SSL certificate problem: unable to get local issuer certificate. Где мне отключить проверку на сертификацию?

Malashko

Здравствуйте.
Только вникаю в Laravel, не судите строго.

Данные из формы добавляются в БД (на этом этапе все без проблем) далее подключается модель отправки почты и появляется ошибка "Too few arguments to function App\Mail\Question::__construct()", вроде скопировал все с документации, но все равно вылазят ошибки.

Вот тут весь алгоритм отправки письма: https://pastebin.com/1iARkmzL
Подскажите, что я делаю не так?

Написать комментарий

Разметка: ? ?

Авторизуйся, чтобы прокомментировать.