' . 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; } }