Smartyの小ワザ集(1): メールアドレスを安全に

今までSmartyをあまり使ってきませんでしたが、ちょっとしたネタを見つけながら勉強していこうと思っています。

「極めるPHP」を読んでいたら、P89に興味深いワザが載っていました。
検索エンジンbotがメールアドレスを収集しないようにするための工夫についてです。
どうやらJavaScriptを利用するみたいです。

サンプル自体は無かったので、ちょっと試してみました。
まずは、テンプレート。

$ vi templates/mail.html
<html>
<body>
{mailto address="$mail" encode="javascript"}
</body>
</html>

mail変数にメールアドレスをassignしているだけです。

$ vi mail.php
<?php
    require_once "Smarty.class.php";

    $smarty = new Smarty();
    $smarty->template_dir = "./templates";
    $smarty->compile_dir  = "./templates_c";
    $smarty->cache_dir    = "./cache";

    $smarty->assign('mail', 'email@example.com');

    $smarty->display("mail.html");
?>

生成されたHTMLは以下の通り。
こんな工夫で、botから収集されるのを防げるんですね。

<html>
<body>
<script type="text/javascript">eval(unescape('%64%6f%63%75%6d%65%6e%74%2e%77
%72%69%74%65%28%27%3c%61%20%68%72%65%66%3d%22%6d%61%69%6c%74%6f%3a
%65%6d%61%69%6c%40%65%78%61%6d%70%6c%65%2e%63%6f%6d%22%20%3e%65%6d
%61%69%6c%40%65%78%61%6d%70%6c%65%2e%63%6f%6d%3c%2f%61%3e%27%29%3b'))</script>
</body>
</html>


Smartyでどのような処理をしているのか気になったのでgrep

cd ~/public_html/php/smarty/Smarty-2.6.9
$ grep -rn "mailto" .
[...]
./libs/plugins/function.mailto.php:10: * Smarty {mailto} function plugin
./libs/plugins/function.mailto.php:13: * Name:     mailto<br>
./libs/plugins/function.mailto.php:15: * Purpose:  automate mailto address link creation, and optionally
./libs/plugins/function.mailto.php:34: * {mailto address="me@domain.com"}
./libs/plugins/function.mailto.php:35: * {mailto address="me@domain.com" encode="javascript"}
./libs/plugins/function.mailto.php:36: * {mailto address="me@domain.com" encode="hex"}
./libs/plugins/function.mailto.php:37: * {mailto address="me@domain.com" subject="Hello to you!"}
./libs/plugins/function.mailto.php:38: * {mailto address="me@domain.com" cc="you@domain.com,they@domain.com"}
./libs/plugins/function.mailto.php:39: * {mailto address="me@domain.com" extra='class="mailto"'}
./libs/plugins/function.mailto.php:41: * @link http://smarty.php.net/manual/en/language.function.mailto.php {mailto}
./libs/plugins/function.mailto.php:50:function smarty_function_mailto($params, &$smarty)


核になっているコードは、こんな感じでした。
こんなものまでSmartyには用意されているのか、と関心しました。

vi libs/plugins/function.mailto.php
[...]
    if ($encode == 'javascript' ) {
        $string = 'document.write(\'<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>\');';

        $js_encode = '';
        for ($x=0; $x < strlen($string); $x++) {
            $js_encode .= '%' . bin2hex($string[$x]);
        }

        return '<script type="text/javascript">eval(unescape(\''.$js_encode.'\'))</script>';

極める ! PHP

極める ! PHP