fEmail

The fEmail class provides an interface to very easily send well-formed emails with UTF-8 content, HTML and attachments. fEmail uses PHP’s built-in mail() function, so it is not appropriate for sending large numbers of email due to performance issues. If you are looking for solutions to send mass amounts of email (which requires an SMTP server), you will probably want to check out Swift Mailer or PHPMailer.

Instantiation

Creating a new email is as simple as making a new instance of fEmail:

$email = new fEmail();

Recipients

fEmail supports To:, CC: and BCC: recipients through the methods addRecipient(), addCCRecipient() and addBCCRecipient(). Each method requires a single parameter $email and accepts a second optional parameter $name. The add methods can be called any number of times to add any number of recipients:

// Add our recipient
$email->addRecipient('will@example.com', 'Will');
 
// Add a few people to the CC and BCC lists
$email->addCCRecipient('john@example.com');
$email->addCCRecipient('bob@example.com', 'Bob Smith, Jr.');
 
$email->addBCCRecipient('alice@example.com');

If need be, all regular, CC and BCC recipients can be cleared by calling the method clearRecipients().

$email->clearRecipients();

From Headers

When sending a message you will also need to set the From: address via the method setFromEmail(). The first parameter, $email, is required, however the second parameter, $name, is optional. Unfortunately the implementation of mail() on Windows does not allow setting the $name parameter.

// Set who the email is from
$email->setFromEmail('will@example.com');
 
// Include the user’s name
$email->setFromEmail('will@example.com', 'Will');

It is also possible to set the Return-Path: header on almost all servers. This email address is listed as the “true” source of the email and will be the recipient of any bounces or delivery notifications. The method setBounceToEmail() sets this address with just a single parameter $email:

$email->setBounceToEmail('will@example.com');

Subject and Body

All email must have a subject and body set by the methods setSubject() and setBody(). Both of these methods accept a single parameter, a UTF-8 string.

// Set the subject include UTF-8 curly quotes
$email->setSubject('This won’t break email programs because it is properly encoded by the class');
 
// Set the body to include a string containing UTF-8
$email->setBody('This is the body of the email…');

HTML Body

It is also possible to add an HTML version of the body by passing it to setHTMLBody(). This HTML content should be encoded using UTF-8:

$email->setHTMLBody('<p>This it the HTML version of the body…</p>');

Attachments

Attachments can be added to an email by calling the method addAttachment(). The method requires three parameters, $filename, $mime_type and $contents. The $filename should be the desired filename the recipient will see.

foreach ($result as $row) {
    $csv_contents .= join(",", $row) . "\n";
}
 
$email->addAttachment('report.csv', 'text/csv', $csv_contents);

There is no limit to the number of attachments.

S/MIME Encryption and Signing

The fEmail class provides support for encrypting and signing messages using S/MIME. To encrypt a message, the PEM-encoded public certificate will be needed. To sign a message, the PEM-encoded private key will be needed. To encrypt and sign you will need both (but not for the user). Please see Obtaining a Secure Certificate/Key Pair for information about how to get the necessary files.

To encrypt a message, call the method encrypt() and pass the path to the recipient’s PEM-encoded public certificate:

$email->encrypt('/path/to/recipients.cer');

To sign a message, call sign() and pass in the sender’s public certificate path, private key path and private key password (if applicable):

$email->sign('/path/to/senders.cer', '/path/to/senders.key', 'key_password');

If you call both sign() and encrypt() (in either order), the message will be signed, then encrypted and then signed again. This is the most secure method, however certain older email clients may not open such emails.

Sending

To send an email, simply call the send() method:

$email->send();

Fixing Formatting Issues

On some linux/unix server running qmail as the sendmail replacement, you may experience issues with emails looking corrupted to the recipients. This will often take the form of equal signs (=) appearing throughout the content and lines being wrapped in odd places.

The technical cause of the issue is that the qmail sendmail binary is automatically replacing every line feed (\n) with a CR-LF (\r\n) because the email specifications require emails use CR-LF and linux uses LF as the line ending. Qmail is trying to ensure you are sending emails that meet specifications, however it is not checking to see if the email already has the proper line endings.

The static method fixQmail() should fix the issue. On servers where open_basedir and safe_mode are not in effect, fEmail will make a commandline call to sendmail and will replace all CR-LF with just LF. If that is not possible, fEmail will simply replace all CR-LFs with LF, however emails with long headers may still have issues.

Normally you would only enable this fix if you experience the issue. Since the fix affects all instances of fEmail, you’ll normally want to call it in a configuration file.

fEmail::fixQmail();

Validating Email Addresses

In certain situations it may be necessary to validate an email address when not using fValidation or fORMValidation with the ORM. The fEmail class provides two regular expression constants to help with the task.

These regular expressions are designed to fully match the mailbox specification of RFC2822 Section 3.4 except for allowing comments and folding white space. Quoted strings are supported along with the +, - and other special characters.

Below is an example of some of the various valid email address formats that are supported:

# regular address
will@example.com

# with + suffix
will+foo@example.com

# with - suffix
will-foo@example.com

# periods
will.foo@example.com

# quoted strings
"will foo"@example.com

# combinations
"will foo".bar+baz@example.com

The two constants are EMAIL_REGEX and NAME_EMAIL_REGEX. EMAIL_REGEX will match an email address, while NAME_EMAIL_REGEX will match a name <email> string.

EMAIL_REGEX captures 3 subpatterns in the following format:

  • [0]: The whole email address
  • [1]: The part of the email before the @
  • [2]: The part of the email after the @

For example:

preg_match(fEmail::EMAIL_REGEX, 'will@example.com', $matches);
 
echo $matches[0] . "\n";
echo $matches[1] . "\n";
echo $matches[2];

will output the following:

will@example.com
will
example.com

NAME EMAIL_REGEX captures 5 subpatterns in the following format:

  • [0]: The whole name and email address
  • [1]: The name
  • [2]: The whole email address
  • [3]: The part of the email before the @
  • [4]: The part of the email after the @

For example:

preg_match(fEmail::NAME_EMAIL_REGEX, 'Will <will@example.com>', $matches);
 
echo $matches[0] . "\n";
echo $matches[1] . "\n";
echo $matches[2] . "\n";
echo $matches[3] . "\n";
echo $matches[4];

will output the following:

Will <will@example.com>
Will
will@example.com
will
example.com