Do You PHP?    
Search Engine Optimization  php5 powerd  Valid XHTML 1.0!  Valid CSS!  このサイトのはてなブックマーク数 



last updated
2005/06/10

counter hits
since 1999/11/06


PEAR::Text_CAPTCHAでCAPTCHA

何年かぶりのGDネタです。最近のコメントSPAM(掲示板荒らし)対策として「イメージに書かれたグニャ~と歪んだ文字をテキストボックスに入力してください」といったものがありますが、このチャレンジ/レスポンス型テストをCAPTCHA(completely automated public Turing test to tell computers and humans apart:コンピュータと人間を区別する完全に自動化された公開チューリングテスト)と呼ぶようです。

スクリプトなど非人間系で行われるコメントSPAMに対しては有効な手段と思いますが、画像を見ることができないユーザにとってはやはりアクセシビリティがない、という問題にも注意を向けるべきでしょう。

こういった特徴のCAPTCHAですがphp.netでもサイトの一部に使われており(どこか忘れてしまいました。。。)、2005/06/10現在まだα版ですがPEARライブラリにも追加されています。

α版なので当然ドキュメントが全くと言っていいほど整備されていませんが、ソースにサンプルスクリプトがありますのでそれを試してみました。

PEAR::Text_CAPTCHAを使用するには、(当然ながら)GD拡張が必要になります。GD拡張はFreeType/FreeType2を使用したTrueTypeフォントをサポートする必要があります。FreeTypeの場合は「--with-ttf」、FreeType2の場合は「--with-freetype-dir」の各configureオプションを付けてbuildしたPHPが必要です。今回は以下のオプションを付けたPHP4.3.11を使用しました。

●configureオプション
./configure \
--with-apxs2=/usr/local/apache2/bin/apxs \
--prefix=/usr/local/lib/php4 \
--with-pear=/usr/local/lib/php4/pear \
--with-config-file-path=/usr/local/lib/php4/ini/4.3.11 \
--with-config-file-scan-dir=/usr/local/lib/php4/ini.d \
--enable-zend-multibyte \
--enable-mbstring \
--enable-mbregex \
--with-dom \
--with-gd=shared \
--with-jpeg-dir \
--with-png-dir \
--with-zlib-dir \
--with-ttf \
--with-freetype-dir \
--enable-gd-jis-conv \
--with-java=shared,/usr/local/jdk \
--enable-xslt \
--with-xslt-sablot \
--with-expat-dir=/usr \
--with-oci8=/u01/app/oracle/product/10.1.0

また、PEAR::Text_CAPTCHAをインストールすることになりますが、PEAR::Image_Text、PEAR::Text_Passwordの各パッケージに依存していますので、これらのパッケージも併せてインストールする必要がなります。なお、今回GD拡張を「shared」としてインストールしましたので、php.ini内でextensionディレクティブを使ってgd.soを指定しておく必要があります(当然、PHP本体に組み込んだ場合は必要ありません)。また、extension_dirディレクティブの設定は、環境によって異なりますので注意してください。

●php.iniの設定(--with-gd=sharedの場合のみ)
extension_dir = "/usr/local/lib/php4/lib/php/extensions/no-debug-non-zts-20020429/"
extension=gd.so
●PEAR::Text_CAPTCHAのインストール
$ /usr/local/lib/php4/bin/pear config-set preferred_state alpha
$ /usr/local/lib/php4/bin/pear install --alldeps text_captcha
downloading Text_CAPTCHA-0.1.2.tgz ...
Starting to download Text_CAPTCHA-0.1.2.tgz (3,827 bytes)
....done: 3,827 bytes
downloading Text_Password-1.0.tgz ...
Starting to download Text_Password-1.0.tgz (3,707 bytes)
...done: 3,707 bytes
downloading Image_Text-0.5.2beta2.tgz ...
Starting to download Image_Text-0.5.2beta2.tgz (12,603 bytes)
...done: 12,603 bytes
install ok: Image_Text 0.5.2beta2
install ok: Text_Password 1.0
install ok: Text_CAPTCHA 0.1.2
$ 

インストール後PEARディレクトリ直下のTextディレクトリにCAPTCHA.phpがありますので、先頭のコメント部分に以下のようなサンプルコードがあります。

  
<?php
if (!function_exists('file_put_contents')) {
    function file_put_contents($filename, $content, $flags = 0) {
        if (!($file = fopen($filename, ($flags & 1) ? 'a' : 'w'))) {
            return false;
        }
        $n = fwrite($file, $content);
        fclose($file);
        return $n ? $n : false;
    }
}

// Start PHP session support
session_start();

$ok = false;

$msg = "Please enter the text in the image in the field below!";

if ($_SERVER['REQUEST_METHOD'] == 'POST') {

    if (isset($_POST['phrase']) && isset($_SESSION['phrase']) &&
        strlen($_POST['phrase']) > 0 && strlen($_SESSION['phrase']) > 0 &&
        $_POST['phrase'] == $_SESSION['phrase']) {
        $msg = 'OK!';
        $ok = true;
    } else {
        $msg = 'Please try again!';
    }

    unlink(session_id() . '.png');

}

print "<p>$msg</p>";

if (!$ok) {

    require_once 'Text/CAPTCHA.php';

    // Generate a new Text_CAPTCHA object, Image driver
    $c = Text_CAPTCHA::factory('Image');
    $c->init(200, 80);

    // Get CAPTCHA secret passphrase
    $_SESSION['phrase'] = $c->getPhrase();

    // Get CAPTCHA image (as PNG)
    file_put_contents(session_id() . '.png', $c->getCAPTCHAAsPNG());

    echo "<form method=\"POST\">" .
         "<img src=\"" . session_id() . ".png?" . time() . "\" />" .
         "<input type=\"text\" name=\"phrase\" />" .
         "<input type=\"submit\" /></form>";
}
?>

ただし、これを実行しても使用するフォントの設定が(ほとんどの場合)正しくありませんので、残念ながらイメージは作成されません。これは内部で使用しているPEAR::Image_Textのデフォルト値になってしまうためですが、PEAR::Text_CAPTCHAのfactoryメソッドから返されるText_CAPTCHA_Driver_Imageオブジェクトのinitメソッドにオプションを渡すことで解決します。

具体的には、

    $c->init(200, 80);

の行を

    $c->init(200, 80, NULL, array("font_path"=>"/usr/X11R6/lib/X11/fonts/TrueType/",
                                  "font_file"=>"kochi-gothic.ttf"));

などフォントファイルへのパスとフォントファイル名を指定することで

作成されたイメージ

のようなイメージファイルが作成される。。。ハズですが、このサンプル自体がPHPスクリプトと同じディレクトリに実際のイメージを保存してそれを<img>タグで読み込む造りになっているので、適宜ディレクトリのpermissionを変更しておいてください。

なお、initメソッドに渡すオプションは最終的にPEAR::Image_Textのコンストラクタに渡されます。詳細についてはPEAR::Text_CAPTCHAではなくPEAR::Image_TextのAPIドキュメント、あるいはソースを参照してください。

ちなみにphp.netで使用されているCAPTCHA用のソースはPEAR::Text_CAPTCHAを使用せずに独自のコードを書いているようです。こちらの場合、

作成されたイメージ

のようにPEAR::Text_CAPTCHAよりもちょっとだけグニャ~となります。詳細はCVSのソースコードを。。。(^-^;



About This Site |  Privacy Policy |  Contact
Copyright © 1999 - 2005 by Hideyuki SHIMOOKA all rights reserved.