Search by

neto737 / xeoncaptcha

neto737

A simple CAPTCHA system written in PHP

Package info

github.com/neto737/xeonCAPTCHA

pkg:composer/neto737/xeoncaptcha

Statistics

Installs: 188

Dependents: 0

Suggesters: 0

Stars: 2

Open Issues: 0

1.1.4 2026-10-19 07:04 UTC

This package is auto-updated.

Last update: 2026-10-19 07:07:11 UTC


README

A simple, dependency-free CAPTCHA for PHP.
Show a distorted text or math challenge as an image and check the answer with one call.

Latest Stable Version Total Downloads PHP 7.4 or later License

Features

  • Two challenge types: random letters, or a simple sum such as 12+9.
  • Four image formats: PNG, JPEG, GIF and WebP.
  • Customisable image: size, font size, number of characters, background colour and text position.
  • One-call validation: case-insensitive, ignores surrounding spaces, and each CAPTCHA can only be used once.
  • Secure by default: answers are generated with random_int(), compared with the timing-safe hash_equals(), and the image is sent with no-cache headers.
  • No dependencies other than PHP's GD extension. The answer is kept in the PHP session.

Requirements

  • PHP 7.4 or later
  • The GD extension with FreeType support, and support for the image format you choose (for example, WebP)
  • PHP sessions

Installation

composer require neto737/xeoncaptcha

Quick start

A CAPTCHA has two parts: a script that sends the image, and a check when the form is submitted.

1. Send the image (for example, captcha.php):

require 'vendor/autoload.php';

use neto737\xeonCAPTCHA;

// Pass true as the second argument for a math CAPTCHA
$xeon = new xeonCAPTCHA(xeonCAPTCHA::IMG_PNG, false);

// 155×30 image, font size 20, 5 characters, bundled font, white background, text baseline at 22px
$xeon->generateCAPTCHA(155, 30, 20, 5, 'xeonCAPTCHA', '', 22);

2. Show it in your form:

<form method="POST" action="submit.php">
    <img src="captcha.php" alt="CAPTCHA">
    <input type="text" name="CAPTCHA" autocomplete="off">
    <button type="submit">Send</button>
</form>

3. Check the answer (in submit.php):

require 'vendor/autoload.php';

use neto737\xeonCAPTCHA;

$xeon = new xeonCAPTCHA(xeonCAPTCHA::IMG_PNG);

if ($xeon->validateCAPTCHA($_POST['CAPTCHA'] ?? '')) {
    // Correct answer
} else {
    // Wrong answer, or the CAPTCHA was already used
}

Note

The answer is removed from the session after every check, right or wrong. After a wrong answer, show a new image. If you set a custom session name when creating the image, use the same name when you validate.

API reference

new xeonCAPTCHA($imageType, $mathCAPTCHA = false, $sessionName = 'xeonCode')

Starts the PHP session if it isn't started yet.

Argument Type Description
$imageType int xeonCAPTCHA::IMG_PNG, IMG_JPEG, IMG_GIF or IMG_WEBP
$mathCAPTCHA bool true for a sum (answer from 0 to 60), false for letters
$sessionName string The session key where the answer is stored

generateCAPTCHA($width, $height, $fontSize, $length = 5, $font = 'xeonCAPTCHA', $bgRGB = '', $posY = 33)

Sends the image to the browser along with its Content-Type and no-cache headers, then returns true. Call it before any other output.

Argument Type Description
$width, $height int Image size in pixels
$fontSize int Font size. Each character is drawn up to 2 points smaller and rotated at random.
$length int Number of letters (A–Z, no repeats). Ignored for math CAPTCHAs.
$font string Name of a .ttf file in the library's src/ directory, without the extension. Only the bundled xeonCAPTCHA font is included.
$bgRGB string Background colour as RRR_GGG_BBB, for example 240_240_255. Empty means white.
$posY int Vertical position of the text baseline, in pixels

Note

Characters are placed 30px apart, and the noise is sized for a small image. Sizes close to the examples above (about 155×30 to 155×40, font size 20) give the best results.

validateCAPTCHA($inputCode): bool

Returns true if $inputCode matches the current CAPTCHA. Letter case and surrounding spaces are ignored. Non-string input (for example, CAPTCHA[]=x) returns false. The stored answer is always removed, so each CAPTCHA can only be checked once.

Error handling

Problems with your setup or arguments are thrown as exceptions:

try {
    $xeon = new xeonCAPTCHA(xeonCAPTCHA::IMG_WEBP);
    $xeon->generateCAPTCHA(155, 30, 20, 5, 'xeonCAPTCHA', '240_240_255', 22);
} catch (\RuntimeException $e) {
    // GD, FreeType or the chosen image format is not available
} catch (\InvalidArgumentException $e) {
    // $font is not a plain font name or the font doesn't exist,
    // or $bgRGB is not in the RRR_GGG_BBB format (0 to 255)
}

A wrong answer is not an error: validateCAPTCHA() returns false.

Upgrading from 1.1.3? Version 1.1.4 needs PHP 7.4 or later. It now throws the exceptions above instead of failing later with warnings or fatal errors. Nothing else changes.

Examples

The examples/ folder contains a text CAPTCHA form, a math CAPTCHA form, and the script that sends their images.

Contributing

Bug reports and pull requests are welcome. Please keep the code compatible with PHP 7.4.

Credits

  • Created and maintained by Neto Melo.
  • The bundled font is "Cube vol.2" by TamaFactory.

Support the project ❤️

If this library saves you time, you can support its development via Liberapay, PayPal or crypto:

BTC: bc1q89ntljt5lk7g9z68f5cjs83qfm2xme7g4hkur7
ETH: 0xeef9220639F14E7A0FD825AAAd0574e5a8aD7A4B
LTC: ltc1q508qfkd09vyya6c5zkfx4r248pf3ezj9ngjdr2

License

Released under the MIT License.