全面解析PHP驗(yàn)證碼的實(shí)現(xiàn)原理 附php驗(yàn)證碼小案例
拓展
我們需要開(kāi)啟gd拓展,可以使用下面的代碼來(lái)查看是否開(kāi)啟gd拓展。
<?php echo "Hello World!!!!"; echo phpinfo(); ?>
然后在瀏覽器上Ctrl+F查找gd選項(xiàng)即可驗(yàn)證自己有沒(méi)有裝這個(gè)拓展,如果沒(méi)有的話,還需要自己全裝一下這個(gè)拓展。
背景圖
imagecreatetruecolor
默認(rèn)生成黑色背景
<?php
// 使用gd的imagecreatetruecolor();創(chuàng)建一張背景圖
$image = imagecreatetruecolor(100,30);
// 在顯示這張圖片的時(shí)候一定要先聲明頭信息
header('content-type:image/png');
imagepng($image);
// 釋放資源,銷(xiāo)毀執(zhí)行對(duì)象
imagedestroy($image);
imagecolorallocate
創(chuàng)建一個(gè)填充色,并用imagefill(image,x,y,color)方法來(lái)附著。
<?php
// 使用gd的imagecreatetruecolor();創(chuàng)建一張背景圖
$image = imagecreatetruecolor(100,30);
// 生成填充色
$bgcolor = imagecolorallocate($image,255,255,255);
// 將填充色填充到背景圖上
imagefill($image,0,0,$bgcolor);
// 在顯示這張圖片的時(shí)候一定要先聲明頭信息
header('content-type:image/png');
imagepng($image);
// 釋放資源,銷(xiāo)毀執(zhí)行對(duì)象
imagedestroy($image);
imagepng
在使用這個(gè)方法之前,一定要先設(shè)置頭信息,否則不會(huì)正常的顯示圖片
imagedestory(image)
適時(shí)的釋放資源會(huì)減輕對(duì)服務(wù)器請(qǐng)求的壓力。
簡(jiǎn)易數(shù)字驗(yàn)證碼
imagecolorallocate
生成顏色信息,方便待會(huì)的賦予處理。
$fontcolor=imagecolorallocate($image,rand(0,255),rand(0,255),rand(0,255));
imagestring
把內(nèi)容信息寫(xiě)到圖片的相應(yīng)位置上。
imagestring($image,$fontsize,$x,$y,$fontcontent,$fontcolor);
增加識(shí)別干擾
//增加點(diǎn)
// 生成一些干擾的點(diǎn),這里是200個(gè)
for($i=0;$i<200;$i++){
$pointcolor = imagecolorallocate($image,rand(50,255),rand(50,255),rand(50,255));
imagesetpixel($image,rand(0,100),rand(0,30),$pointcolor);
}
// 增加線
// 生成一些干擾線 這里是5個(gè)
for($i=0;$i<5;$i++){
// 設(shè)置為淺色的線,防止喧賓奪主
$linecolor = imagecolorallocate($image,rand(50,255),rand(50,255),rand(50,255));
imageline($image,rand(0,99),rand(0,29),rand(0,99),rand(0,29),$linecolor);
}
數(shù)字字母混合驗(yàn)證碼
<?php
// 使用gd的imagecreatetruecolor();創(chuàng)建一張背景圖
$image = imagecreatetruecolor(100,40);
// 生成填充色
$bgcolor = imagecolorallocate($image,255,255,255);
// 將填充色填充到背景圖上
imagefill($image,0,0,$bgcolor);
//////// 生成隨機(jī)4位字母以及數(shù)字混合的驗(yàn)證碼
for($i=0;$i<4;$i++){
$fontsize = rand(6,8);
$fontcolor = imagecolorallocate($image,rand(0,255),rand(0,255),rand(0,255));
// 為了避免用戶(hù)難于辨認(rèn),去掉了某些有歧義的字母和數(shù)字
$rawstr = 'abcdefghjkmnopqrstuvwxyz23456789ABCDEFGHJKLMNOPQRSTUVWXYZ';
$fontcontent = substr($rawstr,rand(0,strlen($rawstr)),1);
// 避免生成的圖片重疊
$x += 20;
$y = rand(10,20);
imagestring($image,$fontsize,$x,$y,$fontcontent,$fontcolor);
}
// 生成一些干擾的點(diǎn),這里是200個(gè)
for($i=0;$i<200;$i++){
$pointcolor = imagecolorallocate($image,rand(50,255),rand(50,255),rand(50,255));
imagesetpixel($image,rand(0,100),rand(0,30),$pointcolor);
}
// 生成一些干擾線 這里是4個(gè)
for($i=0;$i<4;$i++){
// 設(shè)置為淺色的線,防止喧賓奪主
$linecolor = imagecolorallocate($image,rand(50,255),rand(50,255),rand(50,255));
imageline($image,rand(0,99),rand(0,29),rand(0,99),rand(0,29),$linecolor);
}
header('content-type:image/png');
imagepng($image);
// 釋放資源,銷(xiāo)毀執(zhí)行對(duì)象
imagedestroy($image);
使用驗(yàn)證碼
開(kāi)啟session的時(shí)機(jī)
注意: 開(kāi)啟session一定要在開(kāi)始的地方
驗(yàn)證的原理
驗(yàn)證的過(guò)程就是客戶(hù)端輸入的驗(yàn)證碼和存在于session域中的驗(yàn)證碼進(jìn)行對(duì)比。即:
if(isset($_REQUEST['checkcode'])){
session_start();
if($_REQUEST['checkcode']==$_SESSION['checkcode']){
echo "<font color='green'>Success!</font>";
}else{
echo "<font color='red'>Failed!</font>";
}
exit();
}
優(yōu)化驗(yàn)證
但是簡(jiǎn)單的這樣驗(yàn)證有一點(diǎn)不好的地方,那就是字母的大小寫(xiě)容易出錯(cuò)。所以我們要做一下轉(zhuǎn)換,將用戶(hù)輸入的數(shù)值全部變成小寫(xiě)的。
if(strtolower($_REQUEST['checkcode'])==$_SESSION['checkcode']){···}
小案例
生成驗(yàn)證碼
<?php
session_start();// 必須在php的最開(kāi)始部分聲明,來(lái)開(kāi)啟session
// 使用gd的imagecreatetruecolor();創(chuàng)建一張背景圖
$image = imagecreatetruecolor(100,40);
// 生成填充色
$bgcolor = imagecolorallocate($image,255,255,255);
// 將填充色填充到背景圖上
imagefill($image,0,0,$bgcolor);
//////// 生成隨機(jī)4位字母以及數(shù)字混合的驗(yàn)證碼
$checkcode='';
for($i=0;$i<4;$i++){
$fontsize = rand(6,8);
$fontcolor = imagecolorallocate($image,rand(0,255),rand(0,255),rand(0,255));
// 為了避免用戶(hù)難于辨認(rèn),去掉了某些有歧義的字母和數(shù)字
$rawstr = 'abcdefghjkmnopqrstuvwxyz23456789';
$fontcontent = substr($rawstr,rand(0,strlen($rawstr)),1);
// 拼接即將誕生的驗(yàn)證碼
$checkcode.=$fontcontent;
// 避免生成的圖片重疊
$x += 20;
$y = rand(10,20);
imagestring($image,$fontsize,$x,$y,$fontcontent,$fontcolor);
}
// 保存到session變量中
$_SESSION['checkcode']=$checkcode;
// 生成一些干擾的點(diǎn),這里是200個(gè)
for($i=0;$i<200;$i++){
$pointcolor = imagecolorallocate($image,rand(50,255),rand(50,255),rand(50,255));
imagesetpixel($image,rand(0,100),rand(0,30),$pointcolor);
}
// 生成一些干擾線 這里是4個(gè)
for($i=0;$i<4;$i++){
// 設(shè)置為淺色的線,防止喧賓奪主
$linecolor = imagecolorallocate($image,rand(50,255),rand(50,255),rand(50,255));
imageline($image,rand(0,99),rand(0,29),rand(0,99),rand(0,29),$linecolor);
}
header('content-type:image/png');
imagepng($image);
// 釋放資源,銷(xiāo)毀執(zhí)行對(duì)象
imagedestroy($image);
表單驗(yàn)證
<?php
header("Content-Type:text/html;charset=utf8");
if(isset($_REQUEST['checkcode'])){
session_start();
if(strtolower($_REQUEST['checkcode'])==$_SESSION['checkcode']){
echo "<font color='green'>Success!</font>";
}else{
echo "<font color='red'>Failed!</font>";
}
exit();
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>驗(yàn)證驗(yàn)證碼信息</title>
<script>
function change(){
document.getElementById("image_checkcode").src='./store.php?r='+Math.random();
}
</script>
</head>
<body>
<form action="./form.php" method="post">
<p>驗(yàn)證碼圖片:</p><img id="image_checkcode" src="./store.php?r=<?php echo rand();?>" /><a href="javascript:void(0)" onclick="change()">看不清楚</a><br/>
請(qǐng)輸入驗(yàn)證碼<input type="text" name="checkcode" /><br />
<p><input type="submit" value="提交" /></p>
</form>
</body>
</html>
總結(jié)
最后,來(lái)個(gè)總結(jié)吧。
•使用php制作驗(yàn)證碼需要gd拓展的支持。
•使用imagecreatetruecolor方法生成背景色,并用imagefill填充一個(gè)由imagecolorallocate產(chǎn)生的顏色。
•使用imagestring來(lái)實(shí)現(xiàn)驗(yàn)證碼和背景圖的結(jié)合
•使用imagesetpixel來(lái)添加干擾點(diǎn)
•使用imageline來(lái)添加干擾線
•使用session之前要在開(kāi)頭開(kāi)啟session_start()方法
•使用JavaScript來(lái)動(dòng)態(tài)的修改驗(yàn)證碼的src,來(lái)滿(mǎn)足用戶(hù)“換一張”的需求。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- PHP 用session與gd庫(kù)實(shí)現(xiàn)簡(jiǎn)單驗(yàn)證碼生成與驗(yàn)證的類(lèi)方法
- php封裝的驗(yàn)證碼工具類(lèi)完整實(shí)例
- 基于PHP制作驗(yàn)證碼
- PHP實(shí)現(xiàn)生成帶背景的圖形驗(yàn)證碼功能
- PHP 極驗(yàn)驗(yàn)證碼實(shí)例講解
- 分享一個(gè)漂亮的php驗(yàn)證碼類(lèi)
- 一個(gè)簡(jiǎn)單安全的PHP驗(yàn)證碼類(lèi)、PHP驗(yàn)證碼
- Ajax和PHP正則表達(dá)式驗(yàn)證表單及驗(yàn)證碼
- thinkphp自帶驗(yàn)證碼全面解析
- 基于php實(shí)現(xiàn)的驗(yàn)證碼小程序
相關(guān)文章
php+mysql查詢(xún)實(shí)現(xiàn)無(wú)限下級(jí)分類(lèi)樹(shù)輸出示例
這篇文章主要介紹了php+mysql查詢(xún)實(shí)現(xiàn)無(wú)限下級(jí)分類(lèi)樹(shù)輸出,結(jié)合實(shí)例形式分析了php+MySQL查詢(xún)實(shí)現(xiàn)的樹(shù)狀分類(lèi)輸出功能,涉及php數(shù)據(jù)庫(kù)查詢(xún)與數(shù)組遍歷等相關(guān)操作技巧,需要的朋友可以參考下2016-10-10
PHP構(gòu)造函數(shù)與析構(gòu)函數(shù)用法示例
這篇文章主要介紹了PHP構(gòu)造函數(shù)與析構(gòu)函數(shù)用法,簡(jiǎn)單講述php中構(gòu)造函數(shù)與析構(gòu)函數(shù)的定義與使用方法,并結(jié)合實(shí)例形式演示了構(gòu)造函數(shù)與析構(gòu)函數(shù)的執(zhí)行順序,需要的朋友可以參考下2016-09-09
php生成SessionID和圖片校驗(yàn)碼的思路和實(shí)現(xiàn)代碼
做一個(gè)后臺(tái)登陸需要用到校驗(yàn)碼,前臺(tái)的用戶(hù)跟蹤需要用到SessionID,當(dāng)然,默認(rèn)的PHP開(kāi)啟了Session以后就有了一個(gè)SessionID,但是我需要自己的,并且能夠存儲(chǔ)進(jìn)數(shù)據(jù)庫(kù),那么我就嘗試了一下,構(gòu)造了以下的函數(shù)。2009-03-03
在php中判斷一個(gè)請(qǐng)求是ajax請(qǐng)求還是普通請(qǐng)求的方法
如何在php中判斷一個(gè)網(wǎng)頁(yè)請(qǐng)求是ajax請(qǐng)求還是普通請(qǐng)求?你可以通過(guò)傳遞參數(shù)的方法來(lái)實(shí)現(xiàn),例如使用如下網(wǎng)址請(qǐng)求2011-06-06
淺談PHP中單引號(hào)和雙引號(hào)到底有啥區(qū)別呢?
本文向我們簡(jiǎn)單介紹了php中單雙引號(hào)的區(qū)別,以及對(duì)比了下javascript中單引號(hào)和雙引號(hào)的區(qū)別,方便我們更好的理解,非常實(shí)用,推薦給大家2015-03-03
PHP setcookie() cannot modify header information 的解決方法
PHP setcookie() 報(bào) cannot modify header information 錯(cuò)誤的解決方法2009-01-01

