PHP code example of rpillz / laravel-visitor

1. Go to this page and download the library: Download rpillz/laravel-visitor library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

rpillz / laravel-visitor example snippets


// config/database.php
'visitor' => [
    'driver' => 'sqlite',
    'database' => storage_path('app/analytics.sqlite'),
],

// config/database.php
'visitor_remote' => [
    'driver'    => 'libsql',
    'url'       => env('VISITOR_DB_URL'),
    'authToken' => env('VISITOR_DB_AUTH_TOKEN'),
    'prefix'    => '',
],

// config/visitor.php
'auto_track' => false,

// routes/web.php
Route::middleware('visitor.track')->group(function () {
    Route::get('/', HomeController::class);
    // ...
});

use RPillz\LaravelVisitor\Facades\Visitor;

Visitor::track($request);

Visitor::anonymous()->track($request);

'anonymous' => false,

// AppServiceProvider::boot()
use RPillz\LaravelVisitor\LaravelVisitor;

LaravelVisitor::resolveConnectionUsing(function () {
    return tenant() ? 'tenant_' . tenant()->id : config('visitor.connection', 'visitor');
});

Visitor::setConnection('tenant_42')->track($request);

// routes/console.php
Schedule::command('visitor:prune')->daily();

'block_probes' => true, // set false to disable entirely

'probe_paths' => [
    'wp-admin*',
    'wp-login*',
    '.env*',
    'phpinfo*',
    'xmlrpc.php',
    // add your own patterns — supports * and ? wildcards
],

'probe_block_duration' => env('VISITOR_PROBE_BLOCK_DURATION', 60*24*3), // minutes, null = permanent

'probe_404' => [
    'threshold' => env('VISITOR_PROBE_404_THRESHOLD', 5), // 404s before blocking
    'window'    => env('VISITOR_PROBE_404_WINDOW', 3),    // rolling window in minutes
],

'verified_crawlers' => [
    'enabled'   => env('VISITOR_VERIFIED_CRAWLERS', true),
    'cache_ttl' => env('VISITOR_CRAWLER_CACHE_TTL', 1440), // minutes per IP
    'ip_lists'  => [
        'https://raw.githubusercontent.com/hexydec/ip-ranges/main/output/crawlers.json',
    ],
],

// Blocked by name, even if IP-verified
'block_verified_bots' => [
    'ClaudeBot', 'GPTBot', 'PerplexityBot', 'Amazonbot', 'CCBot', 'Bytespider',
    'Meta-WebIndexer', 'Meta-ExternalAds', 'Meta-ExternalAgent',
    'Semrush', 'Ahrefs', 'DotBot', 'MJ12bot', 'Diffbot', 'PetalBot', 'Scrapy',
],

// Block any crawler that cannot prove its identity (default: true)
'block_unverified_bots' => env('VISITOR_BLOCK_UNVERIFIED_BOTS', true),

'allow_agents' => [
    'Phare',           // Phare uptime monitor
    'UptimeRobot',     // UptimeRobot
],

'rate_limit' => [
    'enabled'    => env('VISITOR_RATE_LIMIT', true),
    'threshold'  => env('VISITOR_RATE_LIMIT_THRESHOLD', 60), // requests per window
    'window'     => env('VISITOR_RATE_LIMIT_WINDOW', 1),     // minutes
    'auto_block' => env('VISITOR_RATE_LIMIT_AUTO_BLOCK', true),
],

'robots_txt' => [
    'enabled' => env('VISITOR_ROBOTS_TXT', false),
    'disallow' => [
        'ClaudeBot', 'Amazonbot', 'meta-externalagent',
        'meta-webindexer', 'meta-externalads',
        'GPTBot', 'Google-Extended', 'PerplexityBot', 'CCBot',
    ],
],

'log_blocks' => env('VISITOR_LOG_BLOCKS', true),

use RPillz\LaravelVisitor\Filament\VisitorPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        // ...
        ->plugins([
            VisitorPlugin::make(),
        ]);
}

> 'silenced' => [
>     \RPillz\LaravelVisitor\Jobs\TrackVisitJob::class,
> ],
> 

// config/visitor.php

return [
    // Database connection for visit records
    'connection' => env('VISITOR_DB_CONNECTION', 'visitor'),

    // Queue connection and name for the tracking job
    'queue' => [
        'connection' => env('VISITOR_QUEUE_CONNECTION', null),
        'name'       => env('VISITOR_QUEUE_NAME', 'default'),
    ],

    // Automatically append visitor.track to the web middleware group
    'auto_track' => env('VISITOR_AUTO_TRACK', true),

    // Paths to exclude from tracking (supports * and ? wildcards)
    'exclude_paths' => [
        'admin*', '_debugbar*', 'horizon*', 'telescope*', 'livewire*', '_ignition*',
    ],

    // Track bot/crawler visits (stores bot_name, fingerprint, is_verified)
    'track_bots' => env('VISITOR_TRACK_BOTS', true),

    // Skip requests from these IPs
    'exclude_ips' => [],

    // Only track these HTTP methods
    'track_methods' => ['GET'],

    // Never store the authenticated user ID
    'anonymous' => true,

    // Never store IP addresses (also skips country/city resolution)
    'store_ip' => env('VISITOR_STORE_IP', false),

    // Prevent duplicate records for the same session+path within a rolling window
    'deduplication' => [
        'enabled' => env('VISITOR_DEDUP_ENABLED', true),
        'window'  => env('VISITOR_DEDUP_WINDOW', 30), // minutes
    ],

    // Local MaxMind GeoLite2 database for country/city resolution (disabled by default)
    'geoip' => [
        'enabled'  => env('VISITOR_GEOIP_ENABLED', false),
        'database' => env('VISITOR_GEOIP_DATABASE', storage_path('app/geoip/GeoLite2-City.mmdb')),
    ],

    // Bot names (resolved from User-Agent) to block even when IP-verified
    'block_verified_bots' => [
        'ClaudeBot', 'GPTBot', 'PerplexityBot', 'Amazonbot', 'CCBot', 'Bytespider',
        'Meta-WebIndexer', 'Meta-ExternalAds', 'Meta-ExternalAgent',
        'Semrush', 'Ahrefs', 'DotBot', 'MJ12bot', 'Diffbot', 'PetalBot', 'Scrapy',
    ],

    // Block any crawler that cannot be verified via rDNS or a published IP list
    'block_unverified_bots' => env('VISITOR_BLOCK_UNVERIFIED_BOTS', true),

    // User-Agent substrings that bypass block_verified_bots and block_unverified_bots
    'allow_agents' => [
        // 'Phare',
    ],

    // Fingerprint-based rate limiter — catches high-volume scrapers that hit only valid pages
    'rate_limit' => [
        'enabled'    => env('VISITOR_RATE_LIMIT', true),
        'threshold'  => env('VISITOR_RATE_LIMIT_THRESHOLD', 60), // requests per window
        'window'     => env('VISITOR_RATE_LIMIT_WINDOW', 1),     // minutes
        'auto_block' => env('VISITOR_RATE_LIMIT_AUTO_BLOCK', true),
    ],

    // Serve GET /robots.txt with Disallow entries for each listed User-agent
    'robots_txt' => [
        'enabled' => env('VISITOR_ROBOTS_TXT', false),
        'disallow' => [
            'ClaudeBot', 'Amazonbot', 'meta-externalagent',
            'meta-webindexer', 'meta-externalads',
            'GPTBot', 'Google-Extended', 'PerplexityBot', 'CCBot',
        ],
    ],

    // Auto-block IPs and fingerprints that hit probe paths; return 404
    'block_probes' => env('VISITOR_BLOCK_PROBES', true),

    // Record blocked requests as visits with is_blocked=true (excluded from analytics)
    'log_blocks' => env('VISITOR_LOG_BLOCKS', true),

    // Paths treated as probe/scanner activity (supports wildcards)
    'probe_paths' => [
        'wp-admin*', 'wp-login*', '.env*', 'phpinfo*', 'xmlrpc.php',
    ],

    // How long auto-blocks last (minutes); null = permanent
    'probe_block_duration' => env('VISITOR_PROBE_BLOCK_DURATION', 60 * 24 * 3), // 3 days

    // Auto-block IPs that hit this many 404s within the window
    'probe_404' => [
        'threshold' => env('VISITOR_PROBE_404_THRESHOLD', 5),
        'window'    => env('VISITOR_PROBE_404_WINDOW', 3), // minutes
    ],

    // Verify legitimate search engine bots via rDNS and published IP lists
    'verified_crawlers' => [
        'enabled'   => env('VISITOR_VERIFIED_CRAWLERS', true),
        'cache_ttl' => env('VISITOR_CRAWLER_CACHE_TTL', 1440), // minutes per IP
        'ip_lists'  => [
            'https://raw.githubusercontent.com/hexydec/ip-ranges/main/output/crawlers.json',
        ],
    ],

    // Retention period for visit records
    'pruning' => [
        'enabled' => true,
        'days'    => env('VISITOR_PRUNE_DAYS', 90),
    ],
];

// config/visitor.php
'anonymous' => false,
'store_ip' => true,

Artisan::call('visitor:forget', ['userId' => $user->id, '--force' => true]);

// config/visitor.php
'pruning' => ['enabled' => true, 'days' => 90],

// routes/console.php
Schedule::command('visitor:prune')->daily();
bash
php artisan visitor:install
bash
php artisan vendor:publish --tag="visitor-config"
php artisan vendor:publish --tag="visitor-migrations"
php artisan migrate
bash
php artisan visitor:prune --days=90
bash
# By user ID
php artisan visitor:forget {userId}

# By session ID (for anonymous visitors)
php artisan visitor:forget --session={sessionId}

# By IP address
php artisan visitor:forget --ip={ipAddress}