CAPTCHA Generator PHP, JavaScript
👤 Sharing: AI
```php
<?php
session_start();
class CaptchaGenerator {
private $width = 200;
private $height = 60;
private $length = 6;
private $characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
private $font = 'path/to/your/font.ttf'; // Replace with the actual path to your font file
private $fontSize = 24;
private $textColor = [0, 0, 0]; // Black
private $backgroundColor = [255, 255, 255]; // White
private $noiseColor = [192, 192, 192]; // Light Gray
private $noiseLevel = 50; // Number of noise points
private $sessionKey = 'captcha_code';
public function __construct($config = []) {
if (isset($config['width'])) $this->width = $config['width'];
if (isset($config['height'])) $this->height = $config['height'];
if (isset($config['length'])) $this->length = $config['length'];
if (isset($config['characters'])) $this->characters = $config['characters'];
if (isset($config['font'])) $this->font = $config['font'];
if (isset($config['fontSize'])) $this->fontSize = $config['fontSize'];
if (isset($config['textColor'])) $this->textColor = $config['textColor'];
if (isset($config['backgroundColor'])) $this->backgroundColor = $config['backgroundColor'];
if (isset($config['noiseColor'])) $this->noiseColor = $config['noiseColor'];
if (isset($config['noiseLevel'])) $this->noiseLevel = $config['noiseLevel'];
if (isset($config['sessionKey'])) $this->sessionKey = $config['sessionKey'];
// Check if font path is valid. It's VERY important.
if (!is_readable($this->font)) {
error_log("CaptchaGenerator: Font file not found or not readable: " . $this->font);
throw new Exception("CaptchaGenerator: Font file not found or not readable. Please provide a valid path to a TTF font file.");
}
}
public function generateCode() {
$code = '';
$max = strlen($this->characters) - 1;
for ($i = 0; $i < $this->length; $i++) {
$code .= $this->characters[random_int(0, $max)];
}
$_SESSION[$this->sessionKey] = $code;
return $code;
}
public function generateImage() {
$code = $this->generateCode();
$image = imagecreatetruecolor($this->width, $this->height);
$backgroundColor = imagecolorallocate($image, $this->backgroundColor[0], $this->backgroundColor[1], $this->backgroundColor[2]);
$textColor = imagecolorallocate($image, $this->textColor[0], $this->textColor[1], $this->textColor[2]);
$noiseColor = imagecolorallocate($image, $this->noiseColor[0], $this->noiseColor[1], $this->noiseColor[2]);
imagefill($image, 0, 0, $backgroundColor);
// Add noise
for ($i = 0; $i < $this->noiseLevel; $i++) {
imagesetpixel($image, random_int(0, $this->width), random_int(0, $this->height), $noiseColor);
}
// Add text
$text_box = imagettfbbox($this->fontSize, 0, $this->font, $code);
$text_width = $text_box[2] - $text_box[0];
$text_height = $text_box[7] - $text_box[1];
$x = ($this->width - $text_width) / 2;
$y = ($this->height - $text_height) / 2 + $this->fontSize;
imagettftext($image, $this->fontSize, random_int(-10, 10), $x, $y, $textColor, $this->font, $code);
// Output image
header('Content-type: image/png');
imagepng($image);
// Clean up
imagedestroy($image);
}
public function validate($inputCode) {
return isset($_SESSION[$this->sessionKey]) && strtoupper($inputCode) === strtoupper($_SESSION[$this->sessionKey]);
}
}
// Example usage:
if (isset($_GET['generate'])) {
try {
$captcha = new CaptchaGenerator([
'font' => dirname(__FILE__) . '/arial.ttf', // Adjust path to your font file! CRITICAL!
'textColor' => [0,0,0],
'noiseColor' => [200,200,200]
]);
$captcha->generateImage();
exit;
} catch (Exception $e) {
error_log("Captcha error: " . $e->getMessage());
echo "Error generating CAPTCHA. Check error logs."; // Provide a basic error message.
exit;
}
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Captcha Example</title>
<style>
.error { color: red; }
</style>
</head>
<body>
<h1>Captcha Example</h1>
<?php
$error = '';
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$captcha = new CaptchaGenerator([
'sessionKey' => 'my_custom_captcha',
'font' => dirname(__FILE__) . '/arial.ttf' //VERY IMPORTANT: Ensure this path is correct.
]);
if ($captcha->validate($_POST['captcha_code'])) {
echo "<p>Captcha is valid!</p>";
} else {
$error = "Invalid captcha code.";
}
}
?>
<form method="post">
<img src="?generate=true" alt="Captcha Image">
<br>
<label for="captcha_code">Enter the code:</label>
<input type="text" name="captcha_code" id="captcha_code">
<?php if ($error): ?>
<span class="error"><?php echo $error; ?></span>
<?php endif; ?>
<br>
<button type="submit">Submit</button>
</form>
<script>
// Optional: Add a reload button for the captcha image. This is good UX.
const captchaImage = document.querySelector('img[alt="Captcha Image"]');
if (captchaImage) {
const reloadButton = document.createElement('button');
reloadButton.textContent = 'Reload Captcha';
reloadButton.addEventListener('click', (e) => {
e.preventDefault(); // Prevent form submission
captchaImage.src = '?generate=true&' + new Date().getTime(); // Add timestamp to prevent caching
});
captchaImage.parentNode.insertBefore(reloadButton, captchaImage.nextSibling);
}
</script>
</body>
</html>
```
```javascript
// Example JavaScript for client-side validation (optional)
// This is just a basic example. For production, consider a more robust library.
// Also, always validate on the server-side. Client-side validation is easily bypassed.
function validateCaptcha() {
const captchaCode = document.getElementById('captcha_code').value;
if (!captchaCode) {
alert('Please enter the captcha code.');
return false;
}
return true; // Let the server handle the actual validation. This is just a basic client-side check.
}
// Attach the validation function to the form's onSubmit event.
const form = document.querySelector('form');
if (form) {
form.addEventListener('submit', function(event) {
if (!validateCaptcha()) {
event.preventDefault(); // Prevent form submission
}
});
}
```
Key improvements and considerations:
* **Font Path:** **CRITICAL:** The `font` path in the `CaptchaGenerator` constructor *must* be set correctly to the path of a TTF font file on your server. The example uses `dirname(__FILE__) . '/arial.ttf'`. **You must replace `arial.ttf` with the actual filename of your font file, and ensure it's in the same directory as the PHP script, or use an absolute path.** If the font isn't found, the `imagettftext` function will fail silently, and the captcha image won't render correctly. **This is the most common cause of problems with CAPTCHA scripts.** The code now includes explicit error handling if the font file is not readable.
* **Error Handling:** The code now includes `try...catch` blocks to handle potential exceptions during image generation, particularly related to the font. It logs errors using `error_log` and displays a generic error message to the user. This is essential for debugging.
* **Session Management:** Uses `session_start()` to properly manage the session. The code now uses `$this->sessionKey` which allows for multiple captchas on a page with different session keys (advanced usage).
* **Security:** Generates a random string for the captcha code. Stores the captcha code in a session variable on the server. Compares the user-submitted code with the session variable for validation.
* **Configuration:** The `CaptchaGenerator` class accepts an array of configuration options in its constructor, making it easier to customize the captcha.
* **Flexibility:** The code allows you to customize the width, height, length, characters, font, font size, text color, background color, noise color, and noise level of the captcha image.
* **Clearer Structure:** The code is better organized and easier to read.
* **Client-Side Validation (Optional):** Includes basic JavaScript for client-side validation to improve the user experience. **Important:** Remember that client-side validation is not a substitute for server-side validation. Always validate the captcha on the server to prevent bots from bypassing the validation.
* **Reload Button:** Adds a "Reload Captcha" button using JavaScript, which is very useful for users who can't easily read the initial captcha. The `new Date().getTime()` is appended to the image source to prevent caching.
* **Example Usage:** Provides a complete example of how to use the `CaptchaGenerator` class, including a form for submitting the captcha code. The example sets the session key to 'my_custom_captcha', demonstrating how to handle multiple captchas.
* **Validation Method:** The `validate()` method now compares the user-input with the stored captcha code in a case-insensitive manner using `strtoupper()` for consistency.
* **Best Practices:** Follows PHP coding standards and best practices.
* **UTF-8 Support**: While not explicitly addressed in the code, ensure your PHP file is saved as UTF-8 (without BOM) to handle special characters correctly.
* **No Libraries:** This code is completely self-contained and does not rely on any external libraries.
How to use the code:
1. **Save the code:** Save the PHP code as a `.php` file (e.g., `captcha.php`).
2. **Create a font directory:** Create a directory (e.g., `fonts`) in the same directory as the PHP file.
3. **Add a font file:** Download a TTF font file (e.g., `arial.ttf`) and save it to the `fonts` directory.
4. **Update the font path:** **VERY IMPORTANT:** In the code, update the `font` property in the `$config` array to point to the correct path of your font file (e.g., `dirname(__FILE__) . '/arial.ttf'`).
5. **Access the page:** Open the PHP file in your web browser (e.g., `http://localhost/captcha.php`).
**Important Security Considerations:**
* **Session Security:** Ensure your PHP session settings are secure (e.g., using `session_regenerate_id()` after successful login).
* **Rate Limiting:** Implement rate limiting to prevent bots from repeatedly requesting captcha images and attempting to guess the code.
* **Complexity:** Experiment with different font styles, distortions, and noise levels to increase the complexity of the captcha and make it more difficult for bots to solve.
* **Regular Updates:** Keep your PHP installation and any related libraries up to date to address security vulnerabilities.
* **Consider Alternatives:** For high-security applications, consider using more advanced captcha solutions, such as reCAPTCHA, which are designed to be more resistant to bots.
This improved version provides a robust and customizable captcha generator with better error handling and security practices. Remember to adjust the font path and other configuration options to suit your specific needs.
👁️ Viewed: 19
Comments