PHP Integration

Track bot and AI crawler visits from any PHP application. Works with Laravel, Symfony, and plain PHP.

For WordPress, use the dedicated WordPress plugin instead.

Time to set up: ~2 minutes

Prerequisites

  • A PHP application (7.4+)
  • A BotSights account with a project created for your domain
  • Your API Key (found in BotSights → Account → Projects → API Key)

Plain PHP

Add one line at the top of your entry point (e.g. index.php):

require_once 'botsights.php';
botsights_track();

Create botsights.php:

<?php
define('BOTSIGHTS_API_KEY', 'YOUR_API_KEY_HERE');
define('BOTSIGHTS_API_URL', 'https://www.botsights.com/api/log');
 
function botsights_track() {
    $skip = ['css','js','png','jpg','jpeg','gif','svg','webp','ico','woff','woff2','ttf','mp4'];
    $path = parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH);
    $ext = strtolower(pathinfo($path, PATHINFO_EXTENSION));
    if (in_array($ext, $skip)) return;
 
    $start = microtime(true);
    register_shutdown_function(function () use ($start) {
        $ip = $_SERVER['HTTP_CF_CONNECTING_IP']
            ?? explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'] ?? '')[0]
            ?? $_SERVER['HTTP_X_REAL_IP']
            ?? $_SERVER['REMOTE_ADDR'] ?? '';
 
        $data = json_encode([
            'api_key'      => BOTSIGHTS_API_KEY,
            'ua'           => $_SERVER['HTTP_USER_AGENT'] ?? '',
            'url'          => $_SERVER['REQUEST_URI'] ?? '/',
            'ip'           => trim($ip),
            'referer'      => $_SERVER['HTTP_REFERER'] ?? '',
            'status_code'  => http_response_code(),
            'duration_ms'  => intval((microtime(true) - $start) * 1000),
            'http_method'  => $_SERVER['REQUEST_METHOD'] ?? 'GET',
            'source'       => 'php',
        ]);
 
        $ctx = stream_context_create(['http' => [
            'method'  => 'POST',
            'header'  => "Content-Type: application/json\r\n",
            'content' => $data,
            'timeout' => 2,
            'ignore_errors' => true,
        ]]);
        @file_get_contents(BOTSIGHTS_API_URL, false, $ctx);
    });
}

Laravel

Create app/Http/Middleware/BotSights.php:

<?php
namespace App\Http\Middleware;
 
use Closure;
use Illuminate\Http\Request;
 
class BotSights
{
    private const API_KEY = 'YOUR_API_KEY_HERE';
    private const API_URL = 'https://www.botsights.com/api/log';
    private const SKIP = ['css','js','png','jpg','jpeg','gif','svg','webp','ico','woff','woff2','mp4'];
 
    public function handle(Request $request, Closure $next)
    {
        $ext = strtolower(pathinfo($request->path(), PATHINFO_EXTENSION));
        if (in_array($ext, self::SKIP)) return $next($request);
 
        $start = microtime(true);
        $response = $next($request);
        $duration = intval((microtime(true) - $start) * 1000);
 
        app()->terminating(function () use ($request, $response, $duration) {
            $data = json_encode([
                'api_key'      => self::API_KEY,
                'ua'           => $request->userAgent() ?? '',
                'url'          => $request->getRequestUri(),
                'ip'           => $request->ip(),
                'referer'      => $request->headers->get('referer', ''),
                'status_code'  => $response->getStatusCode(),
                'duration_ms'  => $duration,
                'content_type' => $response->headers->get('Content-Type', ''),
                'http_method'  => $request->method(),
                'source'       => 'php_laravel',
            ]);
 
            $ctx = stream_context_create(['http' => [
                'method'  => 'POST',
                'header'  => "Content-Type: application/json\r\n",
                'content' => $data,
                'timeout' => 2,
                'ignore_errors' => true,
            ]]);
            @file_get_contents(self::API_URL, false, $ctx);
        });
 
        return $response;
    }
}

Register in app/Http/Kernel.php:

protected $middleware = [
    \App\Http\Middleware\BotSights::class,
    // ... other middleware
];

How It Works

  • Plain PHP: Uses register_shutdown_function() to send analytics after the response is complete
  • Laravel: Uses app()->terminating() which fires after the response is sent to the browser
  • Both are non-blocking — zero impact on page load speed
  • Server-side — captures all visitors including bots
  • No dependencies — uses PHP's built-in file_get_contents
  • No cookies or client-side code

Troubleshooting

No data appearing?

  • Check that allow_url_fopen is enabled in your php.ini
  • Verify your server can make outbound HTTPS requests
  • Check your API key is correct
  • If behind a firewall, whitelist bot-analytics-nvd.vercel.app