Отправка почты
Сайт отправляет письма: подтверждение регистрации, уведомление о новом комментарии, сообщение из формы обратной связи. В Yii за это отвечает компонент Yii::$app->mailer. В стандартном проекте он работает через пакет yiisoft/yii2-symfonymailer, который уже установлен.
Где настраивается почта
Компонент описан в config/web.php:
// config/web.php
'components' => [
'mailer' => [
'class' => \yii\symfonymailer\Mailer::class,
'viewPath' => '@app/mail',
'useFileTransport' => true,
],
],Пока useFileTransport равно true, письма никуда не уходят, а сохраняются файлами в папке runtime/mail. Это режим для разработки: можно проверять письма, не рискуя отправить их настоящим людям.
Первое письмо
// controllers/PostController.php
public function actionNotify(): string
{
$sent = Yii::$app->mailer->compose()
->setFrom('blog@example.com')
->setTo('anna@example.com')
->setSubject('Новая статья в блоге')
->setTextBody('В блоге появилась новая статья.')
->send();
return $sent ? 'Письмо отправлено' : 'Ошибка отправки';
}Откройте /post/notify — в папке runtime/mail появится файл с расширением .eml. Его открывает почтовая программа или текстовый редактор. Метод send() возвращает true при успехе.
Письмо из шаблона
Шаблоны писем лежат в папке mail. Создайте mail/new-post.php:
<?php
// mail/new-post.php
use yii\helpers\Html;
use yii\helpers\Url;
?>
<h1><?= Html::encode($post->title) ?></h1>
<p>В блоге появилась новая статья.</p>
<p><?= Html::a('Читать', Url::to(['post/view', 'id' => $post->id], true)) ?></p>Имя шаблона и данные передают в compose():
Yii::$app->mailer->compose('new-post', ['post' => $post])
->setFrom('blog@example.com')
->setTo('anna@example.com')
->setSubject('Новая статья: ' . $post->title)
->send();Письмо получит разметку из шаблона, обёрнутую в общий макет писем mail/layouts/html.php. Второй аргумент Url::to() — true — делает адрес полным: в письме относительная ссылка /posts/5 не сработает.
Методы письма
| Метод | Что задаёт |
|---|---|
setFrom('blog@example.com') | Отправителя |
setTo(['anna@example.com', 'ivan@example.com']) | Одного или нескольких получателей |
setSubject('Тема') | Тему |
setTextBody('Текст') | Текстовое содержимое |
setHtmlBody('<b>Текст</b>') | Содержимое с разметкой |
attach('/path/to/file.pdf') | Вложение |
Настоящая отправка
На сервере отключают файловый режим и указывают почтовый сервер:
'mailer' => [
'class' => \yii\symfonymailer\Mailer::class,
'viewPath' => '@app/mail',
'useFileTransport' => false,
'transport' => [
'dsn' => 'smtp://user:password@smtp.example.com:587',
],
],Строка dsn содержит имя пользователя, пароль, адрес и порт сервера SMTP — их выдаёт почтовая служба.
Частая ошибка
Письма «не приходят», хотя send() возвращает true, — значит, остался включённым useFileTransport, и они копятся в runtime/mail. Проверьте эту настройку на сервере. Обратная ошибка опаснее: отключить её на компьютере разработчика с копией настоящей базы — и тестовые письма уйдут настоящим пользователям.