Obscures email addresses in HTML to prevent spam bots from harvesting them.
Description
Typically this will randomly replace characters from the email address with HTML character references; however, when the hex encoding parameter is set, some characters will also be represented in their percent-encoded form.
Because this function is randomized, the outputs for any given input may differ between calls. This helps diversify the ways the email addresses are obscured.
When non-UTF-8 inputs are provided, any spans of invalid UTF-8 bytes will be passed through without any obfuscation.
Example:
$email = 'noreply@example.com';
$obscured = antispambot( $email );
$obscured === 'noreply@example.com';
// Hex-encoding also obscures characters with percent-encoding.
$obscured = antispambot( $email, 1 );
$obscured === '%6eore%70l%79@%65x%61mple%2e%63%6fm';
// Non-UTF-8 characters are not obfuscated. "\xFC" is Latin1 "ü".
$obscured = antispambot( "b\xFCcher@library.de" );
$obscured === 'b�cher@library.de';
$obscured === "b\xFCcher@library.de"Parameters
$email_addressstringrequired- Email address.
$hex_encodingintoptional- Set to 1 to enable hex encoding.
Source
function antispambot( $email_address, $hex_encoding = 0 ) {
$obfuscated = '';
$at = 0;
$end = strlen( $email_address );
$invalid_length = 0;
while ( $at < $end ) {
$was_at = $at;
if (
0 === _wp_scan_utf8( $email_address, $at, $invalid_length, null, 1 ) &&
0 === $invalid_length
) {
break;
}
$character_length = $at - $was_at;
if ( $character_length > 0 ) {
$character = substr( $email_address, $was_at, $character_length );
switch ( rand( 0, 1 + $hex_encoding ) ) {
case 0:
$code_point = mb_ord( $character );
$obfuscated .= "&#{$code_point};";
break;
case 1:
$obfuscated .= $character;
break;
case 2:
for ( $i = 0; $i < $character_length; $i++ ) {
$hex_value = bin2hex( $character[ $i ] );
$obfuscated .= "%{$hex_value}";
}
break;
}
}
if ( 0 !== $invalid_length ) {
$obfuscated .= substr( $email_address, $at, $invalid_length );
}
$at += $invalid_length;
}
return str_replace( '@', '@', $obfuscated );
}
Example
To use this in your WordPress Content area all you have to do it wrap it in a short code.
You can also use this in a plain text widget if you add this filter to your function file as well.
Edited with a contribution from @johnrafferty
http://before email address. In lack of better option, it’s more appropriate to useesc_attr()instead.widget_textis no longer necessary as shortcodes are allowed in text widgets by default.I really feel like this function should be updated. We’re in 2024 and HTML entities can be easily decoded by spam bots. At this point, this technique does not block spam at all.
If you can, try to use Xor on your WordPress site; avoid using this function.
Fatal error risk without the `mbstring` extension
Since WP 7.1 (see Changelog), `antispambot() ` calls `mb_ord()` on every scanned character — not just multibyte ones. The `switch` branch that decides how to obfuscate each character is chosen at random, regardless of whether that character is multibyte.
`mb_ord()` is provided by PHP’s `mbstring` extension. Unlike `mb_substr()` and `mb_strlen()`, WordPress does not ship a polyfill for it in `wp-includes/compat.php`. `mbstring` is only recommended for WordPress, not required — it’s disabled by default in PHP, and some hosts still don’t enable it.
On a server without `mbstring`, any call to `antispambot() ` has a random, per-character chance of throwing:
Fatal error: Uncaught Error: Call to undefined function mb_ord()
This can happen even for a plain ASCII email address, since the branch selection doesn’t check the character length first.
If your theme/plugin needs to support hosts without `mbstring`, guard for it before calling the function:
if ( ! function_exists( ‘mb_ord’ ) ) {
// Provide a fallback obfuscation method, or skip antispambot() entirely.
}