Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

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

Сайт отправляет письма: подтверждение регистрации, уведомление о новом комментарии, сообщение из формы обратной связи. В 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. Проверьте эту настройку на сервере. Обратная ошибка опаснее: отключить её на компьютере разработчика с копией настоящей базы — и тестовые письма уйдут настоящим пользователям.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.