Spam Eater for PHP: stop form spam without a CAPTCHA

Stop contact form spam on any PHP site without a CAPTCHA. Spam Eater for PHP forms runs every check on your own server: free, open source, no account.

Spam Eater for PHP forms 0.1: stops spam on any PHP site with no CAPTCHA, no account, running on your own server. MIT and free.

If you run a PHP website that isn’t WordPress, there’s now a simple way to stop contact form spam without a CAPTCHA. Spam Eater for PHP forms takes the checks from our WordPress anti-spam plugin and packages them for any PHP site or app. Your visitors never solve a puzzle, there’s no account to create, and nothing they type is sent anywhere: every check runs on your own server. It’s free and open source.

Get it: composer require accessnow/spam-eater, or download it from the project page. It needs PHP 7.4 or later and nothing else.

Why another anti-spam tool?

A hand-built PHP form has had three ways to keep bots out, and each has a catch:

  • A CAPTCHA such as reCAPTCHA or Turnstile. It loads a script from another company, and some versions set cookies or show a puzzle to real people.
  • A cloud spam service. It sends what your visitors type to someone else’s server to be judged, and most charge once you’re past a small free allowance.
  • A honeypot you write yourself. It’s quick to add, but on its own it only catches the simplest bots.

The one tool that covered any PHP site by adding a single file, CleanTalk’s universal anti-spam, stopped development in November 2024, and its support ended in November 2025. If you used it, Spam Eater is a replacement that doesn’t need an account.

How it tells bots from people

Each submission goes through a few quiet checks. A real person passes all of them without noticing:

  • a hidden field that people never see, but bots fill in;
  • a value set by a small script, so bots that don’t run JavaScript are caught;
  • a signed timestamp, so a form sent within three seconds of loading, or tampered with, is refused;
  • proof that the mouse, keyboard, touch screen or scroll wheel was used on the page.

An address that keeps filling in the hidden field is blocked for 24 hours. You can also add your own words, phrases and patterns, for spam that people type by hand, and turn away about 9,000 throwaway email services. Every refusal comes with a short reference code, such as SE-E3 for “sent too fast”, so you can see which check caught it without telling a bot what to change.

Adding it to a form

Set it up once, with a secret of your own and a folder outside your web root for the block list:

$guard = new AccessNowSpamEaterGuard( array(
    'secret'  => 'a long random string',
    'storage' => '/a/folder/outside/your/web/root',
) );

Print the hidden fields inside the form and the script once after it:

<form method="post">
    ...your fields...
    <?= $guard->field() ?>
    <button>Send</button>
</form>
<?= $guard->script() ?>

Then check the submission before you send the email:

if ( $guard->check() ) {
    exit( 'Sorry, your message could not be sent. Reference: ' . $guard->failCode() );
}

It works with page caching, sites behind Cloudflare or another proxy, and a strict Content Security Policy. The documentation on GitHub covers login forms, forms that appear after the page loads, and keeping the block list in your own database.

Already at work

Spam Eater for PHP forms already protects the support form of Taikai, our karate tournament app, which takes messages from anyone without signing in. On WordPress, the same checks run in AccessNow Spam Eater, which also covers comments, WooCommerce checkout and more than 30 form plugins. Read what’s new in Spam Eater 2.4 for the latest on that side.

Privacy

There are no cookies, no tracking and no calls to outside services. What people type is checked in memory and never stored. The block list keeps only a one-way hash of each address, and its entries expire by themselves.

Get Spam Eater for PHP forms

Install it with composer require accessnow/spam-eater, or download it from the Spam Eater for PHP forms project page. The source code is on GitHub under the MIT licence, so you can use it on any site, commercial or not.

martin Avatar

Written by

Previous post
Next post

More from the blog