<-- IE錯誤修正 --> RiS社群 | FileMaker 中小企業應用 - 瀏覽單個文章 - 分享 實作 PHP 表單圖形驗證碼 CAPTCHA
瀏覽單個文章
  #1 (permalink)  
舊 2008-06-27
Bing 的頭像
Bing Bing 目前離線
論壇管理員
 
註冊日期: 2007-08-21
住址: 台北, 桃園, 台中(豐原區)
文章: 5,364
微笑 實作 PHP 表單圖形驗證碼 CAPTCHA

來源:小正正教室

Click the image to open in full size.
最近常常都會在網頁表單中看到類似這樣歪曲扭八亂碼的圖片,必須先輸入圖片中的文字或數字,才能正確的將表單資料送出。這是為了防止機器人程式不停 的送出表單所做的驗證,在會員註冊、登入、投票、訪客張貼文章以及網路ATM中都會經常看到這種圖形驗證的表單欄位 (英文縮寫為 captcha )。如果你自己網站的表單也想加入這樣的圖形驗證欄位,防止有心人士的騷擾,小正正教你最簡單實用的方式可以直接套用下面這個範例 !
下載完整範例檔案
加入圖形驗證欄位

1. 首先在網頁中有一個表單 form,表單裡面可以有很多不同的欄位,再多加上一個輸入驗證碼的文字欄位,以及一個驗證碼的圖形。例如下面這樣的 HTML 碼 ( 你可以參照範例檔案中的 imgcheck_form.html):
Click the image to open in full size.
請特別注意幾個地方:
  • 表單動作送出的頁面為 imgcheck.php,這是接收表單資料以及檢查驗證碼的 PHP 頁面。
  • 輸入驗證碼的文字欄位名稱為 checknum,在檢查驗證碼時會用到。
  • 驗證碼圖形的來源 src 為 showrandimg.php,這是主要產生出驗證碼圖形的 PHP 程式,稍後會使用到。
這時在瀏覽器中看起來會像是下面這樣,當然圖片還沒有產生出來:
Click the image to open in full size.
2. 將這個表單頁面,以及範例檔案中的 showrandimg.php 一起上傳到支援 PHP 的網站伺服器上,放在同一個資料夾中。
因為是由 showrandimg.php 這個程式來產生出隨機亂數的驗證碼圖形,所以一定要在支援 PHP 的網站伺服器環境下才能夠運作。如果你自己的電腦中有安裝 Apache 和 PHP 也是可以在自己的電腦中測試,記得要放到網站根目錄以下。
3. 在瀏覽器中輸入剛剛上傳的表單的網址 (例如 http://localhost/imgcheck_form.html ) 就可以看到驗證碼的圖片了!
Click the image to open in full size.

檢查驗證碼

接著來處理接收表單資料、檢查所輸入的驗證碼是否正確的部份。
1. 開啟接收表單資料的那一頁 (例如範例中的 imgcheck.php ),在頁面的一開頭加入這段 PHP 程式碼來檢查:
Click the image to open in full size.
首先呼叫 Session_start() 來啟動這一頁的 Session,因為正確的圖形驗證碼是儲存在 Session 中的。
然後用 if 來檢查表單欄位中所輸入的驗證碼,也就是變數 $_POST['checknum'] 和儲存在 Session 中的正確驗證碼,也就是變數 $_SESSION["Checknum"] 是否相同。相同的話就顯示一種訊息文字、不同的話就顯示另一種訊息文字。
當然你也會需要再這一頁中自行加入一些處理資料或存取資料庫的 PHP 程式碼。
在這裡要特別注意的是:$_POST['checknum'] 的變數名稱 checknum 是上一個頁面表單中的文字欄位名稱。而 $_SESSION["Checknum"] 則是寫在產生出驗證碼圖形的 showrandimg.php 程式裡面,稍後再教大家怎麼去修改。PHP 程式是會區分大小寫的,也請特別注意!
2. 然後在同一頁的 HTML 內容中你可以使用這段 PHP 程式來輸出訊息文字:
Click the image to open in full size.
3. 最後將這一頁 ( imgcheck.php ) 存檔,一起上傳到伺服器上,和其他兩個頁面放在同一個資料夾中,就可以開始測試了!測試的時候先瀏覽表單頁面,輸入正確或不正確的驗證碼再送出表單,便能夠看到檢查的結果囉!

自訂驗證碼圖形

你可能會想要自行調整驗證碼圖形,例如幾位數字和圖形的大小等等,這些都是寫在 showrandimg.php 裡面。用 Dreamweaver 或純文字編輯器開啟 showrandimg.php 來編輯,找到下面這幾行:
$num="";
$num_max = 6;
$img_height = 25;
$img_width = 80;
$mass = 200;

說明如下:
$num 不要去更改。
$num_max 寫 6 代表 6 位數字的驗證碼,如果只需要 4 位數就改為 4 即可,依此類推。
$img_height 是圖片的高度。
$img_width 是圖片的寬度,你可以依照驗證碼有幾位數字自行調整。
$mass = 雜點的數量,數字愈大愈不容易辨識。
如果你想要更改 Session 變數的名稱,找到下面這兩行:
Session_start();
$_SESSION["Checknum"] = $num;

$_SESSION["Checknum"] 裡面的 Checknum 改為自己想要的變數名稱即可,修改後表單檢查的頁面也要一起跟著修改。請注意大小寫哦!
如果你要更改文字和背景的顏色,找到下面這兩行:
$black = ImageColorAllocate($im, 0,0,0);
$gray = ImageColorAllocate($im, 200,200,200);

原本預設文字是黑色 0,0,0、背景是灰色 200,200,200。這三組數字分別是 RGB 0~255 的數值,你可以自行修改為自己喜歡的顏色,例如 100,255,100。

重新產生驗證碼

有時候驗證碼真的很難辨識,怎麼看也看不懂,我們希望不需要重新整理整個頁面,只要重新產生出新的圖形驗證碼,這時候就需要 Javascript 來幫忙了。(如果不需要重新產生,可以不用加入這段 Javascript )
1. 首先在驗證碼圖形的後面加入一個文字超連結 "重新產生":
Click the image to open in full size.
我們幫圖片和超連結都分別取了 id 名稱,是為了方便讓 Javascript 使用。
2. 在整個頁面的最後,最好是結束的 前面,加入下面這段 Javascript:
Click the image to open in full size.
程式碼中都有註解,小正正就不再一一解釋了,只要注意幾個重點:
a. 不要把事件 onclick 的 Javascript 寫在 HTML 裡面,例如:
< a href="#" id="reload-img" onclick="reloadImg();return false;" >重新產生< /a>
如此一來 HTML 和 Javascript 便會混在一起,變得很難維護,也不符合 LSM 的作法。應該要在 Javascript 的程式碼區塊中用 getElementById (或其他 DOM 方法) 來取得超連結元素,然後再去定義它的事件:
var dReloadLink = document.getElementById("reload-img");
dReloadLink.onclick = function(e) { ... };

這樣才符合 LSM 以及非侵入式 Javascript ( Unobtrusive Javascript ) 的作法。
b. 為了變數命名空間 (Namespace) 的考量,將整段 Javascript 前後用匿名函數包起來:
(function(){ .... })();
如此一來這個匿名函數內所使用的變數名稱,就不會和頁面中其他 Javascript 程式的變數名稱,或者你所載入的其他 Javascript 函式庫的變數名稱互相衝突了!
通常定義函數是這樣寫的:function(){ .... }
但函數不呼叫它的話,是不會自己執行的。所以在多加了幾個括號直接呼叫這個匿名函數:(function(){ .... })();
這是很有技巧的一招,大家要學起來!
c. 重新載入圖形的程式碼將它獨立成一個函數 reloadImg 是為了日後能夠讓其他程式重複呼叫使用,只要先取得任何一個圖形元素,作為參數傳入就可以重新載入該圖形。這個函數只是很簡單的在原本圖形來源的 URL 後面加上 ?rnd=0.1234567 之類的亂數參數,讓瀏覽器以為是不同的圖形而重新載入。如果原本的圖形 URL 後面就已經有問號和其他參數的話,就得將 ?rnd= 改為 &rnd= 了,這部份留給你自己練習吧!
d. 通常超連結都會有預設的事件動作,按下超連結時應該要前往到連結的網址,網址如果是 # 的話也會跳到頁面的最開頭。為了防止這個預設的動作發生,在 onclick 事件的最後加上了:
if(e) e.preventDefault();
return false;

e.preventDefault() 是給 Firefox 看的,return false 是 IE 用的。

更多資源

圖形驗證碼 (captcha) 很多種,是否容易被機器人程式自動辨識,各家都有自己的訣竅。搜尋一下 captcha圖形驗證碼 這幾個關鍵字可以找到更多有用的資訊哦!

回覆時引用此篇文章