vTilt
Why vTiltHow It WorksFeaturesFAQDocs
Docs / PHP
Quick startEvent forwarding
MCP server
Guides
OverviewAuthenticationOAuthAgent skills (prompts)AI intelligenceGoogle Ads
Client setup
CursorClaude DesktopVS CodeCodex
Realtime
Debug ViewRealtime Dashboard
Integration guides
Frontend frameworks
Next.jsNuxt.jsVue.jsReactReact RouterRemixGatsbySvelte / SvelteKitAstroAngularTanStack StartDocusaurus
Backend frameworks
NestJSHonoCloudflare WorkersDjangoFlaskLaravelPhoenixRuby on Rails
Backend languages
PythonPHPRubyElixirGoJava.NET / C#Rust
Stack guides
Vue + PHP
SDK
Browser SDK
InstallScript bundlesEvent trackingAutocaptureIdentify & aliasWeb VitalsSession recordingChat widgetFeature readinessRemote configurationReverse proxyDebug logging
Node SDK
Install & setupCapture, identify & aliasContext & shutdown

Documentation

vTilt
Quick startEvent forwarding

MCP server

Realtime

Debug ViewRealtime Dashboard

Integration guides

PythonPHPRubyElixirGoJava.NET / C#Rust

SDK

DocsIntegration guidesPHP

PHP

Send vTilt events from any PHP code (Symfony, Slim, scripts) by POSTing to the ingest API.

There's no native PHP SDK yet, but vTilt's wire format is a plain JSON POST so any PHP code can emit events. Use this guide for non-framework PHP projects (Symfony, Slim, plain PHP, CLI scripts). For Laravel and full-stack Vue + PHP, see the dedicated Laravel and Vue + PHP guides.

#1. Configure

# .env
VTILT_TOKEN=YOUR_PROJECT_TOKEN
VTILT_HOST=https://www.vtilt.com
text

#2. Capture helper

A small client built on curl_*. No Composer dependencies. Add Guzzle if you want a richer HTTP client.

<?php
// vtilt.php
function vtilt_capture(string $distinct_id, string $event, array $properties = []): void
{
    $payload = json_encode([
        'api_key'     => $_ENV['VTILT_TOKEN'],
        'event'       => $event,
        'distinct_id' => $distinct_id,
        'properties'  => $properties,
    ], JSON_THROW_ON_ERROR);

    $ch = curl_init(($_ENV['VTILT_HOST'] ?? 'https://www.vtilt.com') . '/api/e');
    curl_setopt_array($ch, [
        CURLOPT_POST           => true,
        CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
        CURLOPT_POSTFIELDS     => $payload,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 2,
    ]);
    @curl_exec($ch);
    curl_close($ch);
}

function vtilt_identify(string $distinct_id, array $properties): void
{
    vtilt_capture($distinct_id, '$identify', ['$set' => $properties]);
}
php

#3. Capture events

require __DIR__ . '/vtilt.php';

vtilt_identify('user_42', ['email' => 'alice@example.com', 'plan' => 'pro']);

vtilt_capture('user_42', 'purchase_completed', [
    'amount'   => 99.99,
    'currency' => 'USD',
]);
php

#4. Symfony Messenger (recommended)

Run captures in a queue handler so analytics never blocks the user-facing response.

#[AsMessageHandler]
class CaptureVTiltEventHandler
{
    public function __invoke(CaptureVTiltEvent $msg): void
    {
        vtilt_capture($msg->distinctId, $msg->event, $msg->properties);
    }
}
php

#Next steps

  • Laravel integration guide — Laravel-specific helpers + Blade layout.
  • Vue + PHP integration guide — full Vue front-end + PHP back-end walkthrough.
  • Identify & alias — full identification model.
  • Event forwarding — fan events out to GA4, Meta CAPI, PostHog.
PreviousPythonIntegration guidesNextRubyIntegration guides

On this page

  • 1. Configure
  • 2. Capture helper
  • 3. Capture events
  • 4. Symfony Messenger (recommended)
  • Next steps