背景
驗證碼就是把一串隨機(jī)產(chǎn)品的數(shù)字動態(tài)生成一幅圖片,再加上干擾元素。此時用戶可以通過肉眼能識別里面的數(shù)字或者字符,但是可以屏蔽機(jī)器的自動識別。
很多地方需要用到驗證碼,因為Web網(wǎng)站經(jīng)常會遇到身份欺騙的攻擊,攻擊者通過在客戶端腳本寫入代碼,寫請求消耗遠(yuǎn)遠(yuǎn)大于讀請求。大量寫請求的情況,會嚴(yán)重耗費(fèi)系統(tǒng)的資源。所以說驗證碼主要是防止有人利用機(jī)器人進(jìn)行自動批量注冊等行為。
筆者看過了http://www.imooc.com/learn/115
的視頻教程以后非常有感觸,想把實(shí)現(xiàn)驗證碼的步驟一步一步的記錄下來。同時最后的時候他封裝成類,可以在之后的工作中進(jìn)行反復(fù)的利用。
其實(shí)驗證碼的代碼已經(jīng)研究了很多次了,但是大部分網(wǎng)上找到的教程都是一次性給出所有的代碼,這樣閱讀的時候很難把握住筆者的開發(fā)思路,本教程希望一步一步的截圖上代碼,幫助新人理清思路。
驗證碼的核心技術(shù)
首先需要對實(shí)現(xiàn)驗證碼的步驟進(jìn)行分解。主要可以分為如下幾步:
- 生成驗證碼底圖
- 生成隨機(jī)字符,然后和底圖合并
- 當(dāng)用戶輸入的時候,和原內(nèi)容進(jìn)行對比校驗。
接下來我們分不同的章節(jié)介紹如何實(shí)現(xiàn)每一個步驟。
環(huán)境
項目 | 內(nèi)容 |
---|---|
操作系統(tǒng) | windows |
環(huán)境 | xamp |
需要啟動Apache,驗證方法是在瀏覽器框里輸入127.0.0.1
如果出現(xiàn)如下的圖片,則啟動成功。
實(shí)現(xiàn)驗證碼底圖
首先是通過PHP實(shí)現(xiàn)100×30px大小的圖片。
主要使用的函數(shù)方法:resource imagecreatetruecolor(int $width, int $height)
在D:\xampp\htdocs下建立project文件夾。新建captcha.php
輸入:
<?php $image = imagecreatetruecolor(100,30);//生成資源 $bgcolor = imagecolorallocate($image , 255,255,255);//#ffffff,為一幅圖像分配顏色 imagefill($image , 0 , 0 , $bgcolor);//左上角,區(qū)域填充 header("content-type:image/png"); imagepng($image); imagedestroy($image); ?>
在瀏覽器輸入框輸入http://127.0.0.1/project/captcha.php
結(jié)果是一片大白。
下面解釋一下里面涉及到的函數(shù):
項目 | 內(nèi)容 |
---|---|
imagecreatetruecolor | 生成空白的畫布 |
imagecolorallocate | 分配顏色 |
imagefill | 填充顏色 |
header | 發(fā)送HTTP頭 |
imagepng | 以png格式進(jìn)行導(dǎo)出 |
imagedestory | 輸出結(jié)束的時候記得回收資源 |
為了表明各函數(shù)用法,特將PHP手冊中的詳細(xì)用法摘錄如下:
- imagecreatetruecolor — 新建一個真彩色圖像
resource imagecreatetruecolor ( int $width , int $height )
- imagecolorallocate — 為一幅圖像分配顏色
int imagecolorallocate ( resource $image , int $red , int $green , int $blue )
第一次對 imagecolorallocate() 的調(diào)用會給基于調(diào)色板的圖像填充背景色,即用 imagecreate() 建立的圖像。
其他red,green,blue對應(yīng)RGB值 - imagefill — 區(qū)域填充
bool imagefill ( resource $image , int $x , int $y , int $color )
imagefill() 在 image 圖像的坐標(biāo) x,y(圖像左上角為 0, 0)處用 color 顏色執(zhí)行區(qū)域填充(即與 x, y 點(diǎn)顏色相同且相鄰的點(diǎn)都會被填充)。 - header — 發(fā)送原生 HTTP 頭
void header ( string $string [, bool $replace = true [, int $http_response_code ]] )
請注意 header() 必須在任何實(shí)際輸出之前調(diào)用 - imagepng — 以 PNG 格式將圖像輸出到瀏覽器或文件
bool imagepng ( resource $image [, string $filename ] )
- imagedestroy — 銷毀圖片資源
bool imagedestroy ( resource $image )
注意事項:
- 依賴于GD擴(kuò)展,輸出圖片前必須提前輸出圖片header信息
- 默認(rèn)輸出為黑色背景。
實(shí)現(xiàn)數(shù)字驗證碼
在上一章里面我們已經(jīng)新建了一張畫布,相當(dāng)于把整個框架搭起來了,本章的主要目的是在上面加上隨機(jī)的數(shù)字。
給圖片加上數(shù)字,主要使用imagestring()方法。
imagestring — Draw a string horizontally
bool imagestring ( resource $image , int $font , int $x , int $y , string $string , int $color )
- font:表示字體,
- x,y:表示位置
從上面這個函數(shù)的參數(shù)可以看出,我們需要給出生成隨機(jī)驗證碼數(shù)字的字體,位置,內(nèi)容和顏色。
字體是死的,可以直接規(guī)定大小。
因為要生成4個隨機(jī)數(shù)字,可以使用一個for循環(huán)for ($i = 0 ; $i < 4 ; $i++)
。
下面討論怎么獲得位置信息:
可以把長度100分成4份,所以每個數(shù)字的位置是($i * 100 / 4 )
,然后加上隨機(jī)的offset,可以得到
$x = ($i * 100 / 4 ) + rand (5,10);
內(nèi)容通過:$fontContent = rand (0,9);
獲得。
最后是怎么獲得隨機(jī)的顏色:
對于imagecolorallocate()這個函數(shù)而言,只需要獲得隨機(jī)的RGB值,就可以實(shí)現(xiàn)隨機(jī)的顏色了。為了更加醒目,我們限定隨機(jī)RGB值的范圍為0~120,因為是深色區(qū)間。
$fontColor = imagecolorallocate($image , rand(0,120) , rand(0,120), rand(0,120));//0~120是深色區(qū)間。
下面加上生成隨機(jī)數(shù)字的代碼段,在imagefill()那行下面加入:
<?php $image = imagecreatetruecolor(100,30);//生成資源 $bgcolor = imagecolorallocate($image , 255,255,255);//#ffffff,為一幅圖像分配顏色 imagefill($image , 0 , 0 , $bgcolor);//左上角,區(qū)域填充 // 生成隨機(jī)數(shù)字 for ($i = 0 ; $i < 4 ; $i++){ $fontSize = 6; $fontColor = imagecolorallocate($image , rand(0,120) , rand(0,120), rand(0,120));//0~120是深色區(qū)間。 $fontContent = rand (0,9); // 坐標(biāo) $x = ($i * 100 / 4 ) + rand (5,10);//總寬度100,放4個數(shù)字。 $y = rand (5 , 10); imagestring ($image,$fontSize,$x,$y,$fontContent,$fontColor); } header("content-type:image/png"); imagepng($image); imagedestroy($image); ?>
在地址欄里面輸入127.0.0.1/project/captcha.php
可以看出生成了4個隨機(jī)的數(shù)字。
增加干擾元素
為了防止被機(jī)器輕易的讀出來,可以增加干擾的元素。
先增加干擾的小點(diǎn),用到函數(shù)
bool imagesetpixel(resource $image , int $x , int $y , int $color)
首先看點(diǎn)的位置怎么得到。
既然是隨機(jī)生成用來干擾的點(diǎn),那么可以在整個畫布隨機(jī)的跑,所以x = rand (1 , 99); y = rand (1 , 29)
而點(diǎn)的顏色注意要比字的淺,所以在50~200中選。
上代碼,增加200個點(diǎn)。
<?php $image = imagecreatetruecolor(100,30);//生成資源 $bgcolor = imagecolorallocate($image , 255,255,255);//#ffffff,為一幅圖像分配顏色 imagefill($image , 0 , 0 , $bgcolor);//左上角,區(qū)域填充 for ($i = 0 ; $i < 4 ; $i++){ $fontSize = 6; $fontColor = imagecolorallocate($image , rand(0,120) , rand(0,120), rand(0,120));//0~120是深色區(qū)間。 $fontContent = rand (0,9); // 坐標(biāo) $x = ($i * 100 / 4 ) + rand (5,10);//總寬度100,放4個數(shù)字。 $y = rand (5 , 10); imagestring ($image,$fontSize,$x,$y,$fontContent,$fontColor); } for ($i = 0 ; $i < 200 ; $i++){ $pointColor = imagecolorallocate ($image , rand (50,200),rand(50,200),rand(50,200));//顏色要比數(shù)字的淺。 imagesetpixel ($image , rand (1,99),rand(1,29),$pointColor);//生成的點(diǎn)不要超過畫布。 } header("content-type:image/png"); imagepng($image); imagedestroy($image); ?>
依舊看看效果:
再加點(diǎn)隨機(jī)的線:
使用方法:bool imageline (resource $image , int $x1 , int $y1 , int $x2 , int $y2 , int $color)
手冊上的解釋是:
Draws a line between the two given points.
也就是說在給出的兩點(diǎn)間畫線。
注意隨機(jī)線的顏色比隨機(jī)點(diǎn)的顏色要更淺,所以在80~220里面選。
下面給出加隨機(jī)線的代碼:
// 生成干擾線 for ( $i = 0 ; $i < 3 ; $i++){ $lineColor = imagecolorallocate($image , rand (80,220),rand(80,220),rand(80,220)); imageline($image , rand (1,99),rand(1,29),rand(1,99),rand(1,29),$lineColor); }
結(jié)果如圖:
生成隨機(jī)的字母和數(shù)字
之前生成的內(nèi)容只有隨機(jī)的數(shù)字,還是容易被機(jī)器識別出來,所謂道高一尺魔高一丈,對手在加碼,我們也得加碼撒。下面我們在隨機(jī)的內(nèi)容里面加上字母,這樣組合更多,可以更好的屏蔽那些機(jī)器人。
首先我們把可能用到的字母和數(shù)字放到變量$data里面去,注意可以把容易混淆的字母和數(shù)字去掉,比如l和數(shù)字1容易混,所以直接干掉。
然后每次隨機(jī)的從字符串里面抽一個出來,使用substr函數(shù)。
string substr ( string $string , int $start [, int $length ] )
從$string里$start位置抽出$length長的字符。
這樣對原有的代碼進(jìn)行簡單的修改就可以了。
<?php $image = imagecreatetruecolor(100,30);//生成資源 $bgcolor = imagecolorallocate($image , 255,255,255);//#ffffff,為一幅圖像分配顏色 imagefill($image , 0 , 0 , $bgcolor);//左上角,區(qū)域填充 // 生成隨機(jī)數(shù)字 for ($i = 0 ; $i < 4 ; $i++){ $fontSize = 6; $fontColor = imagecolorallocate($image , rand(0,120) , rand(0,120), rand(0,120));//0~120是深色區(qū)間。 // $fontContent = rand (0,9); $data = "abcdefghijkmnopqrstuvwxyz23456789"; // 生成隨機(jī)的字母和數(shù)字,從$data字符串里面,任意一個位置,取一個字母 $fontContent = substr($data , rand(0,strlen($data)), 1); // 坐標(biāo) $x = ($i * 100 / 4 ) + rand (5,10);//總寬度100,放4個數(shù)字。 $y = rand (5 , 10); imagestring ($image,$fontSize,$x,$y,$fontContent,$fontColor); } for ($i = 0 ; $i < 200 ; $i++){ $pointColor = imagecolorallocate ($image , rand (50,200),rand(50,200),rand(50,200));//顏色要比數(shù)字的淺。 imagesetpixel ($image , rand (1,99),rand(1,29),$pointColor);//生成的點(diǎn)不要超過畫布。 } // 生成干擾線 for ( $i = 0 ; $i < 3 ; $i++){ $lineColor = imagecolorallocate($image , rand (80,220),rand(80,220),rand(80,220)); imageline($image , rand (1,99),rand(1,29),rand(1,99),rand(1,29),$lineColor); } header("content-type:image/png"); imagepng($image); imagedestroy($image); ?>
效果如圖
通過session存儲驗證信息
session是存儲的服務(wù)器端的信息,可以把生成的內(nèi)容保存在服務(wù)器端的$_SESSION["authcode"]字段里面。當(dāng)前端的用戶輸入相應(yīng)的驗證字符后,和$_SESSION["authcode"]進(jìn)行對比,如果相同,自然證明輸入正確、
需要在代碼的最頂部加上session_start()
現(xiàn)在要考慮如何保存保存驗證碼的信息,先定義一個$captch_code 的空字符串,每生成一的隨機(jī)的數(shù)字或者字符,都拼接到上面去。
其實(shí)在真實(shí)的開發(fā)環(huán)境下,我們都是用服務(wù)器的集群來保存session的,也就是說有可能第一次請求的時候建立的session保存在A服務(wù)器上,但是下次需要來拿數(shù)據(jù)的時候會被分配到B服務(wù)器上,所以校驗會失敗。在多服務(wù)器的情況下,我們需要考慮集中管理session,比如使用memcache來保存session信息。
<?php session_start(); $image = imagecreatetruecolor(100,30);//生成資源 $bgcolor = imagecolorallocate($image , 255,255,255);//#ffffff,為一幅圖像分配顏色 imagefill($image , 0 , 0 , $bgcolor);//左上角,區(qū)域填充 // 生成隨機(jī)數(shù)字 $captch_code = ""; for ($i = 0 ; $i < 4 ; $i++){ $fontSize = 6; $fontColor = imagecolorallocate($image , rand(0,120) , rand(0,120), rand(0,120));//0~120是深色區(qū)間。 // $fontContent = rand (0,9); $data = "abcdefghijkmnopqrstuvwxyz23456789"; // 生成隨機(jī)的字母和數(shù)字,從$data字符串里面,任意一個位置,取一個字母 $fontContent = substr($data , rand(0,strlen($data)), 1); $captch_code .= $fontContent; // 坐標(biāo) $x = ($i * 100 / 4 ) + rand (5,10);//總寬度100,放4個數(shù)字。 $y = rand (5 , 10); imagestring ($image,$fontSize,$x,$y,$fontContent,$fontColor); } // 將循環(huán)生成的隨機(jī)數(shù)字保存在$_SESSION里面 $_SESSION['authcode'] = $captch_code; for ($i = 0 ; $i < 200 ; $i++){ $pointColor = imagecolorallocate ($image , rand (50,200),rand(50,200),rand(50,200));//顏色要比數(shù)字的淺。 imagesetpixel ($image , rand (1,99),rand(1,29),$pointColor);//生成的點(diǎn)不要超過畫布。 } // 生成干擾線 for ( $i = 0 ; $i < 3 ; $i++){ $lineColor = imagecolorallocate($image , rand (80,220),rand(80,220),rand(80,220)); imageline($image , rand (1,99),rand(1,29),rand(1,99),rand(1,29),$lineColor); } header("content-type:image/png"); imagepng($image); imagedestroy($image); ?>
驗證碼通過表單進(jìn)行提交
在project文件夾里面新建form.php
輸入
<pre>
<?php?>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>確認(rèn)驗證碼</title>
</head>
</pre>
<body> <form action="./form.php" method="post"> <p>驗證圖片:</p> <p>請輸入圖片中的內(nèi)容:<input type="text" name="authcode" value=""/></p> <p><input type="submit" value="提交" style="padding:6px 20px;"/></p> </form> </body> </html>
表單提交的內(nèi)容都會存到$_REQUEST['authcode']里面,所以需要加上驗證表單提交和$_SESSION[‘a(chǎn)uthcode’]是否相同的代碼。
<pre>
<?php
if (isset($_REQUEST['authcode'])){
session_start();
if($_REQUEST['authcode'] == $_SESSION['authcode']){
echo '<font color="#0000CC">輸入正確</font>';
}else{
echo '<font color = "#CC0000"><b>輸入錯誤</b></font>';
}
exit();
}
?>
</pre>
此時在地址欄輸入127.0.0.1/project/form.php,然后填入驗證碼字符
點(diǎn)擊提交按鈕。
但是如果是輸入全大寫的字母,會輸出“輸入錯誤”的標(biāo)志。
因為我們在判斷的時候是把原始輸入和服務(wù)器保存的進(jìn)行比較,所以自然需要完全一致才行。
可以把用戶的輸入全部轉(zhuǎn)換為小寫
<pre>
<?php
if (isset($_REQUEST['authcode'])){
session_start();
if(strtolower(trim($_REQUEST['authcode'])) == $_SESSION['authcode']){
echo '<font color="#0000CC">輸入正確</font>';
}else{
echo '<font color = "#CC0000"><b>輸入錯誤</b></font>';
}
exit();
}
?>
</pre>
動態(tài)驗證
之前的代碼存在一個問題,如果出來的驗證碼圖片用戶不能完全分辨得出,就沒有辦法了。在生活中,一般的驗證碼圖片旁邊都會有“看不清?”這樣的提示,點(diǎn)擊的話,會刷新驗證碼。
可以通過三個步驟進(jìn)行:
- 增加可點(diǎn)擊的“換一個”文案
- 用JS選擇器選取圖片
- 用js修改驗證碼圖片地址
首先增加文案
<pre>
<a href="javascript:void(0)">換一個?</a>
</pre>
為了方便選取圖片,給img加上id屬性,使用document.getElementById('captch_img')獲得圖片,然后用新的圖片對他進(jìn)行賦值,注意可以加上一段隨機(jī)數(shù)字。
<pre>
<?php
if (isset($_REQUEST['authcode'])){
session_start();
if(strtolower(trim($_REQUEST['authcode'])) == $_SESSION['authcode']){
echo '<font color="#0000CC">輸入正確</font>';
}else{
echo '<font color = "#CC0000"><b>輸入錯誤</b></font>';
}
exit();
}
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>確認(rèn)驗證碼</title>
</head>
<body>
<form action="./form.php" method="post">
<p>驗證圖片:<img id="captcha_img" border="1" src="./captcha.php?r=<?php echo rand();?>" width="100" heigh="30">
<a href="javascript:void(0)" onclick="document.getElementById('captcha_img').src='./captcha.php?r='+Math.random()">換一個?</a>
</p>
<p>請輸入圖片中的內(nèi)容:<input type="text" name="authcode" value=""/></p>
<p><input type="submit" value="提交" style="padding:6px 20px;"/></p>
</form>
</body>
</html>
</pre>
至此驗證碼的功能基本都實(shí)現(xiàn)了,下面主要進(jìn)行類的封裝,以后可以多次的復(fù)用。
驗證碼類的封裝
首先考慮通用的驗證碼類里面有那些元素:
<pre>
class Vcode {
private $width; //驗證碼圖片的寬度
private $height; //驗證碼圖片的高度
private $codeNum; //驗證碼字符的個數(shù)
private $disturbColorNum; //干擾元素數(shù)量
private $checkCode; //驗證碼字符
private $image; //驗證碼資源
}
</pre>
然后寫構(gòu)造方法,主要用來實(shí)例化驗證碼對象,并為一些成員屬性初使化 。
在寫構(gòu)造方法之前,我們新定義一個內(nèi)部私有方法createCheckCode(),隨機(jī)生成用戶指定個數(shù)的字符串,去掉了容易混淆的字符oOLlz和數(shù)字012
<pre>
private function createCheckCode(){
$data="3456789abcdefghijkmnpqrstuvwxy";
for($i=0; $i<$this->codeNum; $i++) {
// $char = $code{rand(0,strlen($code)-1)};
$fontContent = substr($data , rand(0,strlen($data)), 1);
$captch_code .= $fontContent;
}
return $captch_code;
}
</pre>
然后開始寫構(gòu)造函數(shù):
<pre>
/**
* 構(gòu)造方法用來實(shí)例化驗證碼對象,并為一些成員屬性初使化
* @param int $width 設(shè)置驗證碼圖片的寬度,默認(rèn)寬度值為80像素
* @param int $height 設(shè)置驗證碼圖片的高度,默認(rèn)高度值為20像素
* @param int $codeNum 設(shè)置驗證碼中字母和數(shù)字的個數(shù),默認(rèn)個數(shù)為4個
/
function __construct($width=80, $height=20, $codeNum=4) {
$this->width = $width;
$this->height = $height;
$this->codeNum = $codeNum;
$number = floor($height$width/15);
//如果驗證碼字符過多,則需要減少干擾點(diǎn)的數(shù)量
if($number > 240-$codeNum)
$this->disturbColorNum = 240-$codeNum;
else
$this->disturbColorNum = $number;
$this->checkCode = $this->createCheckCode();
}
</pre>
我們之前講過輸出圖像有幾個步驟,首先新建畫布,然后生成干擾點(diǎn),再加上隨機(jī)的字符,最后輸出。可以把每個步驟包裝成一個方法,然后在outImg()里面統(tǒng)一調(diào)用。
-
新建畫布
<pre>
/* 內(nèi)部使用的私有方法,用來創(chuàng)建圖像資源,并初使化背影 */
private function getCreateImage(){
$this->image = imagecreatetruecolor($this->width,$this->height);$backColor = imagecolorallocate($this->image, rand(225,255),rand(225,255),rand(225,255)); @imagefill($this->image, 0, 0, $backColor); }
</pre>
設(shè)置干擾元素
<pre>
/* 內(nèi)部使用的私有方法,設(shè)置干擾像素,向圖像中輸出不同顏色的點(diǎn) */
private function setDisturbColor() {
// 畫隨機(jī)點(diǎn)
for($i=0; $i <= $this->disturbColorNum; $i++) {
$color = imagecolorallocate($this->image, rand(50,200), rand(50,200), rand(50,200));
imagesetpixel($this->image,rand(1,$this->width-2),rand(1,$this->height-2),$color);
}
// 畫隨機(jī)線
for($i=0; $i<10; $i++){
$color=imagecolorallocate($this->image,rand(80,220),rand(80,220),rand(80,220));
imageline($this->image,rand(-10,$this->width),rand(-10,$this->height),rand(30,300),rand(20,200),55,44,$color);
}
}
</pre>在圖片上寫字
<pre>
/* 內(nèi)部使用的私有方法,隨機(jī)顏色、隨機(jī)擺放、隨機(jī)字符串向圖像中輸出 /
private function outputText() {
for ($i=0; $i<=$this->codeNum; $i++) {
$fontcolor = imagecolorallocate($this->image, rand(0,128), rand(0,128), rand(0,128));
$fontSize = rand(3,5);
$x = floor($this->width/$this->codeNum)$i+3;
$y = rand(0,$this->height-imagefontheight($fontSize));
imagechar($this->image, $fontSize, $x, $y, $this->checkCode{$i}, $fontcolor);
}
}
</pre>
- 輸出圖像,
<pre>
/* 內(nèi)部使用的私有方法,自動檢測GD支持的圖像類型,并輸出圖像 */
private function outputImage(){
if(imagetypes() & IMG_GIF){
header("Content-type: image/gif");
imagegif($this->image);
}elseif(imagetypes() & IMG_JPG){
header("Content-type: image/jpeg");
imagejpeg($this->image, "", 0.5);
}elseif(imagetypes() & IMG_PNG){
header("Content-type: image/png");
imagepng($this->image);
}elseif(imagetypes() & IMG_WBMP){
header("Content-type: image/vnd.wap.wbmp");
imagewbmp($this->image);
}else{
die("PHP不支持圖像創(chuàng)建!");
}
}
</pre>
- 使用outImg()函數(shù)統(tǒng)一起來
<pre>
/* 內(nèi)部使用的私有方法,用于輸出圖像 */
private function outImg(){
$this->getCreateImage();
$this->setDisturbColor();
$this->outputText();
$this->outputImage();
}
</pre>
向服務(wù)器SESSION中保存驗證碼
<pre>
/**
* 用于輸出驗證碼圖片,也向服務(wù)器的SESSION中保存了驗證碼,使用echo 輸出對象即可
/
function __toString(){
/ 加到session中, 存儲下標(biāo)為code */
$_SESSION["code"] = strtoupper($this->checkCode);
$this->outImg();
return '';
}
</pre>析構(gòu)函數(shù)
<pre>
/* 析構(gòu)方法,在對象結(jié)束之前自動銷毀圖像資源釋放內(nèi)存 */
function __destruct(){
imagedestroy($this->image);
}
</pre>
至此驗證碼類已經(jīng)完成,只要直接輸出對象,就可以向瀏覽器中輸出圖片,可以在表單中使用。
在提交驗證碼到服務(wù)器的時候,已經(jīng)轉(zhuǎn)為了大寫,需要在驗證的時候把瀏覽器提交的也轉(zhuǎn)換為大寫。
應(yīng)用驗證碼類
新建imgcode.php文件,使用session_start()開啟回話控制,同時創(chuàng)建類的對象。
此時如果使用echo輸出,同時會自動將驗證碼字符串保存在服務(wù)器中。
<pre>
<?php
/**
file:imgcode.php
用于請求時,通過驗證碼類的對象向客戶端輸出圖片
*/
session_start(); //開啟SESSION,會使用$_SESSION["code"]在服務(wù)器中保存驗證碼
require_once('captch.class.php'); //包含驗證碼所在的類文件
echo new Vcode(); //創(chuàng)建驗證碼對象,并直接被輸出自動調(diào)用魔術(shù)__toString()方法
</pre>
構(gòu)造表單,應(yīng)用驗證碼
在form.php中,包含輸入表單和匹配驗證碼兩部分。
<pre>
<?php
/** form.php 用于輸出用戶操作表單和驗證用戶的輸入 /
session_start(); //開啟SESSION
if(isset($_POST['submit'])){ //判斷用戶提交后執(zhí)行
/ 判斷用戶在表單中輸入的字符串和驗證碼圖片中的字符串是否相同 /
if(strtoupper(trim($_POST["code"])) == $_SESSION['code']){ //如果驗證碼輸出成功
echo '驗證碼輸入成功
'; //輸出成功的提示信息
}else{ //如果驗證碼輸入失敗
echo '<font color="red">驗證碼輸入錯誤!!</font>
'; //輸出失敗的輸入信息
}
}
?>
<html>
<head>
<title>Image</title>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<script>
/ 定義一個JavaScript函數(shù),當(dāng)單擊驗證碼時被調(diào)用,將重新請求并獲取一個新的圖片 /
function newgdcode(obj,url) {
/ 后面?zhèn)鬟f一個隨機(jī)參數(shù),否則在IE7和火狐下,不刷新圖片 */
obj.src = url+ '?nowtime=' + new Date().getTime();
}
</script>
</head>
<body>  <form method="POST" action="form.php"> <input type="text" size="4" name="code" /> <input type="submit" name="submit" value="提交"> </form> </body> </html>