Email Class
The Email class composes and sends MIME emails via PHP’s built-in mail()
function. It supports plain text and HTML bodies, multiple To / CC / BCC
recipients, reply-to addresses, file attachments, priority flags, and a
fluent chainable interface so every setter returns $this.
Loading
Load the library inside your controller:
<?php
$this->call->library('email');
Once loaded it is available as $this->email.
Basic Usage
Every setter returns $this, so calls can be chained:
<?php
$this->email
->sender('no-reply@example.com', 'My App')
->recipient('user@example.com')
->subject('Welcome to My App')
->email_content('Hello, thanks for signing up!')
->send();
Or called individually:
<?php
$this->email->sender('no-reply@example.com', 'My App');
$this->email->recipient('user@example.com');
$this->email->subject('Welcome');
$this->email->email_content('Hello!');
$this->email->send();
Sender
Set the From address and an optional display name.
<?php
// Address only
$this->email->sender('no-reply@example.com');
// Address with display name
$this->email->sender('no-reply@example.com', 'My Application');
Parameter |
Description |
Required |
|---|---|---|
|
Valid email address |
Yes |
|
Name shown in the From field (e.g. |
No |
Note
An Exception is thrown if the address fails validation.
The display name is passed through filter_header() to strip newlines
and high-byte characters, preventing header injection attacks.
Recipients — To, CC, BCC
To
Add one or more primary recipients. Calling recipient() multiple times
builds a list — duplicates are silently ignored.
<?php
$this->email->recipient('alice@example.com');
$this->email->recipient('bob@example.com');
CC (Carbon Copy)
Recipients in the CC list receive the email and can see each other’s addresses.
<?php
$this->email->cc('manager@example.com');
$this->email->cc('team@example.com');
BCC (Blind Carbon Copy)
Recipients in the BCC list receive the email but are hidden from all other recipients.
<?php
$this->email->bcc('audit@example.com');
Note
send() throws an Exception if no To recipients have been added.
Method |
Description |
Duplicates |
|---|---|---|
|
Add a To recipient |
Silently ignored |
|
Add a CC recipient |
Silently ignored |
|
Add a BCC recipient |
Silently ignored |
Subject
<?php
$this->email->subject('Your order has shipped');
Note
An Exception is thrown if the subject is empty. The value is passed
through filter_header() to strip newlines and prevent header injection.
Email Content
Set the body and its type. The default type is 'plain'.
Plain text
<?php
$this->email->email_content('Hello, your account is ready.');
HTML
<?php
$this->email->email_content('
<h1>Welcome!</h1>
<p>Your account has been created.</p>
<p><a href="https://example.com/login">Log in here</a></p>
', 'html');
HTML shortcut
html() is a convenience alias for email_content($content, 'html'):
<?php
$this->email->html('<h1>Welcome!</h1><p>Thanks for joining.</p>');
Parameter |
Default |
Description |
|---|---|---|
|
— |
The body of the email. Lines are automatically wrapped at 70 characters
using MIME-compliant |
|
|
|
Note
The charset for HTML emails defaults to config_item('charset').
Override it per-message with charset().
Priority
Set the email priority flag. This controls the X-Priority,
X-MS-Priority, and Importance headers.
<?php
$this->email->priority(1); // High
$this->email->priority(3); // Normal (default)
$this->email->priority(5); // Low
Value |
Label |
Notes |
|---|---|---|
|
High |
Most email clients show a red exclamation mark |
|
High |
— |
|
Normal |
Default — no special indicator shown |
|
Low |
— |
|
Low |
Most email clients show a blue down-arrow |
Charset
Override the character set used for HTML emails on a per-message basis:
<?php
$this->email->charset('iso-8859-1');
If not called, the charset defaults to config_item('charset') (typically utf-8).
Attachments
Attach one or more files by providing their absolute server path. Duplicates are silently ignored.
<?php
// Single attachment
$this->email->attachment(APPPATH . 'uploads/invoice.pdf');
// Multiple attachments (chained)
$this->email
->attachment(APPPATH . 'uploads/invoice.pdf')
->attachment(APPPATH . 'uploads/receipt.pdf');
Attachments are base64-encoded and sent as multipart/related MIME parts.
The MIME type and filename are detected automatically.
Note
An Exception is thrown if the path is empty or the file does not exist
on disk. This is a change from the original behaviour where missing files
were silently skipped — explicit errors prevent silent data loss.
Charset, Charset & State Reset
Reset for re-use
Call reset() to clear all state and reuse the same instance for a new
email without reloading the library:
<?php
// Send first email
$this->email->sender('no-reply@example.com')
->recipient('alice@example.com')
->subject('Hello Alice')
->email_content('Hi Alice!')
->send();
// Reset and send a second email
$this->email->reset()
->sender('no-reply@example.com')
->recipient('bob@example.com')
->subject('Hello Bob')
->email_content('Hi Bob!')
->send();
Accessors
These read-only methods are useful for logging, testing, or conditional logic:
<?php
echo $this->email->get_sender(); // 'no-reply@example.com'
print_r($this->email->get_recipients()); // ['alice@example.com', ...]
print_r($this->email->get_cc()); // ['manager@example.com']
print_r($this->email->get_bcc()); // ['audit@example.com']
echo $this->email->get_subject(); // 'Your order has shipped'
var_dump($this->email->is_html()); // bool(true)
Method |
Returns |
Description |
|---|---|---|
|
|
Current sender address |
|
|
All To recipient addresses |
|
|
All CC recipient addresses |
|
|
All BCC recipient addresses |
|
|
Current subject line |
|
|
|
Sending
Call send() after all required fields have been set.
<?php
$sent = $this->email->send();
if ($sent)
{
// Mail accepted by the MTA
}
else
{
log_message('error', 'mail() returned false');
}
send() throws an Exception (not just returns false) when:
sender()has not been calledrecipient()has not been calledsubject()has not been called
This makes missing-field errors loud and easy to catch during development.
<?php
try
{
$this->email->send();
}
catch (Exception $e)
{
log_message('error', 'Email error: ' . $e->getMessage());
// handle gracefully
}
Method Reference
Method |
Signature |
Returns |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Complete Examples
Plain text password reset
<?php
$this->call->library('email');
$this->email
->sender('no-reply@example.com', 'My App')
->recipient($user['email'])
->reply_to('support@example.com')
->subject('Password Reset Request')
->email_content(
"Hello {$user['name']},\r\n\r\n"
. "Click the link below to reset your password:\r\n"
. "https://example.com/reset/{$token}\r\n\r\n"
. "If you did not request this, please ignore this email."
)
->send();
HTML invoice email with attachment and high priority
<?php
$this->call->library('email');
try
{
$sent = $this->email
->sender('billing@example.com', 'Billing Team')
->recipient($customer['email'])
->cc('accounts@example.com')
->subject('Invoice #' . $invoice_id)
->priority(1)
->html("
<h2>Invoice #{$invoice_id}</h2>
<p>Dear {$customer['name']},</p>
<p>Please find your invoice attached.</p>
<p>Thank you for your business.</p>
")
->attachment(APPPATH . 'uploads/invoices/invoice_' . $invoice_id . '.pdf')
->send();
if ( ! $sent)
{
log_message('error', "Invoice #{$invoice_id} email failed for {$customer['email']}");
}
}
catch (Exception $e)
{
log_message('error', 'Email exception: ' . $e->getMessage());
}
Looped newsletter with reset between sends
<?php
$this->call->library('email');
$subscribers = $this->subscriber_model->get_active();
foreach ($subscribers as $subscriber)
{
$this->email
->reset()
->sender('newsletter@example.com', 'Monthly Update')
->recipient($subscriber['email'])
->subject('April 2026 Newsletter')
->html('<h1>April Update</h1><p>Here is what is new this month...</p>')
->send();
}
Sending with CC, BCC, and low priority
<?php
$this->email
->sender('hr@example.com', 'HR Team')
->recipient('employee@example.com')
->cc('manager@example.com')
->bcc('hr-archive@example.com')
->subject('Your Annual Review')
->priority(5)
->email_content('Please find your annual review notes below...')
->attachment(APPPATH . 'uploads/reviews/review_2026.pdf')
->send();
Tips and Best Practices
Always wrap
send()in atry/catchblock — it now throwsExceptionfor missing required fields, andmail()can returnfalseon misconfigured servers even when no exception is thrown.Use
reset()when sending emails in a loop rather than reloading the library — it is faster and keeps the same instance.Use
bcc()when sending the same email to many recipients so addresses are not exposed to each other.Use
reply_to()whenever the sender is a no-reply address — this gives recipients a real mailbox to reply to.Always pass absolute paths to
attachment()— relative paths may resolve incorrectly depending on the server’s working directory.For high-volume or transactional email (order confirmations, password resets), consider routing through an SMTP relay or a third-party service (SendGrid, Mailgun, SES). PHP’s
mail()does not support SMTP authentication, queuing, or delivery tracking.Test emails in development using tools like Mailpit or Mailtrap to catch formatting issues before sending to real addresses.