Pragmatism in the real world

Redirecting email whilst developing

One common problem whilst developing is that you don’t want to send emails out to the client (or their clients!). Ideally, we want to alter our development environment so that this doesn’t happen, but still allows us to test the contents of emails that are sent by our web applications.


On Windows, the mail() function uses SMTP over port 25. Unless you’ve changed your php.ini file, then it will try to connect to localhost in order to send an email. On Windows VM, I use Fakemail. This is an SMTP mail server written in perl (or python) that store emails as files into a given directory. When your web application sends an email, you check in the directory and look at the files created. One top tip: alter the script to give each file a .txt extension. Then you can double click :)

Fakemail is also very useful in Linux/Mac if you are using the SMTP transport mail in Zend_Mail or Swiftmailer or whatever.

Linux / OS X

On the *nix based systems, mail() sends email using an application on the system called sendmail (or any number of compatible alternatives). By default it will call the sendmail binary, however you can change this in your php.ini with the sendmail_path setting.

I set my development boxes like this:

sendmail_path = /usr/local/bin/trapmail

Now, mail() will call my trapmail script. This script is trivial:

formail -R cc X-original-cc \
-R to X-original-to \
-R bcc X-original-bcc \
-f -A"To:" \
| /usr/sbin/sendmail -t -i

This script causes all emails to be redirect to my email address with the original to, cc and bcc fields renamed in the headers, so they can be checked!. I like this solution even better than Fakemail as it’s easier to see exactly what the mail looks like in a mail client, especially for HTML format.

I just wish I had thought of this script myself! However Sean Coates came up with the idea in 2005 and I’ve been using it ever since.

9 thoughts on “Redirecting email whilst developing

  1. Thanks for sharing this Rob, I've been wondering how you do it for a while.

    I assume this principle does not apply just to PHP, but any thing you may be testing on your computer?

  2. Only drawback of putting it in php.ini is any applications that you want to send real emails will fail.

    When using zf you can just pop this into your application.ini set the sendmail_path on a per-environment basis. Which is pretty handy!

  3. Dan,
    Replacement SMTP servers work for any development involving email.

    Thanks for the info on papercut. I'd never heard of it.

    Good tip!



  4. That is much better than my typical solution, which usually involves hacking at the user's email accounts to send mail to me rather than them. Great tip!

  5. I just re-read what I posted and I don't actually hack user's email accounts…duh…I change their account IN MY SYSTEM so that their email address is mine. Don't think my brain is engaged yet this morning :)

  6. Well, why don't you just set the addTo according to the application_env? Seems pretty simple enough for me.

    if (APPLICATION_ENV == 'testing' || APPLICATION_ENV == 'development') $mail->addTo('', 'Dev');
    if (APPLICATION_ENV == 'testing' || APPLICATION_ENV == 'production') $mail->addTo('', 'Client');

  7. @Aaron that won't work since sendmail_path is not settable via ini_set() as sendmail_path has changeable type of PHP_INI_SYSTEM. However, I believe you can put:

    php_admin_value sendmail_path /usr/local/bin/trapmail

    in a vhost entry in httpd.conf (will not work in .htaccess tho)

    Someone correct me if I am wrong.

Comments are closed.