antispambot( string $email_address, int $hex_encoding ): string

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.

Return

string Converted email address.

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( '@', '&#64;', $obfuscated );
}

Changelog

VersionDescription
7.1.0Masquerades multibyte characters.
0.71Introduced.

User Contributed Notes

  1. Skip to note 4 content

    Example

    /**
     * Hide email from Spam Bots using a shortcode.
     *
     * @param array  $atts    Shortcode attributes. Not used.
     * @param string $content The shortcode content. Should be an email address.
     * @return string The obfuscated email address. 
     */
    function wpdocs_hide_email_shortcode( $atts , $content = null ) {
    	if ( ! is_email( $content ) ) {
    		return;
    	}
    	return '<a href="' . esc_url('mailto:' . antispambot( $content ) ) . '">' . esc_html( antispambot( $content ) ) . '</a>';
    }
    add_shortcode( 'email', 'wpdocs_hide_email_shortcode' );

    To use this in your WordPress Content area all you have to do it wrap it in a short code.

    [email]john.doe@mysite.com[/email]

    You can also use this in a plain text widget if you add this filter to your function file as well.

    add_filter( 'widget_text', 'shortcode_unautop' );
    add_filter( 'widget_text', 'do_shortcode' );

    Edited with a contribution from @johnrafferty

  2. Skip to note 6 content

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

You must log in before being able to contribute a note or feedback.