PHP still runs most of the web — and PHP sites get most of the bot abuse: form spam on WordPress comment forms, credential stuffing on login pages, scrapers on price pages. This tutorial walks through real PHP bot protection, from install to challenge flow, using an installable package instead of hand-rolled snippets.
Why include-first protection beats "check it in the form"
Many PHP tutorials show you how to check a CAPTCHA inside a form handler. That's too late and too narrow: bots hit every page, not just forms. The pattern that works is include-first: a single file included at the very top of your entry point evaluates every request before your application runs — and can allow, challenge, or block before any HTML is sent.
Step 1 — Get your API key
- Create a free XAntiBot account (no credit card).
- Dashboard → API Keys → create a key.
- The key is shown once — store it in server-side configuration, never in HTML or browser JavaScript.
Step 2 — Install the PHP package
Download the official PHP Blocker from the dashboard (it's also linked from the docs). Install:
- Copy the package folder into your site (e.g.
/var/www/mysite/xantibot/). - Copy
config.php.example→config.phpand set:
// xantibot/config.php
return [
'api_key' => 'xb_your_real_key_here', // server-side only!
'domain' => 'yourwebsite.com',
// Failure mode when the detection API is unreachable:
'failure_mode' => 'deny', // or 'allow' — your availability-vs-safety choice
];
- Include it at the very top of your front controller (
index.php):
<?php
require __DIR__ . '/xantibot/protect.php';
That's the whole integration. Every request is now evaluated before your app runs.
What the package does on each request
- Sends the visitor's IP + User-Agent + your domain to the XAntiBot detection API.
- Reads the decision:
- allow → your site runs normally. - block → clean 403 page (branded, from the package). - challenge → renders a challenge page (see Step 4).
- Caches decisions for a short window to keep latency near zero for repeat visitors.
- Fails safe: if the API is unreachable, your
failure_modedecides (deny= strict protection;allow= availability first).
(Pattern matches the shipped package; verify option names against the current README inside the ZIP.)
Step 3 — Works with WordPress / Laravel / anything PHP
Because it's include-first at the front controller:
- WordPress: include in
wp-config.php's earliest hook or the top ofindex.php. - Laravel: include in
public/index.phpbefore the framework boots. - Any other PHP app: top of the front controller.
Step 4 — Challenge flow (Turnstile)
When the decision is challenge, the package renders a challenge page backed by Cloudflare Turnstile (invisible-first, CAPTCHA-like only when needed). Configure your Turnstile site/secret keys once; the gateway verifies the token server-side before letting the visitor through. Full walkthrough: Cloudflare Turnstile Integration Guide.
Step 5 — Protect form submissions specifically
Form-spam bots usually pass the page once and POST immediately. Extra layers that work:
- Honeypot field — hidden input humans never fill.
- Minimum submit time — reject submissions under ~3 seconds.
- Rate limit per IP on the form route.
- Let the API decision handle the rest — most form-spam bots are already blocked at step 3 above.
Step 6 — Verify it's working
- Visit your site normally → loads fine (
allow). - Check the XAntiBot dashboard → Detection Logs show your visit with score + reasons.
- (Optional) send a request with a bot-like client (e.g.
curlwith no browser headers) → expectchallengeorblockper your rules.
# Quick sanity test from a terminal (not a browser):
curl -s -X POST https://xantibot.com/api/check \
-H "Content-Type: application/json" -H "X-API-Key: $XAB_KEY" \
-d '{"ip":"203.0.113.9","ua":"curl/8.0","domain":"yourwebsite.com"}'
(Not execution-tested here — verify against current docs.)
Common mistakes
- Putting the API key in frontend code (anyone can steal it).
- Setting
failure_mode: allowand forgetting it exists (protection silently off during outages). - Testing with your own whitelisted IP and concluding "it doesn't work" for others.
- Blocking your monitoring's IPs — whitelist uptime monitors deliberately.
FAQ
Does this work on shared hosting? Yes — it's plain PHP + cURL; no server extensions needed. Will it block Google? No — real search crawlers are verified (reverse-DNS) and allowed; fake "Googlebot" user-agents are scored like any bot. How much does it cost? The detection API has a real free tier; paid plans are transparent per-month (see pricing).
Next steps
Create your free account → download the PHP package → protect your first page in minutes.