' . EmailObfuscator::email('name@domain.com') . '';
*/
class EmailObfuscator
{
/**
* Obfuscate an email address for display in HTML content.
*/
public static function email(string $address): string
{
return self::encode($address);
}
/**
* Obfuscate a mailto: link for use in an href attribute.
* Returns 'mailto:' followed by the obfuscated email.
*/
public static function mailto(string $address): string
{
return 'mailto:' . self::encode($address);
}
/**
* Replace plain-text email addresses in a string with obfuscated versions.
* Only replaces addresses that appear as bare text (not already inside HTML entities).
*/
public static function emailText(string $text): string
{
return preg_replace_callback(
'/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/',
fn(array $m) => self::encode($m[0]),
$text
);
}
/**
* Obfuscate a mailto: URL found in text (e.g. from Markdown or user input).
* Matches 'mailto:user@domain.com' pattern.
*/
public static function mailtoInText(string $text): string
{
return preg_replace_callback(
'/mailto:([A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,})/i',
fn(array $m) => 'mailto:' . self::encode($m[1]),
$text
);
}
/**
* Post-process rendered HTML: obfuscate all mailto: links and their
* visible text (email addresses) so bots can't scrape them.
*
* Matches patterns like:
* foo@bar.com
* some text
*
* In the second case, only the href is obfuscated (the link text is kept).
*/
public static function obfuscateHtml(string $html): string
{
// Match tags whose href starts with mailto:
return preg_replace_callback(
'/]*href="mailto:([^"]+)"[^>]*>(.*?)<\/a>/is',
function (array $m): string {
$email = $m[1];
$linkText = $m[2];
$obfuscated = self::encode($email);
// If the link text is the email itself, replace it too
$text = strip_tags($linkText);
if ($text === $email) {
$linkText = self::encode($linkText);
}
// Rebuild the tag with obfuscated values
return str_replace(
['mailto:' . $email, '>' . $m[2] . '<'],
['mailto:' . $obfuscated, '>' . $linkText . '<'],
$m[0]
);
},
$html
);
}
// ── Private ───────────────────────────────────────────────────────────
private static function encode(string $s): string
{
$out = '';
$len = strlen($s);
for ($i = 0; $i < $len; $i++) {
$out .= '' . ord($s[$i]) . ';';
}
return $out;
}
}