ホームページ >バックエンド開発 >PHPチュートリアル >PHPとGDのシンプルなキャプチャ

PHPとGDのシンプルなキャプチャ

Jennifer Aniston
Jennifer Anistonオリジナル
2025-02-22 09:13:09566ブラウズ

PHPとGDのシンプルなキャプチャ

PHPとGDのシンプルなキャプチャ

今では、私たちは皆、オンライン形式でCaptchaの画像に遭遇しました。キャプチャは必要な悪であり、この記事はそれらがどのように作られているかを教えます。

RecaptchaなどのCaptchasのためのより良い自動サードパーティのソリューションはありますが、このチュートリアルは、そのようなテクノロジーが実際にどのように機能するかを説明し、実証することを目的としていることに注意してください。それは一般的な知識であると想定されており、すでに他の場所でより詳細にカバーされているため、Captchasが実際に何であるかを説明することはありません。

キーテイクアウト

    PHPのGD(グラフィックドロー)ライブラリを使用して、通常、形状、歪み、テキストで構成されるCaptcha画像を作成できます。
  • キャプチャ作成プロセスでは、空の画像の表示、形状の作成、ランダムな線とドットの生成、ランダムなテキストの生成が含まれます。
  • CAPTCHA検証プロセスでは、ユーザーの入力をセッション変数に保存されているCAPTCHA文字列と比較することが含まれます。入力がCaptcha文字列と一致する場合、ユーザーの応答は正しいとみなされます。 このチュートリアルでは、シンプルなキャプチャを作成する方法を示していますが、生産アプリケーションにRecaptchaのようなより安全でアクセスしやすいサードパーティのソリューションを使用することをお勧めします。
  • 描画captchas
  • 進行前にGD(グラフィックドロー)ライブラリをインストールする必要があります。このライブラリは、内蔵のPHP関数を介してグラフィックと画像の描画を可能にします。インストールするには、sudo apt-getインストールphp5-gdを実行するか、unubuntu以外のオペレーティングシステムにある場合は、指示に従ってください。
  • captchasは通常、形、歪み、テキストの3つのもので構成されています。
  • 以下の手順に従います:

ブラウザに空の画像を表示します。

形状を作成します。

ランダムな行を生成します。

ランダムドットを生成します。
  1. ランダムテキストを生成します
  2. この記事で使用される手続きスタイルは、これが概念の証明であり、最終ファイルを可能な限り単純に保つためにのみ存在します。実際のプロジェクトでは、oopになります。
  3. 空の画像を表示
  4. 画像は、「IMG」タグを使用して外部画像が表示されているかのようにHTMLによって扱われます。 2つの関数が使用されます - 1つは画像を作成するために、もう1つは表示するためです。
  5. 最初の行は、ページ上のユーザーのセッションの開始を示します。
  6. display()関数には、ブラウザに画像を表示する通常のHTMLコードに他なりません。それ以外は、出力が見栄えの良いように見えるようにスタイリングのみが行われます。
Create_image()関数の内部では、変数が使用され、画像の幅と長さを引数として取得するImageCreatetruecolor()関数によって返される画像を参照します。 ImagePng()指定された名前とパスのPNG画像を作成します(同じディレクトリ内)。

最初のステップの後に黒の画像が出力になります。

PHPとGDのシンプルなキャプチャ

関数ImagePng()が関数の最後の行になることに注意し、次のすべての手順は、この関数が呼び出す前にcreate_image()関数に挿入されることに注意してください。

形状を作成します

キャプチャには任意の形状を選択できます。関数ImageFilledRectangle()を使用して、長方形を選択します。画像参照、X-POSを開始する、Y-POSを開始する、X-POSの終了、Y-POの終了、および背景色の5つの引数が必要です。楕円形のキャプチャを生成するために、楕円に対応する関数を使用できます。

ImageColorAllocate()関数は、色の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とGDのシンプルなキャプチャランダムな線を生成します。

今、私たちは実際にキャプチャの歪み部分を作ることから始めます。 PHPでは、ラインは開始点(x1、y1)からエンドポイント(x2、y2)まで生成されます。これで、ラインがボックスの両端に触れたいので、座標を、つまりボックスの完全な幅として維持します。 座標はランダムに生成されます。これにより、1つのランダムな行が作成されます。この機能をforループ内に配置することにより、複数の行を生成します。

ImageLine()関数は、x1、x2、y1、y2の座標を、画像参照と線の色とは別に、その順序で引数として調整します。前のステップで背景色が割り当てられていたように、線の色は割り当てられています。
<span>$background_color = imagecolorallocate($image, 255, 255, 255);  
</span><span>imagefilledrectangle($image,0,0,200,50,$background_color);</span>

y座標はrand()*として与えられます。これはボックスの高さであり、常に50未満の値を返すためです。代わりにrand(0,50)を使用できます。それらは同じ出力範囲を生成します。

PHPとGDのシンプルなキャプチャランダムドットを生成します。

ランダムなドットは、ランダムな線と同じ方法で生成されます。使用される関数はImagesEtpixel()です。この関数は、ドットがボックスに配置される座標の値を取得します。

X座標は、rand()* 0を使用してランダムに生成されます。これはボックスの幅であり、常に200未満の値を返します。代わりにRAND(0,200)を使用できます。それらは同じ出力範囲を生成します。 y座標は、ラインステップのように生成されます。

PHPとGDのシンプルなキャプチャ

ランダムなテキストを生成

文字列内の位置(下品と上品の両方にアルファベットが含まれています)をランダムに指し、変数$文字

に割り当てます。
<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-coordinate(すべてのアルファベットで比例して変更)。
  4. y座標(同じものを保持しますが、これもランダムに変更できます)。
  5. 書き込まれる実際の文字列。
  6. テキストのフォントカラー。
より大きなフォントと異なるフォントスタイルが必要な場合は、関数ImageTtftext()を使用することもできます。テキストのアングルスタイルとフォントスタイルについて2つの追加の議論が必要です。

X座標の計算は、検査によって行われます。大まかに、文字は約35ピクセル(5($ i*30))に間隔が塗られています。ここで、$ i = 0,1,2,3,4,5,6です。これは、この値を15〜20px程度に保持していた場合、2文字が重複する可能性があったためです。値が40pxを超えていた場合、文字は完全にボックスに収まりませんでした。

これにより、6アルファベットのCaptchaテキストが生成されます。色、Y座標など、シンプルさのために一定に保たれている側面を変更することにより、いつでもよりランダムさを作成できます。

最後のキャプチャはこのように見えます

キャプチャに記載されているテキストは、ページを更新するたびに変更されます。

ピクセルでデザインを作成したり、色やサイズを変更したりすることで、よりランダム性を実現できます。 PHPとGDのシンプルなキャプチャ検証

ここでは、ユーザーの応答が取得され、処理後、返信を受け取ります。最初は、入力テキストボックスと送信ボタンで簡単なフォームが作成されます。複雑なWebアプリケーションの要件に従って、キャプチャを処理する多くの方法があります。ただし、この例のためにシンプルに保つと、同じページで処理します。

前のコードスニペットで説明されていない2行のラインが今すぐに登場します:

$ word。= $ letter; - 連結演算子。個々の文字を次々に追加するために使用され、6文字の単語が生成されます。

$ _セッション['captcha_string'] = $ word; Captcha文字列は、検証目的で使用されるセッション変数に保存されています。

    display()の定義を変更して、フォームのような構造を追加します。
  1. 2つの提出ボタンが使用されます。1つは文字列を送信し、もう1つはページを更新します。
  2. 次の行は、2つのクロージングDivタグの間に追加されます(前のdisplay()関数のコメントを参照)
  3. <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. ユーザーの回答が間違っていた場合。
    最初の条件は、送信ボタンがクリックされるたびに「1」に設定されている$フラグを使用して満たされます。当初、それは他の価値に設定されていました。 2番目の条件は、セッション変数に保存されている値がユーザー入力と同じかどうかを確認することで達成されます(以下のコードを参照)。

    これを達成するために、記事の冒頭での開始ステップの次の行を置き換えます:

    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のシンプルなキャプチャ

    マイナーな注意事項があります。ユーザーが戻るボタンを押すと、ブラウザのキャッシュに既に存在する画像はリロードされませんが、ページが表示されます。 POSTリクエストでは、ブラウザのバックボタンには「ドキュメントの有効期限が切れた」ページが表示されますが、リクエストが取得されると、画像は再生されません。 PHPとGDのシンプルなキャプチャソリューションはシンプルです - 毎回画像の一意の名前を作成しているため、ブラウザがキャッシュに表示されないようにします。ブラウザでの作成中および表示中に、Image Nameに組み込まれたTime()関数によって返された一意の文字列を追加します。

    セッションを開始した場所のすぐ下にこの行を追加します:

    display()関数のIMG SRCタグを

    に置き換えます

    およびcreate_image()関数でpngイメージを作成した部分も
    <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>
    に置き換えられます

    画像はImage39342015.pngのようなものと呼ばれるようになりました。この手順では、ページを何度も更新して画像を作成して、膨大な量のディスクスペースを無駄にする可能性があるため、画像を作成する前に、PNG拡張機能の他のすべての画像が削除されることを確認します。 ImagePng()関数が呼び出される直前に、以下を追加します。
    <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>

    制作アプリでは、Captcha画像が保存されているフォルダーを分離していることを確認してください。
    <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>

    ここから完全なコードをダウンロードしてください。

    結論

    PHPでさまざまな種類のキャプチャを作るのは非常に簡単です。この記事では、標準的なキャプチャの作成に使用される3つの基本的なもの、つまり形、歪み、テキストについて説明しました。この記事は概念の証明であり、ここに示されているコードは、生産に使用されるべきではありません。特に、聴覚障害のある人々を支援するための健全な出力もサポートするRecaptchaなどの優れた代替品が存在するためです。この記事が面白いと思います。以下にコメントとフィードバックを残してください!

    PHP GDを備えたシンプルなキャプチャに関するよくある質問(FAQ)

    キャプチャの外観をカスタマイズするにはどうすればよいですか?

    キャプチャの外観をカスタマイズすることで、PHPコードを変更することで実行できます。フォント、色、サイズ、さらにはキャプチャの背景を変更できます。たとえば、フォントを変更するには、imagettftext()関数を使用して、パラメーターのフォントファイルを指定できます。色を変更するには、ImageColorAllocate()関数を使用して、必要な色のRGB値を指定できます。覚えておいてください、カスタンはあなたのキャプチャをより審美的に心地よくするだけでなく、ボットに対してより安全にするだけでなく、キャプチャをより安全にするにはどうすればよいですか? 1つの方法は、高度と小文字の両方で英数字のミックスを使用することです。これにより、可能な組み合わせの数が増加し、ボットが推測するのが難しくなります。キャプチャの長さを増やすこともできます。別の方法は、ラインやドットなどのノイズをキャプチャ画像に追加することです。これは、phpのImageLine()とImageLipse()関数を使用して実行できます。いくつかの理由。よくある理由の1つは、GDライブラリがPHPのインストールにインストールまたは有効になっていないことです。これは、function_exists(「gd_info」)関数を使用して確認できます。 falseを返す場合、GDは有効になりません。もう1つの理由は、PHPコードのエラーです。エラーログに何らかの手がかりがあるか確認してください。

    リフレッシュキャプチャ機能を実装するにはどうすればよいですか?

    リフレッシュキャプチャ機能の実装は、AJAXを使用して実行できます。新しいCaptchaを生成するためにサーバーにリクエストを送信するJavaScript関数を作成する必要があります。次に、サーバーは新しいCaptcha画像で応答します。これは、フルページのリロードなしでWebページで更新されます。 PHPでCaptchasを作成することは、唯一の方法ではありません。また、ImageMagickなどの他のライブラリを使用したり、テキストベースのCaptchaを作成したりすることもできます。ただし、これらの方法は、GDライブラリと同じレベルのセキュリティとカスタマイズを提供しない場合があります。

    連絡先フォームにcaptchaを追加するにはどうすればよいですか?

    連絡先フォームにCaptchaを追加するには、フォームのHTMLおよびPHPコードの変更が含まれます。 HTMLでは、Captchaの画像タグと、ユーザーがCaptchaを入力するための入力フィールドを追加する必要があります。 PHPでは、CAPTCHAを生成してユーザーの入力を検証する必要があります。

    captchaはスパムを防ぐための一般的な方法ですが、それが唯一の方法ではありません。その他の方法には、ボットが記入するが、人間はそうしない隠されたフォームフィールドであるハニーポットの使用、フォームに記入するのにかかった時間など、ユーザーの動作を確認し、Akismetのようなサービスを使用してフィルターアウトします。既知のスパムのデータベースに基づいたスパム

以上がPHPとGDのシンプルなキャプチャの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。