How to Stop PHP Form Spam (Without a Plugin)
If your PHP mail script is being abused by bots, stop the bot before mail() runs — server-side CAPTCHA verification in a few lines of PHP, via Procaptcha.

CAPTCHA Updated 6 min read

If your PHP contact form is being abused — mail() firing thousands of times a day, your inbox filled with junk, your shared host warning you about outbound mail limits — the fix isn't in PHP. The form is doing exactly what you wrote it to do. The problem is who is submitting it.
This is a server-side problem with a server-side answer: verify that the request came from a real person (or a trusted agent) before mail() runs. The rest of this post walks through how to do that in a few lines of PHP using the Procaptcha API — no WordPress plugin required, no JavaScript framework, no rewriting of your existing form.
Why "spam PHP" isn't really a PHP problem
PHP forms get spammed because they're easy targets:
- The HTML form is on a static URL — a bot can POST to it from anywhere.
- The backend (
mail(), PDO, an HTTP webhook, anything) trusts the request and runs. - Standard PHP doesn't have any concept of "this came from a browser, not a script".
Adding a server-side check is the only real fix. Honeypot fields catch the laziest bots. Time-on-page checks catch a few more. Modern bots solve both within a year of any new technique appearing in the wild — and the bots written for AI training, those used by residential-proxy networks, and the agentic shopping bots that solve image puzzles in 200ms don't care about any of them.
A CAPTCHA that runs server-side and that the bot can't pre-solve is the only durable answer.
The three-line fix
The shape of the integration is the same for every PHP setup:
- Embed the Procaptcha widget in your form.
- On submit, the widget returns a token in a hidden field.
- Your PHP handler POSTs that token to Procaptcha's verification endpoint before running
mail()or anything else.
If the token is invalid, you reject the submission. If it's valid, you proceed.
<?php
// process-form.php
$token = $_POST['procaptcha-response'] ?? '';
if (empty($token)) {
http_response_code(400);
exit('Verification missing.');
}
$verify = curl_init('https://api.prosopo.io/siteverify');
curl_setopt_array($verify, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query([
'secret' => getenv('PROCAPTCHA_SECRET'),
'token' => $token,
]),
]);
$response = json_decode(curl_exec($verify), true);
curl_close($verify);
if (empty($response['verified'])) {
http_response_code(400);
exit('Verification failed.');
}
// Only now do we call mail().
$name = strip_tags($_POST['name'] ?? '');
$email = filter_var($_POST['email'] ?? '', FILTER_SANITIZE_EMAIL);
$message = strip_tags($_POST['message'] ?? '');
mail(
'inbox@example.com',
'Contact form: ' . $name,
$message,
"From: $email"
);
echo 'Thanks — we got your message.';
The widget on the form side is one script tag plus a <div>:
<form method="POST" action="/process-form.php">
<input type="text" name="name" required>
<input type="email" name="email" required>
<textarea name="message" required></textarea>
<div data-procaptcha
data-sitekey="<?= htmlspecialchars(getenv('PROCAPTCHA_SITE_KEY')) ?>"></div>
<button type="submit">Send</button>
</form>
<script src="https://js.prosopo.io/js/procaptcha.bundle.js" async defer></script>That's the whole integration. The mail() call never runs unless verification passes — so the bot can spray a thousand POSTs at process-form.php and not one of them turns into an outbound email.
What about Laravel / Symfony?
The pattern is identical — POST to /siteverify with the token, fail closed if it doesn't come back verified. In Laravel you'd typically wrap it in a form-request rule; in Symfony, a validator constraint. The HTTP call itself is the same Guzzle / Symfony HttpClient request, and the response shape is the same. No PHP-specific package required.
Why this is the right layer to fix it
PHP form spam often gets "solved" by adding mail-side rules — SPF, DKIM, DMARC, rate-limiting the outbound queue. None of those address the actual problem. Your mail server is doing the right thing: it's sending the mail your application asked it to send. The application is asking it to send junk because the application can't tell humans from bots.
Verifying before mail() runs:
- Restores your sending reputation (no more bursts of bot-driven outbound mail).
- Stops shared-host abuse warnings.
- Cuts CRM and autoresponder costs (bots aren't subscribing to anything).
- Stops
Reply-Toinjection attacks and header-spoofing exploits dead in their tracks — the bot can't even submit the form to attempt them.
Pricing and free tier
Procaptcha covers 10,000 verifications a month on the free tier. For a typical PHP contact form that's well above what real traffic uses, so the integration costs nothing for most sites. Paid plans start at $39/month and include the Spam Filter at no extra cost — Gmail dot-trick blocking, VPN/Tor traffic filters, and disposable-domain detection — for forms that need belt-and-braces protection.
See the pricing page for the full breakdown, or get in touch via the form below if you want a hand wiring it up.
Related
- Spam bot protection — the broader use case across every form type and platform.
- How Prosopo Spam Filter works — the email/traffic filter that pairs with the CAPTCHA.
- Best CAPTCHA in 2026 — comparison if you're evaluating Procaptcha against alternatives.
Stop PHP form spam at the source
A Bot Exposure Assessment is a 30-minute call with an engineer. We look at your traffic, show where your current setup leaves gaps, and agree how a trial would be judged. Nothing to install first.
Related reading
CAPTCHA · What is the best value CAPTCHA in 2024? Find out what the best value CAPTCHA is in 2024 and how it compares to other popular CAPTCHA solutions.
Ticketing · How Do Ticket Scalpers Get Tickets? Bots, Tactics & Defenses Ticket scalping meaning, how ticket scalpers get tickets before fans, and the bot tactics behind resale markups — plus what venues can do about it.
CAPTCHA · hCaptcha and GDPR - Privacy Claims Warrant Scrutiny Examination of hCaptcha reveals several potential friction points with GDPR principles.
CAPTCHA · Best CAPTCHA 2026: 7 Top Solutions Compared What is the best CAPTCHA in 2026? Compare pricing, privacy, GDPR compliance and bot-stopping power across the 7 leading CAPTCHA solutions.