Отправка почты
Сайту нужно отправлять письма: подтверждение регистрации, уведомление о новом комментарии, ссылку для сброса пароля. В CodeIgniter для этого есть встроенная служба email. Ей указывают почтовый сервер, а затем в контроллере задают адресата, тему и текст.
Настройки
Настройки лежат в классе app/Config/Email.php. Данные своего почтового сервера пишут в .env:
email.fromEmail = 'blog@example.com'
email.fromName = 'Блог'
email.protocol = smtp
email.SMTPHost = smtp.example.com
email.SMTPUser = blog@example.com
email.SMTPPass = secret
email.SMTPPort = 587
email.SMTPCrypto = tlsSMTP — способ отправки писем через почтовый сервер. Адрес сервера, порт и пароль выдаёт почтовая служба. fromEmail и fromName — адрес и имя отправителя по умолчанию.
Первое письмо
// app/Controllers/Home.php
public function mail(): string
{
$email = service('email');
$email->setTo('anna@example.com');
$email->setSubject('Привет');
$email->setMessage('Это письмо отправлено из CodeIgniter.');
if ($email->send()) {
return 'Письмо отправлено';
}
return 'Письмо не отправлено';
}Функция service('email') возвращает объект службы. Добавьте маршрут $routes->get('mail', 'Home::mail'); и откройте /mail — на адрес придёт письмо, а страница сообщит результат. Метод send() возвращает true при успехе.
Методы письма
| Метод | Что задаёт |
|---|---|
setFrom('blog@example.com', 'Блог') | Отправителя, если он отличается от настроек |
setTo('anna@example.com') | Получателя |
setCC(), setBCC() | Копию и скрытую копию |
setReplyTo() | Адрес для ответа |
setSubject() | Тему |
setMessage() | Текст |
attach($path) | Вложение |
Письмо из шаблона
Письмо в формате HTML удобно собирать из шаблона. Создайте файл app/Views/emails/new_post.php:
<!-- app/Views/emails/new_post.php -->
<h1>Новая статья в блоге</h1>
<p><?= esc($post['title']) ?></p>
<p><a href="<?= url_to('posts.show', $post['id']) ?>">Читать</a></p>В контроллере шаблон превращают в строку функцией view():
$email = service('email');
$email->setMailType('html');
$email->setTo('anna@example.com');
$email->setSubject('Новая статья: ' . $post['title']);
$email->setMessage(view('emails/new_post', ['post' => $post]));
$email->send();setMailType('html') сообщает, что в письме разметка, а не простой текст. Ссылка в письме должна быть полной, с доменом, — url_to() возвращает именно такую.
Вложение
$email->attach(WRITEPATH . 'uploads/report.pdf');WRITEPATH — путь к папке writable. Метод вызывают до send().
Если письмо не ушло
Причину показывает метод printDebugger():
if (! $email->send()) {
log_message('error', $email->printDebugger(['headers']));
}Ответ почтового сервера попадёт в журнал в папке writable/logs — о нём рассказывает урок о журнале.
Частая ошибка
Отправка письма занимает секунды, и посетитель всё это время ждёт ответа страницы. Одно письмо после регистрации — допустимо, но рассылку сотням подписчиков из контроллера запускать нельзя: запрос оборвётся по времени. Такие рассылки выносят в команду spark, которую запускает планировщик сервера, — этому посвящён следующий урок.