Sending email
A site needs to send messages: a registration confirmation, a notice about a new comment, a password reset link. CodeIgniter has a built-in email service for that. You tell it the mail server, then set the recipient, subject and text in a controller.
Settings
The settings live in the app/Config/Email.php class. The details of your mail server go into .env:
email.fromEmail = 'blog@example.com'
email.fromName = 'Blog'
email.protocol = smtp
email.SMTPHost = smtp.example.com
email.SMTPUser = blog@example.com
email.SMTPPass = secret
email.SMTPPort = 587
email.SMTPCrypto = tlsSMTP is the way of sending messages through a mail server. The server address, port and password are given by the mail provider. fromEmail and fromName are the default sender address and name.
The first message
// app/Controllers/Home.php
public function mail(): string
{
$email = service('email');
$email->setTo('anna@example.com');
$email->setSubject('Hello');
$email->setMessage('This message was sent from CodeIgniter.');
if ($email->send()) {
return 'Message sent';
}
return 'Message not sent';
}The service('email') function returns the service object. Add the route $routes->get('mail', 'Home::mail'); and open /mail — a message arrives at the address and the page reports the result. The send() method returns true on success.
Message methods
| Method | What it sets |
|---|---|
setFrom('blog@example.com', 'Blog') | The sender, if it differs from the settings |
setTo('anna@example.com') | The recipient |
setCC(), setBCC() | A copy and a blind copy |
setReplyTo() | The reply address |
setSubject() | The subject |
setMessage() | The text |
attach($path) | An attachment |
A message from a view
An HTML message is best built from a view. Create the file app/Views/emails/new_post.php:
<!-- app/Views/emails/new_post.php -->
<h1>A new post in the blog</h1>
<p><?= esc($post['title']) ?></p>
<p><a href="<?= url_to('posts.show', $post['id']) ?>">Read</a></p>In the controller the view is turned into a string with view():
$email = service('email');
$email->setMailType('html');
$email->setTo('anna@example.com');
$email->setSubject('New post: ' . $post['title']);
$email->setMessage(view('emails/new_post', ['post' => $post]));
$email->send();setMailType('html') says the message contains markup, not plain text. A link in a message must be full, with the domain — url_to() returns exactly that.
An attachment
$email->attach(WRITEPATH . 'uploads/report.pdf');WRITEPATH is the path to the writable folder. The method is called before send().
If the message did not go out
The printDebugger() method shows the reason:
if (! $email->send()) {
log_message('error', $email->printDebugger(['headers']));
}The mail server's answer ends up in the log in the writable/logs folder — the lesson about logging covers it.
Common mistake
Sending a message takes seconds, and the visitor waits for the page all that time. One message after registration is acceptable, but a mailing to hundreds of subscribers must not be started from a controller: the request will time out. Such mailings are moved to a spark command run by the server's scheduler — the next lesson is about that.