首頁 >後端開發 >php教程 >帶有PHP和GD的簡單驗驗

帶有PHP和GD的簡單驗驗

Jennifer Aniston
Jennifer Aniston原創
2025-02-22 09:13:09572瀏覽

帶有PHP和GD的簡單驗驗

帶有PHP和GD的簡單驗驗

到目前為止,我們都以在線表格遇到了Captcha圖像。驗證碼是必不可少的邪惡,本文將教您如何製作它們。

>請注意,儘管有更好的自動第三方解決方案,例如Recaptcha,但該教程旨在僅解釋和證明此類技術的實際運行方式。我們不會解釋什麼驗證碼實際上是什麼,因為它被認為是常識,並且已經在其他地方進行了更詳細的範圍。

鑰匙要點

PHP中的GD(圖形繪製)庫可用於創建驗證碼圖像,該圖像通常由形狀,失真和文本組成。

驗證碼創建過程涉及顯示一個空圖像,創建形狀,生成隨機線和點以及生成隨機文本。
  • 碼驗證驗證過程涉及將用戶的輸入與會話變量中存儲的驗證碼字符串進行比較。如果輸入與驗證碼字符串匹配,則將用戶的響應視為正確。
  • > 為了確保始終刷新驗證碼圖像,並且不會從瀏覽器緩存中檢索,可以使用php。
  • 本教程演示瞭如何創建簡單的驗證碼,建議使用更安全,更可訪問的第三方解決方案(例如recaptcha)進行生產應用程序。
  • 繪製驗證碼
  • >您必須在繼續之前安裝GD(圖形繪製)庫。該庫可以通過內置的PHP功能繪製圖形和圖像。要安裝它,請運行sudo apt-get安裝php5-gd或在基於非Ubuntu的操作系統上,請按照說明進行操作。
  • 驗證碼通常由三件事組成 - 形狀,失真和文本。
  • 我們將遵循下面提到的步驟:

>在瀏覽器上顯示一個空圖像。

>創建一個形狀。

生成隨機線。

生成隨機點。
  1. 生成隨機文本。
  2. 本文中使用的過程樣式僅出現僅是因為這是概念的證明,並且使最終文件盡可能簡單。在一個真實的項目中,您會oop。
  3. >
  4. 顯示一個空圖像
  5. >圖像將由HTML處理,就好像使用“ IMG”標籤顯示外部圖像一樣。使用了兩個功能 - 一個用於創建圖像,另一個用於顯示。
  6. >
第一行指示在我們頁面上用戶會話的開始。

display()函數除了在瀏覽器中顯示圖像的普通HTML代碼外,沒有其他內容。除此之外,只能進行樣式以使輸出看起來可顯示。

>在Create_image()函數中,使用一個變量來引用ImageCreateTureColor()函數返回的圖像,該函數以圖像的寬度和長度作為其參數。 ImagePng()創建指定名稱和路徑的PNG圖像(在同一目錄中)。

黑色圖像將是我們的第一步之後的輸出。

請注意,功能imagepng()將是我們函數的最後一行,以下所有步驟將僅在此函數調用之前插入create_image()函數中,否則它們不會生效。 帶有PHP和GD的簡單驗驗

創建一個形狀

可以為驗證碼選擇任何形狀。我們將使用函數ImageFilledRectangle()選擇矩形。它需要五個參數 - 圖像參考,啟動X-POS,啟動Y-POS,結束X-POS,結束Y-POS和背景顏色。您可以使用相應的函數作為橢圓驗驗。 ImageColaralocate()函數

將顏色分配給變量,因為它將顏色的RGB組合作為參數。以下代碼將附加在create()函數中。

在此步驟之後,上圖將是白色的。

<span><span><?php
</span></span><span><span>session_start();
</span></span><span><span>?></span>
</span>
    <span><span><span><title</span>></span>demo.php<span><span></title</span>></span>
</span>    <span><span><span><body</span> <span>style<span>="<span>background-color:#ddd; </span>"</span></span>></span>
</span>
    <span><span><?php
</span></span><span>    <span>create_image();
</span></span><span>    <span>display();
</span></span><span>    <span>/***** definition of functions *****/
</span></span><span>    <span>function display()
</span></span><span>    <span>{
</span></span><span>        <span>?></span>
</span>
        <span><span><span><div</span> <span>style<span>="<span>text-align:center;</span>"</span></span>></span>
</span>            <span><span><span><h3</span>></span>TYPE THE TEXT YOU SEE IN THE IMAGE<span><span></h3</span>></span>
</span>            <span><span><span><b</span>></span>This is just to check if you are a robot<span><span></b</span>></span>
</span>
            <span><span><span><div</span> <span>style<span>="<span>display:block;margin-bottom:20px;margin-top:20px;</span>"</span></span>></span>
</span>                <span><span><span><img</span> src<span>="image.png"</span>></span>
</span>            <span><span><span></div</span>></span>
</span>            //div1 ends
        <span><span><span></div</span>></span>                          //div2 ends
</span>
    <span><span><?php
</span></span><span>    <span>}
</span></span><span>
</span><span>    <span>function  create_image()
</span></span><span>    <span>{
</span></span><span>        <span>$image = imagecreatetruecolor(200, 50);
</span></span><span>        <span>imagepng($image, "image.png");
</span></span><span>    <span>}
</span></span><span>
</span><span>    <span>?></span>
</span>    <span><span><span></body</span>></span>
</span><span><span><?php
</span></span><span><span>?></span></span>

生成隨機線。

現在,我們實際上是從使驗證碼的失真部分開始。在PHP中,線從起點(x1,y1)到終點(x2,y2)生成。現在,當我們希望線條觸摸盒子的兩端時,我們將保持坐標為,即我們的盒子的完整寬度。 坐標將被隨機生成。這將僅創建一個隨機行。我們將通過將此功能放入for循環中來生成多行。 帶有PHP和GD的簡單驗驗

imageLine()函數將x1,x2,y1,y2坐在該順序中作為參數,除了線的圖像參考和顏色。線色已被分配,就像在上一步中分配了背景顏色一樣。

> y坐標是rand()*p給出的,因為這是我們盒子的高度,並且始終將返回50以下的值。您可以使用rand(0,50)。它們將產生相同的輸出範圍。

<span>$background_color = imagecolorallocate($image, 255, 255, 255);  
</span><span>imagefilledrectangle($image,0,0,200,50,$background_color);</span>

生成隨機點。

隨機點將以與隨機線相同的方式生成。使用的函數是ImagesetPixel()。此函數採用將點將點放在框中的坐標值的值。 帶有PHP和GD的簡單驗驗>

>通過使用rand()* 0隨機生成X坐標,因為這是我們盒子的寬度,這將始終返回200歲以下的值。您可以使用RAND(0,200)。它們將產生相同的輸出範圍。 y坐標的生成如線步中。

帶有PHP和GD的簡單驗驗

生成隨機文本

>我們將隨機指向字符串中的一個位置(其中包含在下層和高層中的字母),並將其分配給變量$ letter

>
<span><span><?php
</span></span><span><span>session_start();
</span></span><span><span>?></span>
</span>
    <span><span><span><title</span>></span>demo.php<span><span></title</span>></span>
</span>    <span><span><span><body</span> <span>style<span>="<span>background-color:#ddd; </span>"</span></span>></span>
</span>
    <span><span><?php
</span></span><span>    <span>create_image();
</span></span><span>    <span>display();
</span></span><span>    <span>/***** definition of functions *****/
</span></span><span>    <span>function display()
</span></span><span>    <span>{
</span></span><span>        <span>?></span>
</span>
        <span><span><span><div</span> <span>style<span>="<span>text-align:center;</span>"</span></span>></span>
</span>            <span><span><span><h3</span>></span>TYPE THE TEXT YOU SEE IN THE IMAGE<span><span></h3</span>></span>
</span>            <span><span><span><b</span>></span>This is just to check if you are a robot<span><span></b</span>></span>
</span>
            <span><span><span><div</span> <span>style<span>="<span>display:block;margin-bottom:20px;margin-top:20px;</span>"</span></span>></span>
</span>                <span><span><span><img</span> src<span>="image.png"</span>></span>
</span>            <span><span><span></div</span>></span>
</span>            //div1 ends
        <span><span><span></div</span>></span>                          //div2 ends
</span>
    <span><span><?php
</span></span><span>    <span>}
</span></span><span>
</span><span>    <span>function  create_image()
</span></span><span>    <span>{
</span></span><span>        <span>$image = imagecreatetruecolor(200, 50);
</span></span><span>        <span>imagepng($image, "image.png");
</span></span><span>    <span>}
</span></span><span>
</span><span>    <span>?></span>
</span>    <span><span><span></body</span>></span>
</span><span><span><?php
</span></span><span><span>?></span></span>

放入循環時,看起來像

<span>$background_color = imagecolorallocate($image, 255, 255, 255);  
</span><span>imagefilledrectangle($image,0,0,200,50,$background_color);</span>

我們將解釋行

>
<span>$line_color = imagecolorallocate($image, 64,64,64); 
</span><span>for($i=0;$i<10;$i++) {
</span>    <span>imageline($image,0,rand()%50,200,rand()%50,$line_color);
</span><span>}</span>

在下一節中。

函數Imagestring()在我們的圖像中寫入文本。它有6個參數:

  1. >圖像參考。
  2. 文本的字體大小(最多可以是5)。
  3. x坐標(每個字母比例更改)。
  4. y坐標(保持相同,儘管我們也可以隨機更改此)。
  5. >要編寫的實際字符串。
  6. 文本的字體色。
  7. 如果您希望具有更大的字體和不同的字體樣式,
  8. >也可以使用函數imagettftext()。對於文本的角度和字體樣式,它還需要2個其他論點。

X坐標的計算是通過檢查完成的。大概,這些字母的間距約為35個像素(5($ i*30)),其中$ i = 0,1,2,3,4,5,6。這是因為如果我們將這個值保持在15-20px左右,則可能會有兩個字母重疊。如果該值超過40px,則完全不適合盒子。

這將生成6個字母驗證碼文本。我們始終可以通過更改由於簡單性(例如顏色,Y-Coordine等)來創造更多的隨機性,例如

最終的驗證碼看起來像這樣

>

每次您刷新頁面時,在驗證碼中寫的文本都會更改。

可以通過使用像素或更改顏色或大小來創建設計來實現更多隨機性。 帶有PHP和GD的簡單驗驗>

驗證


>在這裡採取用戶的響應,然後在處理後,他/她會收到答复。首先,使用輸入文本框和提交按鈕製作一個簡單的表單。根據複雜的Web應用程序的要求,可以有許多方法來處理驗證碼。但是,出於此示例,請保持簡單,我們將在同一頁面上對其進行處理。

>在上一個代碼段中未解釋的兩行現在開始發揮作用:>

$ word。 = $ letter; - 串聯操作員。用於一個接一個地附加所有單個字母,生成6個字母的單詞。

$ _ session ['catcha_string'] = $ word;我們的驗證碼字符串存儲在會話變量中,該變量將用於驗證目的。

>
  1. 我們將更改display()的定義以添加類似形式的結構。 >
  2. 將使用兩個提交按鈕,一個將字符串提交,另一個提交按鈕刷新頁面。
  3. >將在兩個關閉的DIV標籤之間添加以下行(請參閱上一個display()函數中的註釋)
>
<span><span><?php
</span></span><span><span>session_start();
</span></span><span><span>?></span>
</span>
    <span><span><span><title</span>></span>demo.php<span><span></title</span>></span>
</span>    <span><span><span><body</span> <span>style<span>="<span>background-color:#ddd; </span>"</span></span>></span>
</span>
    <span><span><?php
</span></span><span>    <span>create_image();
</span></span><span>    <span>display();
</span></span><span>    <span>/***** definition of functions *****/
</span></span><span>    <span>function display()
</span></span><span>    <span>{
</span></span><span>        <span>?></span>
</span>
        <span><span><span><div</span> <span>style<span>="<span>text-align:center;</span>"</span></span>></span>
</span>            <span><span><span><h3</span>></span>TYPE THE TEXT YOU SEE IN THE IMAGE<span><span></h3</span>></span>
</span>            <span><span><span><b</span>></span>This is just to check if you are a robot<span><span></b</span>></span>
</span>
            <span><span><span><div</span> <span>style<span>="<span>display:block;margin-bottom:20px;margin-top:20px;</span>"</span></span>></span>
</span>                <span><span><span><img</span> src<span>="image.png"</span>></span>
</span>            <span><span><span></div</span>></span>
</span>            //div1 ends
        <span><span><span></div</span>></span>                          //div2 ends
</span>
    <span><span><?php
</span></span><span>    <span>}
</span></span><span>
</span><span>    <span>function  create_image()
</span></span><span>    <span>{
</span></span><span>        <span>$image = imagecreatetruecolor(200, 50);
</span></span><span>        <span>imagepng($image, "image.png");
</span></span><span>    <span>}
</span></span><span>
</span><span>    <span>?></span>
</span>    <span><span><span></body</span>></span>
</span><span><span><?php
</span></span><span><span>?></span></span>

>在進一步移動之前,我們必須知道何時顯示以及何時不顯示輸入框。它將僅顯示

>
  1. 如果頁面剛剛加載。
  2. 如果用戶的答案不正確。

>每次單擊提交按鈕時,使用$標誌設置為“ 1”來滿足第一個條件。最初,它已設置為任何其他值。通過檢查我們的會話變量中存儲的值是否與用戶輸入相同(請參見下面的代碼)來實現第二個條件。

為了實現這一目標,我們將在本文開頭替換開始步驟的以下幾行:>

with:
<span>$background_color = imagecolorallocate($image, 255, 255, 255);  
</span><span>imagefilledrectangle($image,0,0,200,50,$background_color);</span>

請注意,函數create_image()和display()僅按照上述2個條件來調用。
<span>$line_color = imagecolorallocate($image, 64,64,64); 
</span><span>for($i=0;$i<10;$i++) {
</span>    <span>imageline($image,0,rand()%50,200,rand()%50,$line_color);
</span><span>}</span>

>我們需要上一頁的會話變量,因此會話不會在此處銷毀。關閉瀏覽器窗口後,會話將自動銷毀。

>

驗證碼看起來像

帶有PHP和GD的簡單驗驗如果輸入不正確,則只有然後再次提示用戶。

>

帶有PHP和GD的簡單驗驗如果輸入正確,則將向用戶顯示消息。

>

帶有PHP和GD的簡單驗驗>有一個小警告 - 當用戶按下返回按鈕時,瀏覽器緩存中的任何圖像都不會重新加載,而頁面則可以。在發布請求中,瀏覽器返回按鈕將顯示一個“過期的文檔”頁面,但是當請求獲取時,圖像不會再生。

>

解決方案很簡單 - 每次創建圖像的唯一名稱,以便瀏覽器在緩存中找不到它們。我們將在創建和顯示在瀏覽器中時,將一個唯一的字符串通過內置時間()函數返回給我們。

>在您開始會話的位置下方添加此行:

>用
<span>$pixel_color = imagecolorallocate($image, 0,0,255);
</span><span>for($i=0;$i<1000;$i++) {
</span>    <span>imagesetpixel($image,rand()%200,rand()%50,$pixel_color);
</span><span>}  </span>
>替換顯示()函數中的img src標籤

以及我們在create_image()函數中創建png映像的部分也將被
<span>$letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
</span><span>$len = strlen($letters);
</span><span>$letter = $letters[rand(0, $len-1)];
</span>
<span>$text_color = imagecolorallocate($image, 0,0,0);</span>
替換

現在,圖像將被稱為Image39342015.png。此過程將隨著頁面的刷新而創建的圖像多次,這可能會浪費大量的磁盤空間,因此,我們將確保在創建圖像之前,刪除了PNG擴展名的所有其他圖像。在調用ImagePNG()函數之前添加以下內容。
<span>for ($i = 0; $i< 6;$i++) {
</span>    <span>$letter = $letters[rand(0, $len-1)];
</span>    <span>imagestring($image, 5,  5+($i*30), 20, $letter, $text_color);
</span>    <span>$word.=$letter;
</span><span>}
</span><span>$_SESSION['captcha_string'] = $word;</span>

在生產應用程序中,只需確保您隔離存儲驗證碼圖像的文件夾,其他有用的圖像也可能會被刪除。

<span>$word.=$letter;
</span><span>$_SESSION['captcha_string'] = $word;   </span>
>在此處下載完整的代碼。

結論

在PHP中製作各種類型的驗證碼非常容易。本文介紹了用於創建標準驗證碼的三個基本內容 - 形狀,失真和文本。本文是概念證明,本文介紹的代碼不應在生產中使用,尤其是因為存在諸如recaptcha之類的優秀替代方案,這也支持聲音輸出以幫助有聽力障礙的人。我們希望您發現這篇文章很有趣。在下面留下您的評論和反饋!

>

經常詢問的問題(常見問題解答)關於帶有PHP GD

的簡單驗證

>如何自定義驗證碼的外觀?

>可以通過修改PHP代碼來自定義驗證碼的外觀。您可以更改字體,顏色,尺寸,甚至可以更改驗證碼的背景。例如,要更改字體,您可以使用imagettftext()函數並在參數中指定字體文件。要更改顏色,您可以使用ImageColorallocate()函數並指定所需顏色的RGB值。請記住,自定義不僅使您的驗證碼更加美觀,而且更加安全地抵抗機器人。

>

>如何使我的驗證碼更安全?

>有幾種使驗證碼更安全的方法。一種方法是使用上和下情況的字母數字字符的混合。這增加了可能的組合數量,因此機器人更難猜測。您還可以增加驗證碼的長度。另一種方法是將噪聲(例如線或點)添加到驗證碼圖像中。可以使用ImageLine()和ImageLeLipse()函數在php。

>

中完成此操作?幾個原因。一個常見的原因是,在PHP安裝中未安裝或啟用GD庫。您可以使用function_Exists('gd_info')函數檢查此功能。如果返回false,則未啟用GD。另一個原因可能是您的PHP代碼中的錯誤。確保檢查您的錯誤日誌是否有任何線索。

如何實現刷新驗證驗證功能?

可以使用AJAX實現刷新驗證驗證功能。您需要創建一個JavaScript函數,該功能將請求發送到服務器以生成新的驗證碼。然後,該服務器使用新的驗證碼映像進行響應,然後在沒有完整頁面的網頁上更新網頁上。

我可以在沒有GD庫的情況下使用CACTCHA嗎?

,而GD庫通常用於用於在PHP中創建驗證碼,這不是唯一的方法。您也可以使用其他庫,例如ImageMagick,甚至可以創建基於文本的驗證碼。但是,這些方法可能無法提供與GD庫相同的安全性和自定義。

>如何將CAPTCHA添加到我的觸點表格?

>向您的聯繫表中添加驗證碼涉及修改表單的HTML和PHP代碼。在HTML中,您需要為驗證碼添加一個圖像標籤和一個輸入字段,以便用戶輸入驗證碼。在PHP中,您需要生成驗證碼並驗證用戶的輸入。

>

>為什麼我的驗證驗證驗證不起作用?

>

如果您的驗證碼驗證不起作用,則可以到期有幾個原因。一個常見的原因是,會話變量未正確設置或檢索。在將任何輸出發送到瀏覽器之前,請確保調用Session_Start(),並且會話變量正在正確使用。另一個原因可能是用戶的輸入未與驗證碼正確進行比較。如果您的驗證碼包含上部和下案例字符,請確保使用不敏感的比較。

>

>如何使我的驗證碼可訪問視覺受損的用戶?

>使您的驗證碼可訪問以視覺上的鍵盤訪問受損的用戶可能具有挑戰性,但是有幾種方法。一種方法是提供音頻驗證碼選項。這涉及生成帶有驗證碼字符大聲說出來的音頻文件。另一種方法是使用一個基於問題的驗證碼,在其中詢問用戶一個簡單的問題,即一個機器人很難回答。

>

bot仍然可以繞過我的驗證碼嗎?為防止機器人而設計,它們不是萬無一失的。高級機器人可以使用OCR(光學字符識別)讀取CAPTCHA字符。但是,通過使您的驗證碼更加複雜,例如使用字符的混合,添加噪音並定期更改驗證碼,您可以使bot更難繞過。

是CAPTCHA,是防止垃圾郵件的唯一方法?

CAPTCHA是防止垃圾郵件的常見方法,但這不是唯一的方法。其他方法包括使用Honeypot,這是一個隱藏的表單字段,該字段將填寫,但人類不會檢查用戶的行為,例如填寫表單所花費的時間,並使用諸如Akismet之類的服務,該服務已過濾出來垃圾郵件基於已知垃圾郵件的數據庫。

以上是帶有PHP和GD的簡單驗驗的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn