[轉]php 圖片驗證碼生成 前後臺驗證
本文轉自:https://www.cnblogs.com/xiaoyezi/p/3541195.html
自己從前一段時間做了個php小專案,關於生成圖片驗證碼生成和後臺的驗證,把自己用到的東西總結一下,希望大家在用到相關問題的時候可以有一定的參考性。
首先,php驗證碼生成。
程式碼如下:
1.生成影象程式碼(picture.php)
<?php header("Cache-Control: no-cache, must-revalidate"); // 宣告影象大小 $img_height=70; $img_width=25; $authnum=''; // 驗證碼內容 $ychar="0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z"; $list=explode(",",$ychar); for($i=0;$i<4;$i++){ $randnum=rand(0,35); $authnum.=$list[$randnum]; } // 生成一個基本大小影象 $aimg = imagecreate($img_height,$img_width); // 影象填充顏色 imagecolorallocate($aimg, 255,255,255); $black = imagecolorallocate($aimg, 0,0,0); for ($i=1; $i<=100; $i++) { imagestring($aimg,1,mt_rand(1,$img_height),mt_rand(1,$img_width),"@",imagecolorallocate($aimg,mt_rand(200,255),mt_rand(200,255),mt_rand(200,255))); } //為了區別於背景,這裡的顏色不超過200,上面的不小於200 for ($i=0;$i<strlen($authnum);$i++){ imagestring($aimg, mt_rand(3,5),$i*$img_height/4+mt_rand(2,7),mt_rand(1,$img_width/2-2), $authnum[$i],imagecolorallocate($aimg,mt_rand(0,100),mt_rand(0,150),mt_rand(0,200))); } imagerectangle($aimg,0,0,$img_height-1,$img_width-1,$black);//畫一個矩形 Header("Content-type: image/PNG"); ImagePNG($aimg); //生成png格式 ImageDestroy($aimg); ?>
2.利用一個form表單(名稱為index.php)呼叫上面的picture.php
為了便於演示,以下所說的所有檔案放在相同的目錄。
--folder1--picture.php
--index.php
1 2 3 4 5 6 |
<form>
<div>
<img id=
"codeP"
src=
"picture.php"
/>
<input id=
"codeT"
type=
"text"
name=
"codeT"
/>
</div>
</form>
|
當你完成上面的程式碼時候你就應該能看到在頁面中載入了圖片的驗證碼。
如果你的圖片沒有載入成功的話,檢查檔案路徑或者php.ini中[extension=php_gd2.dll]這個程式碼是否放開了。
其次,當你完成了圖片的顯示,你又將要遇到另外一個問題,驗證碼的重新整理。
相信只要是稍微理解一點js用法的人都應該想的到,給某個空間加上一個onclick事件,工作就迎刃而解了。為了方便,我將修改上面index.php的程式碼。
1 2 3 4 5 6 7 8 9 10 11 |
<script type=
"text/javascript"
>
function refresh() {
document.getElementById(
"codeP"
).src =
"picture.php?tm="
+Math.random();
}
</script>
<form>
<div>
<img id=
"codeP"
src=
"picture.php"
onclick=
"refresh()"
/>
<input id=
"codeT"
type=
"text"
name=
"codeT"
/>
</div>
</form>
|
當你將上述程式碼修改結束時,你就會發現,當你點選圖片的時候,驗證碼就自己變了。至於說藍色字型的tm=***:代表每次生成隨機碼,也就是不取快取。
再次,當你將上面兩個步驟完成之後,當你提交表單的時候,你就應該去驗證你輸入的驗證碼和圖片驗證碼是否一致,有以下幾種方法:
1.客戶端驗證(cookie驗證,不推薦)不安全
2.伺服器端驗證(session,推薦)安全
關於為什麼安全,為什麼不安全,網上有很多帖子,可以一一膜拜,這裡不細說。
下面的例子就說一下伺服器端驗證的程式碼。
在提到驗證程式碼之前,我要先把前面提到的picture.php修正一下,以得到驗證效果,著重看新新增的程式碼和註釋。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
<?php
// session有效
session_start();
// 宣告一個sessoin
session_register(
"sessionCode"
);
header(
"Cache-Control: no-cache, must-revalidate"
);
// 宣告影象大小
$img_height=70;
$img_width=25;
$authnum=
''
;
// 驗證碼內容
$ychar=
"0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z"
;
$list=explode(
","
,$ychar);
for
($i=0;$i<4;$i++){
$randnum=rand(0,35);
$authnum.=$list[$randnum];
}
// 將每次生成的驗證碼儲存在session中
$_SESSION[
"sessionCode"
] = $authnum;
// 生成一個基本大小影象
$aimg = imagecreate($img_height,$img_width);
// 影象填充顏色
imagecolorallocate($aimg, 255,255,255);
$black = imagecolorallocate($aimg, 0,0,0);
for
($i=1; $i<=100; $i++) { imagestring($aimg,1,mt_rand(1,$img_height),mt_rand(1,$img_width),
"@"
,imagecolorallocate($aimg,mt_rand(200,255),mt_rand(200,255),mt_rand(200,255)));
}
//為了區別於背景,這裡的顏色不超過200,上面的不小於200
for
($i=0;$i<strlen($authnum);$i++){
imagestring($aimg, mt_rand(3,5),$i*$img_height/4+mt_rand(2,7),mt_rand(1,$img_width/2-2), $authnum[$i],imagecolorallocate($aimg,mt_rand(0,100),mt_rand(0,150),mt_rand(0,200)));
}
imagerectangle($aimg,0,0,$img_height-1,$img_width-1,$black);
//畫一個矩形
Header(
"Content-type: image/PNG"
);
ImagePNG($aimg);
//生成png格式
ImageDestroy($aimg);
?>
|
圖片驗證的方式有兩種:
1.後臺驗證,在你提交的頁面中取得你填寫的驗證碼和session中的驗證碼是否一致,在做相關操作。
後臺驗證比較簡單,直接貼一下程式碼。(假如的form表單中要提交的checked.php)
1 2 3 4 5 6 7 8 9 |
<?php
session_start();
$codeT = $_POST[
'codeT '
];
$codeP = $_SESSION[
"sessionCode"
];
if
($codeT==$codeP) {
做你想要做的操作;
}
else
{
驗證碼有誤;<br> 相關操作;
}
|
2.前臺驗證:
如果你想在前臺直接取得$_SESSION["sessionCode"]的值得話,你就大錯特錯了。
因為你取的值肯定實在html中隱藏起來的,但是圖片實在所有html元素載入之後才載入圖片的(也就是俗話說的非同步載入)
所以做check的時候可以採用非同步驗證+提交。也就是非同步驗證過了之後,我在提交表單。我簡單的吧程式碼貼在下面。
index.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
<script type=
"text/javascript"
>
function sub() {
ajaxSubmit(test,
"submitTag.php"
);
}
function ajaxSubmit(formName,submitURL) {
var
code = document.getElementById(
'codeT'
).value;
var
postStr =
"test="
+code;
var
xmlHttp =
false
;
if
(window.ActiveXObject){
xmlHttp =
new
ActiveXObject(
"Microsoft.XmlHttp"
);
}
else
if
(window.XMLHttpRequest){
xmlHttp =
new
XMLHttpRequest();
}
xmlHttp.onreadystatechange = function(){
if
(xmlHttp.readyState==4){
if
(xmlHttp.status==200){
alert(xmlHttp.responseText);
if
(xmlHttp.responseText==
"success"
) {
formName.action = submitURL;
formName.submit();
}
else
{
document.getElementById(
"error"
).innerHTML =
"請輸入正確的驗證碼。"
;
}
}
}
}
var
url=
"bbb.php"
;
xmlHttp.open(
"post"
,url,
true
);
xmlHttp.setRequestHeader(
"Content-Type"
,
"application/x-www-form-urlencoded"
);
xmlHttp.send(postStr);
}
function refresh() {
document.getElementById(
"codeP"
).src =
"picture.php?tm="
+Math.random();
}
</script>
<form id=
"test"
name=
"test"
action=
""
> <div id=
"error"
></div>
<div>
<img id=
"codeP"
src=
"picture.php"
onclick=
"refresh()"
/>
<input id=
"codeT"
type=
"text"
name=
"codeT"
/>
</div>
<div><input type=
"button"
onclick=
"sub()"
name=
"apply"
id=
"apply"
value=
"提交"
/></div>
</form>
|
以上提及了bbb.php裡面的內容自己對照上面的js程式碼稍微想一下,其實很簡單。就不貼了。有什麼問題的話可以m我,有什麼說的不對的地方,請不要客氣。