Shoeisha Technology Media

CodeZine(コードジン)

特集ページ一覧

[PHPプロ!] スパムボットからメールアドレスを守る方法

  • ブックマーク
  • LINEで送る
  • このエントリーをはてなブックマークに追加
2007/01/29 13:33

onPHP5.comにてPHPとJavaScriptを使ってスパムボットによるメールアドレス収集を防ぐ方法が掲載されています。

 onPHP5.comにてPHPとJavaScriptを使ってスパムボットによるメールアドレス収集を防ぐ方法が掲載されています。

 サイトを持っている人にとってスパムボットによるメールアドレス収集はとてもやっかいなことです。サイトを訪れてくれる人に自分の連絡先を知らせるにはメールアドレスを掲載しなければなりませんが、掲載するとスパムボットによっていつの間にか収集され、スパマーの餌食になってしまいます。

 今、それを防ぐ一般的な方法としてメールアドレスを画像にし人間だけにしか読めないようにするというものがあります。しかしこの方法はリンクをクリックしてもメーラーは起動せず、さらにアドレスを選択してもコピーすることは出来ません。もしサイトを訪れてくれる人があなたと連絡を取りたいと思ったときに、とても不便ではないでしょうか?

 そこでonPHP5.comでは、この不便さを解消した画像を使わないスパムボット対策をPHPとJavaScriptを使って紹介しています。

 一つめは、PHPを使ってメールアドレスを数値文字参照に変換する方法です。

  1  <?php 
  2  
  3  function hideEmail($email) { 
  4    $rv = ''; 
  5    for($i = 0; $i < strlen($email); $i++) { 
  6      $rv .= '&#' . ord($email[$i]) . ';'; 
  7    } 
  8    return $rv; 
  9  } 
 10  
 11  // Sample usage: 
 12  
 13  $email = 'me@example.com'; 
 14  $href = hideEmail('mailto:' . $email); 
 15  $email = hideEmail($email); 
 16  
 17  echo "<a href=\"$href\">$email</a> 
 18     
 19  ?> 

 これを実行すると以下のような出力になります。

<a href="mailto:me@
example.com">
me@example.
com</a> 

 もう一つの方法はJavaScriptを使ったもので、JavaScriptを使ってA要素を生成しdocument.writeで出力するというものです。

  1  <?php 
  2  /** 
  3   * Generate JS that will render obfuscated email address
 into the document 
  4   * @param  string $to  the email address 
  5   * @param  string $subject  the subject header 
  6   * @param  array $attrs  optional array of additional attrs
 for the resulting <a> tag 
  7   * @return  string  the resulting JavaScript 
  8   */ 
  9  function jsEmail($to, $subject = null, $attrs = array()) { 
 10    // Split the email into user name and domain 
 11    list($u, $d) = explode('@', $to); 
 12     
 13    // Form the href attribute 
 14    $href = "mailto:$u@$d"; 
 15    if($subject) { 
 16      $href .= '?Subject=' . rawurlencode($subject); 
 17    } 
 18    // Now also split the href attribute 
 19    // We split them so that they do not contain
 the email address in one string literal 
 20    // - otherwise the bot will have no trouble
 finding the email address 
 21    list($hu, $hd) = explode('@', $href); 
 22     
 23    // If we have more attributes, prepare JS for them 
 24    $attr = ''; 
 25    foreach($attrs as $k=>$v) { 
 26      $v = '"' . $v . '"'; 
 27      $attr .= "document.write('$k=$v');\n"; 
 28    }  
 29     
 30    // Generate return value 
 31    $rv = <<<EOT 
 32    <script> 
 33       document.write('<a href="$hu' + '@'); 
 34       document.write('$hd' + '"'); 
 35       $attr 
 36       document.write('>$u' + '@'); 
 37       document.write('$d</a>'); 
 38    </script> 
 39  EOT; 
 40    return $rv; 
 41  } 
 42  
 43  // Example of use 
 44  
 45  echo "Contact email: "; 
 46  echo jsEmail('me@example.com', 'Sales enquiry form submission',  
 47    array('class' => 'link')); 
 48  ?> 

 これを実行すると以下のような出力になります。

Contact email: <script> 
document.write('<a href="mailto:me' + '@'); 
document.write('example.com?Subject=
Sales%20enquiry%20form%20submission' + '"'); 
document.write('class="link"'); 

document.write('>me' + '@'); 
document.write('example.com</a>'); 
</script> 

 また、これらの方法を組み合わせるという方法もあります。数値文字参照に変換しそれをJavaScriptを使って出力します。

  1  <?php 
  2  /** 
  3   * Generate JS that will render obfuscated
 email address into the document 
  4   * @param  string $to  the email address 
  5   * @param  string $subject  the subject header 
  6   * @param  array $attrs  optional array of additional attrs
 for the resulting <a> tag 
  7   * @return  string  the resulting JavaScript 
  8   */ 
  9  function jsEmail($to, $subject = null, $attrs = array()) { 
 10    // Split the email into user name and domain 
 11    list($u, $d) = explode('@', $to); 
 12     
 13    // Form the href attribute 
 14    $href = "mailto:$u@$d"; 
 15    if($subject) { 
 16      $href .= '?Subject=' . rawurlencode($subject); 
 17    } 
 18    // Now also split the href attribute 
 19    // We split them so that they do not contain
 the email address in one string literal 
 20    // - otherwise the bot will have no trouble
 finding the email address 
 21    list($hu, $hd) = explode('@', $href); 
 22     
 23    // Hide letters 
 24    $u = hideEmail($u); 
 25    $d = hideEmail($d); 
 26    $hu = hideEmail($hu); 
 27    $hd = hideEmail($hd); 
 28  
 29    // If we have attributes, prepare JS for them 
 31    $attr = ''; 
 32    foreach($attrs as $k=>$v) { 
 33      $v = '"' . $v . '"'; 
 34      $attr .= "document.write('$k=$v');\n"; 
 35    }  
 36     
 37    // Generate return value 
 38    $rv = <<<EOT 
 39    <script> 
 40       document.write('<a href="$hu' + '@'); 
 41       document.write('$hd' + '"'); 
 42       $attr 
 43       document.write('>$u' + '@'); 
 44       document.write('$d</a>'); 
 45    </script> 
 46  EOT; 
 47    return $rv; 
 48  } 
 49 ?> 

 これを実行すると以下のような出力になります。

<script> 
document.write('<a href="mailto
:me' + '@'); 
document.write('example.
com?Subject
=Sales%20en
quiry%20for
m%20submiss
ion' + '"'); 
document.write('class="link"'); 

document.write('>me' + '@'); 
document.write('example.
com</a>'); 
</script> 

 onPHP5.comでも述べていますが、メールアドレスを画像に変換する方法と比較するとこの方法は決して安全ではありません。スパムボットの開発者がこれらをパースするようにボットを改良するということも考えられるからです。ただ、今回紹介したこの方法はこの方法で先に述べたような利点もあるので、興味のある方は使ってみてはいかがでしょうか。(PHPプロ!

関連リンク

転載元

 PHPプロ!:最新のPHPニュース

  • ブックマーク
  • LINEで送る
  • このエントリーをはてなブックマークに追加
All contents copyright © 2005-2019 Shoeisha Co., Ltd. All rights reserved. ver.1.5