背景
驗證碼就是把一串隨機產(chǎn)品的數(shù)字動態(tài)生成一幅圖片彤恶,再加上干擾元素。此時用戶可以通過肉眼能識別里面的數(shù)字或者字符,但是可以屏蔽機器的自動識別伍俘。
很多地方需要用到驗證碼,因為Web網(wǎng)站經(jīng)常會遇到身份欺騙的攻擊勉躺,攻擊者通過在客戶端腳本寫入代碼癌瘾,寫請求消耗遠遠大于讀請求。大量寫請求的情況饵溅,會嚴重耗費系統(tǒng)的資源妨退。所以說驗證碼主要是防止有人利用機器人進行自動批量注冊等行為。
筆者看過了http://www.imooc.com/learn/115
的視頻教程以后非常有感觸概说,想把實現(xiàn)驗證碼的步驟一步一步的記錄下來碧注。同時最后的時候他封裝成類,可以在之后的工作中進行反復的利用糖赔。
其實驗證碼的代碼已經(jīng)研究了很多次了萍丐,但是大部分網(wǎng)上找到的教程都是一次性給出所有的代碼,這樣閱讀的時候很難把握住筆者的開發(fā)思路放典,本教程希望一步一步的截圖上代碼逝变,幫助新人理清思路基茵。
驗證碼的核心技術
首先需要對實現(xiàn)驗證碼的步驟進行分解。主要可以分為如下幾步:
- 生成驗證碼底圖
- 生成隨機字符壳影,然后和底圖合并
- 當用戶輸入的時候拱层,和原內(nèi)容進行對比校驗。
接下來我們分不同的章節(jié)介紹如何實現(xiàn)每一個步驟宴咧。
環(huán)境
項目 | 內(nèi)容 |
---|---|
操作系統(tǒng) | windows |
環(huán)境 | xamp |
需要啟動Apache根灯,驗證方法是在瀏覽器框里輸入127.0.0.1
如果出現(xiàn)如下的圖片,則啟動成功掺栅。
實現(xiàn)驗證碼底圖
首先是通過PHP實現(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
結果是一片大白。
下面解釋一下里面涉及到的函數(shù):
項目 | 內(nèi)容 |
---|---|
imagecreatetruecolor | 生成空白的畫布 |
imagecolorallocate | 分配顏色 |
imagefill | 填充顏色 |
header | 發(fā)送HTTP頭 |
imagepng | 以png格式進行導出 |
imagedestory | 輸出結束的時候記得回收資源 |
為了表明各函數(shù)用法沙绝,特將PHP手冊中的詳細用法摘錄如下:
- imagecreatetruecolor — 新建一個真彩色圖像
resource imagecreatetruecolor ( int $width , int $height )
- imagecolorallocate — 為一幅圖像分配顏色
int imagecolorallocate ( resource $image , int $red , int $green , int $blue )
第一次對 imagecolorallocate() 的調用會給基于調色板的圖像填充背景色搏明,即用 imagecreate() 建立的圖像。
其他red,green,blue對應RGB值 - imagefill — 區(qū)域填充
bool imagefill ( resource $image , int $x , int $y , int $color )
imagefill() 在 image 圖像的坐標 x闪檬,y(圖像左上角為 0, 0)處用 color 顏色執(zhí)行區(qū)域填充(即與 x, y 點顏色相同且相鄰的點都會被填充)星著。 - header — 發(fā)送原生 HTTP 頭
void header ( string $string [, bool $replace = true [, int $http_response_code ]] )
請注意 header() 必須在任何實際輸出之前調用 - imagepng — 以 PNG 格式將圖像輸出到瀏覽器或文件
bool imagepng ( resource $image [, string $filename ] )
- imagedestroy — 銷毀圖片資源
bool imagedestroy ( resource $image )
注意事項:
- 依賴于GD擴展,輸出圖片前必須提前輸出圖片header信息
- 默認輸出為黑色背景谬以。
實現(xiàn)數(shù)字驗證碼
在上一章里面我們已經(jīng)新建了一張畫布强饮,相當于把整個框架搭起來了,本章的主要目的是在上面加上隨機的數(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ù)可以看出剪廉,我們需要給出生成隨機驗證碼數(shù)字的字體,位置炕檩,內(nèi)容和顏色斗蒋。
字體是死的,可以直接規(guī)定大小笛质。
因為要生成4個隨機數(shù)字泉沾,可以使用一個for循環(huán)for ($i = 0 ; $i < 4 ; $i++)
。
下面討論怎么獲得位置信息:
可以把長度100分成4份妇押,所以每個數(shù)字的位置是($i * 100 / 4 )
跷究,然后加上隨機的offset,可以得到
$x = ($i * 100 / 4 ) + rand (5,10);
內(nèi)容通過:$fontContent = rand (0,9);
獲得敲霍。
最后是怎么獲得隨機的顏色:
對于imagecolorallocate()這個函數(shù)而言俊马,只需要獲得隨機的RGB值丁存,就可以實現(xiàn)隨機的顏色了。為了更加醒目柴我,我們限定隨機RGB值的范圍為0~120解寝,因為是深色區(qū)間。
$fontColor = imagecolorallocate($image , rand(0,120) , rand(0,120), rand(0,120));//0~120是深色區(qū)間艘儒。
下面加上生成隨機數(shù)字的代碼段聋伦,在imagefill()那行下面加入:
<?php $image = imagecreatetruecolor(100,30);//生成資源 $bgcolor = imagecolorallocate($image , 255,255,255);//#ffffff,為一幅圖像分配顏色 imagefill($image , 0 , 0 , $bgcolor);//左上角彤悔,區(qū)域填充 // 生成隨機數(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); // 坐標 $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個隨機的數(shù)字晕窑。
增加干擾元素
為了防止被機器輕易的讀出來,可以增加干擾的元素卵佛。
先增加干擾的小點杨赤,用到函數(shù)
bool imagesetpixel(resource $image , int $x , int $y , int $color)
首先看點的位置怎么得到。
既然是隨機生成用來干擾的點截汪,那么可以在整個畫布隨機的跑疾牲,所以x = rand (1 , 99); y = rand (1 , 29)
而點的顏色注意要比字的淺,所以在50~200中選衙解。
上代碼阳柔,增加200個點。
<?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); // 坐標 $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);//生成的點不要超過畫布。 } header("content-type:image/png"); imagepng($image); imagedestroy($image); ?>
依舊看看效果:
再加點隨機的線:
使用方法:bool imageline (resource $image , int $x1 , int $y1 , int $x2 , int $y2 , int $color)
手冊上的解釋是:
Draws a line between the two given points.
也就是說在給出的兩點間畫線一汽。
注意隨機線的顏色比隨機點的顏色要更淺避消,所以在80~220里面選。
下面給出加隨機線的代碼:
// 生成干擾線 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); }
結果如圖:
生成隨機的字母和數(shù)字
之前生成的內(nèi)容只有隨機的數(shù)字召夹,還是容易被機器識別出來岩喷,所謂道高一尺魔高一丈,對手在加碼监憎,我們也得加碼撒纱意。下面我們在隨機的內(nèi)容里面加上字母,這樣組合更多枫虏,可以更好的屏蔽那些機器人妇穴。
首先我們把可能用到的字母和數(shù)字放到變量$data里面去爬虱,注意可以把容易混淆的字母和數(shù)字去掉,比如l和數(shù)字1容易混腾它,所以直接干掉跑筝。
然后每次隨機的從字符串里面抽一個出來,使用substr函數(shù)瞒滴。
string substr ( string $string , int $start [, int $length ] )
從$string里$start位置抽出$length長的字符曲梗。
這樣對原有的代碼進行簡單的修改就可以了。
<?php $image = imagecreatetruecolor(100,30);//生成資源 $bgcolor = imagecolorallocate($image , 255,255,255);//#ffffff妓忍,為一幅圖像分配顏色 imagefill($image , 0 , 0 , $bgcolor);//左上角虏两,區(qū)域填充 // 生成隨機數(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"; // 生成隨機的字母和數(shù)字,從$data字符串里面世剖,任意一個位置定罢,取一個字母 $fontContent = substr($data , rand(0,strlen($data)), 1); // 坐標 $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);//生成的點不要超過畫布祖凫。 } // 生成干擾線 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是存儲的服務器端的信息,可以把生成的內(nèi)容保存在服務器端的$_SESSION["authcode"]字段里面酬凳。當前端的用戶輸入相應的驗證字符后惠况,和$_SESSION["authcode"]進行對比,如果相同宁仔,自然證明輸入正確稠屠、
需要在代碼的最頂部加上session_start()
現(xiàn)在要考慮如何保存保存驗證碼的信息,先定義一個$captch_code 的空字符串翎苫,每生成一的隨機的數(shù)字或者字符权埠,都拼接到上面去。
其實在真實的開發(fā)環(huán)境下拉队,我們都是用服務器的集群來保存session的弊知,也就是說有可能第一次請求的時候建立的session保存在A服務器上,但是下次需要來拿數(shù)據(jù)的時候會被分配到B服務器上粱快,所以校驗會失敗秩彤。在多服務器的情況下,我們需要考慮集中管理session事哭,比如使用memcache來保存session信息漫雷。
<?php session_start(); $image = imagecreatetruecolor(100,30);//生成資源 $bgcolor = imagecolorallocate($image , 255,255,255);//#ffffff,為一幅圖像分配顏色 imagefill($image , 0 , 0 , $bgcolor);//左上角鳍咱,區(qū)域填充 // 生成隨機數(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"; // 生成隨機的字母和數(shù)字,從$data字符串里面,任意一個位置谤辜,取一個字母 $fontContent = substr($data , rand(0,strlen($data)), 1); $captch_code .= $fontContent; // 坐標 $x = ($i * 100 / 4 ) + rand (5,10);//總寬度100,放4個數(shù)字蓄坏。 $y = rand (5 , 10); imagestring ($image,$fontSize,$x,$y,$fontContent,$fontColor); } // 將循環(huán)生成的隨機數(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);//生成的點不要超過畫布。 } // 生成干擾線 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); ?>
驗證碼通過表單進行提交
在project文件夾里面新建form.php
輸入
<pre>
<?php?>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>確認驗證碼</title>
</head>
</pre>
<body> <form action="./form.php" method="post"> <p>驗證圖片:![](./captcha.php)</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,然后填入驗證碼字符
點擊提交按鈕渔彰。
但是如果是輸入全大寫的字母嵌屎,會輸出“輸入錯誤”的標志。
因為我們在判斷的時候是把原始輸入和服務器保存的進行比較恍涂,所以自然需要完全一致才行宝惰。
可以把用戶的輸入全部轉換為小寫
<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)驗證
之前的代碼存在一個問題,如果出來的驗證碼圖片用戶不能完全分辨得出再沧,就沒有辦法了尼夺。在生活中,一般的驗證碼圖片旁邊都會有“看不清产园?”這樣的提示汞斧,點擊的話,會刷新驗證碼什燕。
可以通過三個步驟進行:
- 增加可點擊的“換一個”文案
- 用JS選擇器選取圖片
- 用js修改驗證碼圖片地址
首先增加文案
<pre>
<a href="javascript:void(0)">換一個?</a>
</pre>
為了方便選取圖片,給img加上id屬性,使用document.getElementById('captch_img')獲得圖片竞端,然后用新的圖片對他進行賦值屎即,注意可以加上一段隨機數(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>確認驗證碼</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>
至此驗證碼的功能基本都實現(xiàn)了技俐,下面主要進行類的封裝,以后可以多次的復用统台。
驗證碼類的封裝
首先考慮通用的驗證碼類里面有那些元素:
<pre>
class Vcode {
private $width; //驗證碼圖片的寬度
private $height; //驗證碼圖片的高度
private $codeNum; //驗證碼字符的個數(shù)
private $disturbColorNum; //干擾元素數(shù)量
private $checkCode; //驗證碼字符
private $image; //驗證碼資源
}
</pre>
然后寫構造方法雕擂,主要用來實例化驗證碼對象贱勃,并為一些成員屬性初使化 井赌。
在寫構造方法之前,我們新定義一個內(nèi)部私有方法createCheckCode(),隨機生成用戶指定個數(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>
然后開始寫構造函數(shù):
<pre>
/**
* 構造方法用來實例化驗證碼對象耘子,并為一些成員屬性初使化
* @param int $width 設置驗證碼圖片的寬度费封,默認寬度值為80像素
* @param int $height 設置驗證碼圖片的高度弓摘,默認高度值為20像素
* @param int $codeNum 設置驗證碼中字母和數(shù)字的個數(shù)焚鹊,默認個數(shù)為4個
/
function __construct($width=80, $height=20, $codeNum=4) {
$this->width = $width;
$this->height = $height;
$this->codeNum = $codeNum;
$number = floor($height$width/15);
//如果驗證碼字符過多,則需要減少干擾點的數(shù)量
if($number > 240-$codeNum)
$this->disturbColorNum = 240-$codeNum;
else
$this->disturbColorNum = $number;
$this->checkCode = $this->createCheckCode();
}
</pre>
我們之前講過輸出圖像有幾個步驟韧献,首先新建畫布末患,然后生成干擾點,再加上隨機的字符锤窑,最后輸出璧针。可以把每個步驟包裝成一個方法渊啰,然后在outImg()里面統(tǒng)一調用探橱。
-
新建畫布
<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>
設置干擾元素
<pre>
/* 內(nèi)部使用的私有方法隧膏,設置干擾像素,向圖像中輸出不同顏色的點 */
private function setDisturbColor() {
// 畫隨機點
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);
}
// 畫隨機線
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)部使用的私有方法嚷那,隨機顏色胞枕、隨機擺放、隨機字符串向圖像中輸出 /
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>
向服務器SESSION中保存驗證碼
<pre>
/**
* 用于輸出驗證碼圖片,也向服務器的SESSION中保存了驗證碼娘摔,使用echo 輸出對象即可
/
function __toString(){
/ 加到session中窄坦, 存儲下標為code */
$_SESSION["code"] = strtoupper($this->checkCode);
$this->outImg();
return '';
}
</pre>析構函數(shù)
<pre>
/* 析構方法,在對象結束之前自動銷毀圖像資源釋放內(nèi)存 */
function __destruct(){
imagedestroy($this->image);
}
</pre>
至此驗證碼類已經(jīng)完成,只要直接輸出對象鸭津,就可以向瀏覽器中輸出圖片彤侍,可以在表單中使用。
在提交驗證碼到服務器的時候逆趋,已經(jīng)轉為了大寫盏阶,需要在驗證的時候把瀏覽器提交的也轉換為大寫。
應用驗證碼類
新建imgcode.php文件闻书,使用session_start()開啟回話控制名斟,同時創(chuàng)建類的對象。
此時如果使用echo輸出魄眉,同時會自動將驗證碼字符串保存在服務器中砰盐。
<pre>
<?php
/**
file:imgcode.php
用于請求時,通過驗證碼類的對象向客戶端輸出圖片
*/
session_start(); //開啟SESSION,會使用$_SESSION["code"]在服務器中保存驗證碼
require_once('captch.class.php'); //包含驗證碼所在的類文件
echo new Vcode(); //創(chuàng)建驗證碼對象坑律,并直接被輸出自動調用魔術__toString()方法
</pre>
構造表單岩梳,應用驗證碼
在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ù)宫屠,當單擊驗證碼時被調用列疗,將重新請求并獲取一個新的圖片 /
function newgdcode(obj,url) {
/ 后面?zhèn)鬟f一個隨機參數(shù),否則在IE7和火狐下浪蹂,不刷新圖片 */
obj.src = url+ '?nowtime=' + new Date().getTime();
}
</script>
</head>
<body> ![](imgcode.php) <form method="POST" action="form.php"> <input type="text" size="4" name="code" /> <input type="submit" name="submit" value="提交"> </form> </body> </html>