Tự tạo captcha đơn giản với PHP

PHP Tutorials 17/03/2026 07:00 1018
Trong bài viết này mình muốn giới thiệu tới các bạn một cách tạo ra một chức năng captcha trong PHP khá đơn giản bảo mật. PhpTextClass là một mã nguồn mở cho phép bạn tạo một hình ảnh phức tạp.

Captcha là một công cụ hình và chữ, được gọi là một CAPTCHA – viết tắt của ‘Completely Automated Public Turing test to tell Computers and Humans Apart' (Phép thử Turing công cộng hoàn toàn tự động để phân biệt máy tính với người). Đó cơ bản là một bài kiểm tra về mức độ chính xác trong phản hồi (các giao thức bao gồm một bên đặt câu hỏi và một bên đưa ra câu trả lời hợp lệ và được xác thực) nhằm phân biệt người dùng (người đang cố gắng truy cập vào trang web) là con người hay robot.

CAPTCHA hoạt động như thế nào?

Phương thức CAPTCHA truyền thống "gõ lại những chữ bạn thấy trong hình" yêu cầu người dùng nhận diện và nộp về một chuỗi giá trị (chữ hoặc số hoặc cả hai) họ nhìn thấy ở một tấm hình méo mó/ lờ mờ. Những CAPTCHA này dựa trên khả năng nhận biết và đọc hiểu các tín hiệu âm thanh/ hình ảnh – những thứ gây khó khăn cho máy tính hay robot. Dựa vào cơ chế trên, nếu một người dùng có khả năng nhận diện được những tín hiệu âm thanh/ hình ảnh đó, họ nhất định đúng là con người.

Các bước để tạo ra một captcha

Thông thường chúng ta sẽ tạo ra một file captcha.php. Trong file này chứa mã lệnh có khả năng tạo một ảnh chứa những ký tự được gọi là mã captcha. Điều đặc biệt là bạn phải khởi tạo một biến và lưu nó vào $_SESSION.

Vì thế bạn phải chắc chắn rằng bạn đã khai báo session_start() trong ứng dụng của bạn.

session_start();

CAPTCHA được ứng dụng vào form như thế nào.

Vì bản chất của file captcha.php là tạo ra một hình ảnh. Nên bạn phải chèn vào một thẻ IMG với thuộc tính src dẫn tới file captcha.php.

<img src="captcha.php?rand=<?php echo rand();?>" onclick="this.src='captcha.php?rand=Math.random()*10000'" id='captchaimg'>
Trong đoạn code trên thì mỗi lần người dùng click vào hình ảnh thì sẽ tạo ra một mã mới.

Ngày nay có khá nhiều công cụ để bạn có thể tự tạo một captcha cho ứng dụng của bạn như Google Capcha chẳng hạn. Nhưng hôm nay mình muốn giới thiệu tới các bạn một cách tạo captcha đơn giản bằng PHP đó là sử dụng PhptextClass.

Một số ưu điểm.

  • Cấu trúc code nhỏ.
  • Nó sử dụng phptextClass để tạo ra hình ảnh captcha.
  • Mã tùy chỉnh.
  • Tính năng bảo mật với đường nét ngẫu nhiên.

1. File phptextClass.php

class phptextClass
{	
	public function phptext($text,$textColor,$backgroundColor='',$fontSize,$imgWidth,$imgHeight,$dir,$fileName)
	{
		/* settings */
		$font = './calibri.ttf';
		/*define font*/
		$textColor=$this->hexToRGB($textColor);	
		
		$im = imagecreatetruecolor($imgWidth, $imgHeight);	
		$textColor = imagecolorallocate($im, $textColor['r'],$textColor['g'],$textColor['b']);	
		
		if($backgroundColor==''){
			/*select random color*/
			$colorCode=array('#56aad8', '#61c4a8', '#d3ab92');
			$backgroundColor = $this->hexToRGB($colorCode[rand(0, count($colorCode)-1)]);
			$backgroundColor = imagecolorallocate($im, $backgroundColor['r'],$backgroundColor['g'],$backgroundColor['b']);
		}else{
			/*select background color as provided*/
			$backgroundColor = $this->hexToRGB($backgroundColor);
			$backgroundColor = imagecolorallocate($im, $backgroundColor['r'],$backgroundColor['g'],$backgroundColor['b']);
		}
		
		imagefill($im,0,0,$backgroundColor);	
		list($x, $y) = $this->ImageTTFCenter($im, $text, $font, $fontSize);	
		imagettftext($im, $fontSize, 0, $x, $y, $textColor, $font, $text);
		if(imagejpeg($im,$dir.$fileName,90)){/*save image as JPG*/
			return json_encode(array('status'=>TRUE,'image'=>$dir.$fileName));
		imagedestroy($im);	
		}
	}	
	public function phpcaptcha($textColor,$backgroundColor,$imgWidth,$imgHeight,$noiceLines=0,$noiceDots=0,$noiceColor='#162453')
	{	
		/* Settings */
		$text=$this->random();
		$font = './font/monofont.ttf';/* font */
		$textColor=$this->hexToRGB($textColor);	
		$fontSize = $imgHeight * 0.75;
		
		$im = imagecreatetruecolor($imgWidth, $imgHeight);	
		$textColor = imagecolorallocate($im, $textColor['r'],$textColor['g'],$textColor['b']);			
		
		$backgroundColor = $this->hexToRGB($backgroundColor);
		$backgroundColor = imagecolorallocate($im, $backgroundColor['r'],$backgroundColor['g'],$backgroundColor['b']);
				
		/* generating lines randomly in background of image */
		if($noiceLines>0){
			$noiceColor=$this->hexToRGB($noiceColor);	
			$noiceColor = imagecolorallocate($im, $noiceColor['r'],$noiceColor['g'],$noiceColor['b']);
			for( $i=0; $i<$noiceLines; $i++ ) {				
				imageline($im, mt_rand(0,$imgWidth), mt_rand(0,$imgHeight),
				mt_rand(0,$imgWidth), mt_rand(0,$imgHeight), $noiceColor);
			}
		}				
				
		if($noiceDots>0){
			/* generating the dots randomly in background */
			for( $i=0; $i<$noiceDots; $i++ ) {
				imagefilledellipse($im, mt_rand(0,$imgWidth),
				mt_rand(0,$imgHeight), 3, 3, $textColor);
			}
		}		
		
		imagefill($im,0,0,$backgroundColor);	
		list($x, $y) = $this->ImageTTFCenter($im, $text, $font, $fontSize);	
		imagettftext($im, $fontSize, 0, $x, $y, $textColor, $font, $text);		

		imagejpeg($im,NULL,90);
		/* Showing image */
		header('Content-Type: image/jpeg');
		/* defining the image type to be shown in browser widow */
		imagedestroy($im);
		/* Destroying image instance */
		if(isset($_SESSION)){
			$_SESSION['skey'] = $text;
			/* set random text in session for captcha validation*/
		}
	}
	
	/*for random string*/
	protected function random($characters=6,$letters = '23456789bcdfghjkmnpqrstvwxyz'){
		$str='';
		for ($i=0; $i<$characters; $i++) { 
			$str .= substr($letters, mt_rand(0, strlen($letters)-1), 1);
		}
		return $str;
	}	
	
	/*function to convert hex value to rgb array*/
	protected function hexToRGB($colour)
	{
			if ( $colour[0] == '#' ) {
					$colour = substr( $colour, 1 );
			}
			if ( strlen( $colour ) == 6 ) {
					list( $r, $g, $b ) = array( $colour[0] . $colour[1], $colour[2] . $colour[3], $colour[4] . $colour[5] );
			} elseif ( strlen( $colour ) == 3 ) {
					list( $r, $g, $b ) = array( $colour[0] . $colour[0], $colour[1] . $colour[1], $colour[2] . $colour[2] );
			} else {
					return false;
			}
			$r = hexdec( $r );
			$g = hexdec( $g );
			$b = hexdec( $b );
			return array( 'r' => $r, 'g' => $g, 'b' => $b );
	}		
		
	/*function to get center position on image*/
	protected function ImageTTFCenter($image, $text, $font, $size, $angle = 8) 
	{
		$xi = imagesx($image);
		$yi = imagesy($image);
		$box = imagettfbbox($size, $angle, $font, $text);
		$xr = abs(max($box[2], $box[4]));
		$yr = abs(max($box[5], $box[7]));
		$x = intval(($xi - $xr) / 2);
		$y = intval(($yi + $yr) / 2);
		return array($x, $y);	
	}
}

2. File captcha.php

<?php
	session_start();
	include("phptextClass.php");	
	
	/*create class object*/
	$phptextObj = new phptextClass();	
	/*phptext function to genrate image with text*/
	$phptextObj->phpcaptcha('#FFF','#000',120,40,10,25);	
 ?>

 

3. File demo.php

Trong file này mình sẽ xây dựng một cái form có chưa một ô input field cho phép bạn nhập mã code và một button submit form.

<?php 
session_start();
if(isset($_POST['Submit'])){
	// Code for check server side validation
	if(empty($_SESSION['skey'] ) || strcasecmp($_SESSION['skey'], $_POST['captcha_code']) != 0){  
		// Captcha verification is incorrect.	
		$msg="<span style='color:red'>Mã bảo mật phù hợp!</span>";	
	}else{
		// Captcha verification is Correct. Final Code Execute here!		
		$msg="<span style='color:green'>Mã bảo mật không phù hợp.</span>";		
	}
}	
?>

<form action="" method="post" name="form1" id="form1" >
    <table width="400" border="0" align="center" cellpadding="5" cellspacing="1" class="table">
		<?php if(isset($msg)){?>
        <tr>
            <td colspan="2" align="center" valign="top"><?php echo $msg;?></td>
        </tr>
        <?php } ?>
        <tr>
            <td align="right" valign="top"> Mã bảo mật:</td>
            <td>
                <img src="captcha.php?rand=<?php echo rand();?>" onclick="this.src='captcha.php?rand=Math.random()*10000'" id='captchaimg'><br>
                Click vào hình để tạo một mã bảo mật mới<br /> <br>
                <label for='message'>Nhập mã bảo mật:</label> <br>
                <input id="captcha_code" name="captcha_code" type="text">
            </td>
        </tr>
        <tr>
            <td>&nbsp;</td>
            <td><input name="Submit" type="submit" onclick="return validate();" value="Submit" class="button1"></td>
        </tr>
    </table>
</form>

Tổng kết.

Xem Thêm

Profile photo of adminTheHalfHeart

B.V.T

Sinh ra và lớn nên ở Bắc Giang. Hiện tại thì tôi đang là một lập trình viên tại VietISO. Tôi lập website này với mục đích là bookmark những gì tôi đã đọc qua và mong muốn chia sẻ những gì tôi biết.