趕緊來總結一下自己的小知識,啊~~ 我還活着
最近做了一個投票活動,但有人刷票,就讓主辦方頭疼了,上級讓我加一個手機短信驗證,就增加了刷票人的成本嘛,第一天完成了手機短信驗證功能,但第二天就讓我改... 改成 PHP生成驗證碼,就取消手機短信了
哼哼,我居然一點都不慌~
因為剛做了手機短信驗證,是將驗證碼記錄在數據庫里的,所以我們的程序生成驗證碼,我也記錄在數據庫里了,這是我的設計模式,目的呢,是能記錄下來,哪些用戶,在什么時間段,獲取了驗證碼,是否使用了等等信息。。
我用的是原生PHP,沒有用ThinkPHP等框架。因為我們公司有自己的框架,但比較古老,已經out了,正在轉TP5
完成PHP驗證碼,很簡單:
/** * 生成隨機數字驗證碼 * * @param int $size 驗證碼長度 * * @return string */ function generateRandNumberVerificationCode($size = 4) { if($size <= 0 || empty($size) || !isset($size)) { $size = 4; } //驗證碼內容 $code_array = array( 0,1,2,3,4,5,6,7,8,9 ); $random_keys = array(); for($i = 0; $i < $size; $i++) { $keys = array_rand($code_array,1); array_push($random_keys,$code_array[$keys]); } //數組轉成字符串 $verification_code = implode('',$random_keys); return $verification_code; }
上面是我自己寫的一個,嗯....里面只有 0-9的數字,如果你想用 a-z 這種,就在 $code_array 數組里加入即可。
封裝的這個方法,個人覺得還是很簡單,易懂,最后返回獲取到的 4位數驗證碼。 你在外面調用時,可以傳入$size,$size=6 就代表是6位驗證碼,默認是4位
我們調用這個方法,獲取到驗證碼,然后就將這個驗證碼保存在數據庫里,再寫個接口給前端調用,就完成啦~ 注:驗證碼記錄到數據庫時,同時記錄是哪個用戶在操作,操作時間,驗證碼過期時間,這是我的設計模式
emmmm最開始我是這么想的
但前端有點懵,因為我的想法是,接口返回一組字符串,前端收到了,不能就直接顯示出來,那多難看啊,肯定要加樣式,我想的是給前端處理,讓他想個辦法,組個圖片,或者打亂樣式,但好像有點難, 最后商量了一下,讓我PHP在后台生成一張圖片傳給前端, 也就是驗證碼圖片
有很多小伙伴不明白驗證碼圖片,因為是圖片,用戶提交的是字符串,怎么和圖片做對比? 以前我也是這么想的。。 其實,上面我就寫了,已經生成了一組驗證碼,記錄到數據庫了,明白了嗎。 用戶輸入的字符串,最后做比較的,不是圖片,而是和我已經生成的驗證碼, 圖片,只是用來給用戶看的, 而這個圖片的內容,就是我來定義
以下是生成 驗證碼圖片代碼:
/** * 生成隨機數字驗證碼圖片 * * @param string $code 驗證碼內容 * * @param string $member_id 會員id * * @param string $width 圖片寬度 * * @param string $height 圖片寬度 * * @return string */ function generateRandNumberVerificationCodeImg($code = '',$member_id = '',$width = 80,$height = 40) { if(empty($code) || !isset($code)) { return false; } if(empty($member_id) || !isset($member_id)) { return false; } //判斷文件夾是否存在,不存在則創建 $dir = ROOT_PATH.'/upload/verification_code_img'; if(!is_dir($dir)){ mkdir($dir, 0777, true); } //驗證碼圖片保存路徑,文件名稱 $file_name = ROOT_PATH.'/upload/verification_code_img/member_id_'.$member_id.'.png'; //域名返回 $domain_name = _constant_url.'/upload/verification_code_img/member_id_'.$member_id.'.png'; $img = imagecreatetruecolor($width, $height); $black = imagecolorallocate($img, 0x00, 0x00, 0x00); $green = imagecolorallocate($img, 0x00, 0xFF, 0x00); $white = imagecolorallocate($img, 0xFF, 0xFF, 0xFF); imagefill($img,0,0,$white); imagestring($img, 5, 22, 12, $code, $black); //加入噪點干擾 for($i=0;$i<100;$i++) { imagesetpixel($img, rand(0, $width) , rand(0, $width) , $black); //imagesetpixel — 畫一個單一像素,語法: bool imagesetpixel ( resource $image , int $x , int $y , int $color ) imagesetpixel($img, rand(0, $width) , rand(0, $width) , $green); } //輸出驗證碼 // header("content-type: image/png"); imagepng($img,$file_name); //保存圖片 imagedestroy($img); //圖像處理完成后,使用 imagedestroy() 指令銷毀圖像資源以釋放內存,雖然該函數不是必須的,但使用它是一個好習慣。 return $domain_name; }
以上代碼需要注意的是:
1. 我這邊定義的常量,可能和你們的不同,但基本是國際命名法,大致應該都能明白變量或常量的意思
2. $code 這個參數是驗證碼內容,就是我先生成了驗證碼,然后調用這個生成圖片,將驗證碼傳了進去,圖片里就是我的驗證碼內容了
3. 方法里最后兩個參數:$width 和 $height,這兩個參數,是用來定義你的圖片寬和高的
4. imagestring() 方法,我在里面寫的是絕對值,4位數驗證碼就合適,但6位,8位,或者其他的,樣式就不好看了,小伙伴有興趣可以寫一個數學運算,這樣傳幾位驗證碼,都能保證在圖片中間,以及好看的樣式。emmmmm以前寫過百分比,各種計算,但這次就算啦
5. 這里生成的圖片,你一定要去學習 PHP GD庫,可以直接百度"PHP GD庫"
驗證碼圖片這個方法,我是將圖片保存在我的項目里,以及取出它的域名鏈接,保存在數據庫里,這樣我就可以傳給前端,前端來獲取這個驗證碼的圖片了。 用戶看到這個圖片的內容,輸入字符串,后台進行驗證,結束。
以下是我本次處理驗證碼功能的邏輯:
1. 生成驗證碼
2. 根據驗證碼,生成 驗證碼圖片
3. 保存至數據庫,記錄驗證碼、當前用戶、創建時間、過期時間、是否已驗證、驗證碼圖片路徑
4. 寫接口,傳給前端 驗證碼圖片
5. 前端展示圖片給用戶
6. 用戶根據驗證碼圖片輸入 驗證碼內容
7. 前端確認用戶輸入信息,傳給接口
8. PHP接口做處理,驗證用戶輸入的驗證碼內容是否正確
9. 正確,投票成功;失敗,提示錯誤