Is there a php only email address obfuscator function? Most of the ones found on the web are a mix of JS and PHP.
            Asked
            
        
        
            Active
            
        
            Viewed 1.1k times
        
    11
            
            
        - 
                    you mean a captcha that you need to fill before the real email address is sent to you? ;) – Gung Foo Sep 25 '12 at 23:08
6 Answers
18
            
            
        Here are a couple of functions I use.
First one obfuscates email address using html character codes:
function getObfuscatedEmailAddress($email)
{
    $alwaysEncode = array('.', ':', '@');
    $result = '';
    // Encode string using oct and hex character codes
    for ($i = 0; $i < strlen($email); $i++) {
        // Encode 25% of characters including several that always should be encoded
        if (in_array($email[$i], $alwaysEncode) || mt_rand(1, 100) < 25) {
            if (mt_rand(0, 1)) {
                $result .= '&#' . ord($email[$i]) . ';';
            } else {
                $result .= '&#x' . dechex(ord($email[$i])) . ';';
            }
        } else {
            $result .= $email[$i];
        }
    }
    return $result;
}
Example:
echo getObfuscatedEmailAddress('firstname.last-name@example.com');
-->
firstname.last-name@example.com
Second one will return link where email address is both html and url encoded:
function getObfuscatedEmailLink($email, $params = array())
{
    if (!is_array($params)) {
        $params = array();
    }
    // Tell search engines to ignore obfuscated uri
    if (!isset($params['rel'])) {
        $params['rel'] = 'nofollow';
    }
    $neverEncode = array('.', '@', '+'); // Don't encode those as not fully supported by IE & Chrome
    $urlEncodedEmail = '';
    for ($i = 0; $i < strlen($email); $i++) {
        // Encode 25% of characters
        if (!in_array($email[$i], $neverEncode) && mt_rand(1, 100) < 25) {
            $charCode = ord($email[$i]);
            $urlEncodedEmail .= '%';
            $urlEncodedEmail .= dechex(($charCode >> 4) & 0xF);
            $urlEncodedEmail .= dechex($charCode & 0xF);
        } else {
            $urlEncodedEmail .= $email[$i];
        }
    }
    $obfuscatedEmail = getObfuscatedEmailAddress($email);
    $obfuscatedEmailUrl = getObfuscatedEmailAddress('mailto:' . $urlEncodedEmail);
    $link = '<a href="' . $obfuscatedEmailUrl . '"';
    foreach ($params as $param => $value) {
        $link .= ' ' . $param . '="' . htmlspecialchars($value). '"';
    }
    $link .= '>' . $obfuscatedEmail . '</a>';
    return $link;
}
Example:
echo getObfuscatedEmailLink('firstname.last-name@example.com');
-->
<a href="mailto:%66i%72stna%6de.%6c%61st-name@example.com" rel="nofollow">firstname.last-name@example.com</a>
 
    
    
        Alexei Tenitski
        
- 9,030
- 6
- 41
- 50
- 
                    Interesting approach +1. But it might have some compatibilty issues. – Andreas Rehm Sep 25 '12 at 23:10
- 
                    I haven't tested it in Safari and mobile browsers. FF, IE, Chrome are good. – Alexei Tenitski Sep 25 '12 at 23:11
- 
                    
14
            
            
        My fav:
Markup + PHP
<span class="rev"><?php echo strrev($email); ?> </span>
CSS
.rev{
    direction: rtl;
    unicode-bidi: bidi-override;
}
 
    
    
        moonwave99
        
- 21,957
- 3
- 43
- 64
- 
                    1
- 
                    
- 
                    Note that this method is far too easy *reverse-engineered*: `if (email.indexOf('.') < email.indexOf('@')) email.reverse()` – yckart Jul 06 '16 at 00:03
- 
                    
- 
                    @AakilFernandes moc.elpmaxe@olleh - so it's not a fit solution for copying data purposes. – Andres SK Oct 28 '19 at 15:58
3
            
            
        Here's one with type-hinting.
Just call it with $this->obfuscateEmail($email);
/**
 * @param string $email
 * @return string
 */
private function obfuscateEmail(string $email): string
{
    $em = explode("@", $email);
    $name = implode(array_slice($em, 0, count($em) - 1), '@');
    $len = floor(strlen($name) / 2);
    return substr($name, 0, $len) . str_repeat('*', $len) . "@" . end($em);
}
 
    
    
        crmpicco
        
- 16,605
- 26
- 134
- 210
- 
                    Note that the implode function's arguments should be reversed since **PHP 8** : `$name = implode('@', array_slice($em, 0, count($em) - 1));` – v.nivuahc Apr 26 '23 at 12:15
2
            
            
        Here is one more way which is quite tight and does not cause errors with https://validator.w3.org
function obfuscate($email){
$encoded_email = '';
for ($a = 0,$b = strlen($email);$a < $b;$a++)
{
    $encoded_email .= '&#'.(mt_rand(0,1) == 0  ? 'x'.dechex(ord($email[$a])) : ord($email[$a])) . ';';
}
return $encoded_email;}
Then to add to the page use:
<a href="mailto:<?= obfuscate(CONTACT_EMAIL.'?subject=Hello!') ?>"><?= CONTACT_EMAIL ?></a>
 
    
    
        Andrew Wood
        
- 21
- 1
2
            
            
        Some of these examples listed here are great, but I went with the WordPress antispambot() function, which is below for convenience:
function antispambot( $email_address, $hex_encoding = 0 ) {
    $email_no_spam_address = '';
    for ( $i = 0, $len = strlen( $email_address ); $i < $len; $i++ ) {
        $j = rand( 0, 1 + $hex_encoding );
        if ( 0 == $j ) {
            $email_no_spam_address .= '&#' . ord( $email_address[ $i ] ) . ';';
        } elseif ( 1 == $j ) {
            $email_no_spam_address .= $email_address[ $i ];
        } elseif ( 2 == $j ) {
            $email_no_spam_address .= '%' . zeroise( dechex( ord( $email_address[ $i ] ) ), 2 );
        }
    }
    return str_replace( '@', '@', $email_no_spam_address );
}
function zeroise( $number, $threshold ) {
    return sprintf( '%0' . $threshold . 's', $number );
}
See WordPress for more details.
 
    
    
        Dario Zadro
        
- 1,143
- 2
- 13
- 23
0
            
            
        Here an alternative way in case there is one character before host:
/**
* @param string $email
* @return string
*/
private function obfuscateEmail($email)
{
    $em   = explode("@", $email);
    $name = implode(array_slice($em, 0, count($em)-1), '@');
    if(strlen($name)==1){
        return   '*'.'@'.end($em);
    }
    $len  = floor(strlen($name)/2);
    return substr($name,0, $len) . str_repeat('*', $len) . "@" . end($em);
}
