About Chris Morrell

I am a Philadelphia web designer and developer who focuses on PHP development and usable design. I am also the Director of IT for the International Association of Certified Home Inspectors.

Please Note: My site fell victim to a Wordpress security flaw a few weeks ago, and I'm just getting everything back to normal. Please bear with me.

I am currently not accepting any new clients.

Other Sites/Clients

Contact Me

If you need to get in touch with me, my name is Chris and my domain name is cmorrell.com. Think about it.

E-Mail Address Obfuscator Class

Posted by Chris Morrell on October 2nd, 2008 in Web Development (tagged , , )

A project I’m working on needs to output text that may have e-mail addresses in it to the Web. Because we don’t want people’s e-mail addresses exposed to spammers, I had to write an obfuscation class to make sure those e-mail addresses are hidden somehow. I haven’t decided what method to hide those addresses with yet (I’m leaning towards Mailhide), but I thought I’d post the base code now. The class is written so that you can extend it to hide the addresses however you like. Here’s the class (PHP 5 only, but would be easy to convert to PHP 4).

/**
 * Simple Obfuscation Class
 *
 * The beginning of an obfuscation class, made primarily to obfuscate
 * email addresses within a block of text or HTML.  Used in conjunction
 * with reCAPTCHA's Mailhide service  or
 * a database-driven e-mail address hider.
 *
 * LICENSE
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details .
 *
 * @author     Chris Morrell
 * @copyright  Copyright 2008 Chris Morrell
 * @version    0.1
 * @license    GPL
 *
 */
class Galahad_Obfuscator
{
	const EMAIL_ANCHOR = 101;
	const EMAIL_URL = 102;
	const EMAIL_DISPLAY = 103;

	protected $mailtoRegexp = '/((.*?)<\/a>/is';
	protected $emailRegexp = '/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b/i';

	/**
	 * Public method to obfuscate all e-mail addresses in a string
	 *
	 * @param string $string
	 * @return string
	 */
	public function emailAddresses($string)
	{
		$string = $this->replaceMailto($string);
		$string = $this->replaceEmail($string);
		return $string;
	}

	/**
	 * Private function to replace all e-mail addresses with
	 * obfuscated string (most often links)
	 *
	 * @param string $string
	 * @return string
	 */
	private function replaceEmail($string)
	{
		$string = preg_replace_callback($this->emailRegexp, array($this, 'processEmail'), $string);
		return $string;
	}

	/**
	 * Private function to handle all found e-mail addresses in string
	 *
	 * @param array $matches
	 * @return string
	 */
	private function processEmail($matches)
	{
		return $this->obfuscateEmail($matches[0], self::EMAIL_ANCHOR);
	}

	/**
	 * Private function to replace all mailto: anchors with
	 * obfuscated anchors
	 *
	 * @param string $string
	 * @return string
	 */
	private function replaceMailto($string)
	{
		$string = preg_replace_callback($this->mailtoRegexp, array($this, 'processMailto'), $string);
		return $string;
	}

	/**
	 * Private function to handle all found mailto: anchors
	 *
	 * @param array $matches
	 * @return string
	 */
	private function processMailto($matches)
	{
		$newUrl = $this->obfuscateEmail($matches[2], self::EMAIL_URL);
		$inner = $matches[4];

		if (preg_match($this->emailRegexp, $inner)) {
			$inner = $this->obfuscateEmail($inner, self::EMAIL_DISPLAY);
		}

		return "{$matches[1]}{$newUrl}{$matches[3]}>{$inner}";
	}

	/**
	 * Subclass this method to obfuscate the address however you see
	 * fit (whether with Mailhide or some other system).  Right now
	 * this function isn't very helpful, as it obfuscates all e-mail
	 * addresses and links them to #
	 *
	 * @param string $email
	 * @param int $type
	 * @return string
	 */
	protected function obfuscateEmail($email, $type = self::EMAIL_ANCHOR)
	{
		$email = substr($email, 0, strpos($email, '@') + 1) . '...';

		if ($type == self::EMAIL_ANCHOR) {
			return "<a href="\">{$email}</a>";
		} else if ($type == self::EMAIL_URL) {
			return "#";
		}

		return $email;
	}
}

Here’s some sample usage:

class My_Obfuscator extends Galahad_Obfuscator
{
	protected function obfuscateEmail($email, $type = self::EMAIL_ANCHOR)
	{
		$id = $this->emailToId($email);
		$email = substr($email, 0, strpos($email, '@') + 1) . '...';

		if ($type == self::EMAIL_ANCHOR) {
			return "<a href="\">{$email}</a>";
		} else if ($type == self::EMAIL_URL) {
			return "http://yoursite.com/get-email.php?id={$id}";
		}

		return $email;
	}

	private function emailToId($email)
	{
		// Implement this by adding the email to a database
		// and returning the row's ID, for example
		return rand(1,500);
	}
}

$html = 'some string with e-mail addresses in it.';
$obfuscator = new My_Obfuscator();
echo $obfuscator->emailAddresses($html);

So far the class has worked well with limited testing. Obviously it handles both e-mail addresses in plain text and mailto: links. Please let me know if you find any bugs in it, or have a suggestion about how to make it better.

No Comments (Respond Now) »

Leave a Reply

Additional comments powered by BackType

Comments & Trackbacks

You can leave a response, or trackback from your own site. Follow any responses to this entry through the RSS 2.0 feed.

More...

@inxilpro

  • Wet Hot American Summer at World Cafe Live. It's free and dead. 2 days ago
  • Would really like something that combines Twitter starred + Google Reader starred/liked + Delicious.com. Does such a thing exist? 6 days ago
  • Also, how can OS X be so rock solid and other Apple-developed software be so buggy? 1 week ago
  • More updates...
Copyright © Chris Morrell, Powered by WordPress, Entry RSS Feed / Comment RSS Feed