🐘 PHP SDK
Официальный SDK для PHP с поддержкой современных фреймворков, PSR-7, PSR-18 и готовыми интеграциями
🎯 Что вы получите
- Простой и удобный API для отправки событий
- Поддержка PSR-7, PSR-17, PSR-18 (HTTP-клиенты)
- Интеграция с Laravel, Symfony, Yii2, WordPress
- Пакетная отправка событий
- Middleware для популярных фреймворков
Установка
# Установка через Composer
composer require instantbase/php-sdk
# С поддержкой Laravel (по желанию)
composer require instantbase/laravel-bridge
# С поддержкой Symfony
composer require instantbase/symfony-bundle
// Ручная установка (без Composer)
require_once '/path/to/instantbase-php-sdk/src/InstantBase.php';
// Автозагрузка классов
spl_autoload_register(function ($class) {
$prefix = 'InstantBase\\';
$base_dir = __DIR__ . '/vendor/instantbase/php-sdk/src/';
$len = strlen($prefix);
if (strncmp($prefix, $class, $len) !== 0) {
return;
}
$relative_class = substr($class, $len);
$file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';
if (file_exists($file)) {
require $file;
}
});
# Dockerfile
FROM php:8.2-cli
RUN apt-get update && apt-get install -y git unzip \
&& curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
WORKDIR /app
COPY composer.json ./
RUN composer install --no-dev
COPY . .
CMD ["php", "bin/console", "instantbase:process"]
Быстрый старт
<?php
require_once 'vendor/autoload.php';
use InstantBase\Client;
use InstantBase\Configuration;
// Конфигурация
$config = Configuration::create()
->withApiKey('your_api_key')
->withEnvironment('production')
->withDebug(true);
// Инициализация клиента
$client = new Client($config);
// Отправка простого события
$client->track('user_signup', [
'user_id' => 'user_123',
'method' => 'email'
]);
// Отправка события с метаданными
$client->track('purchase', [
'user_id' => 'user_123',
'amount' => 1499.99,
'order_id' => 'ORD-001'
], [
'is_order' => true,
'funnel_sales_step' => 4
]);
// Идентификация пользователя
$client->identify('user_123', [
'email' => 'user@example.com',
'name' => 'Иван Петров',
'plan' => 'premium'
]);
Конфигурация
Configuration
Параметры конфигурации
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
api_key |
string | — | Обязательный. Ваш API-ключ |
environment |
string | 'production' |
Режим работы: 'production' или 'development' |
debug |
bool | false |
Включает логирование ошибок |
timeout |
int | 5 |
Таймаут HTTP-запроса в секундах |
max_retries |
int | 3 |
Количество повторных попыток |
batch_size |
int | 10 |
Размер батча для пакетной отправки |
queue_enabled |
bool | false |
Использовать очередь (рекомендуется для продакшна) |
<?php
use InstantBase\Configuration;
// Fluent интерфейс
$config = Configuration::create()
->withApiKey($_ENV['INSTANTBASE_KEY'])
->withEnvironment('production')
->withDebug(false)
->withTimeout(10)
->withMaxRetries(5)
->withBatchSize(50)
->withQueueEnabled(true);
// Или массивом
$config = Configuration::fromArray([
'api_key' => $_ENV['INSTANTBASE_KEY'],
'environment' => 'production',
'debug' => false,
'timeout' => 10,
'max_retries' => 5,
'batch_size' => 50,
'queue_enabled' => true
]);
Основные методы
track()
Отправка события
Основной метод для отправки событий.
<?php
// Простое событие
$client->track('button_click', [
'user_id' => 'user_123',
'button' => 'signup',
'page' => '/home'
]);
// С метаданными
$client->track('purchase', [
'user_id' => 'user_123',
'order_id' => 'ORD-001',
'amount' => 1499.99
], [
'is_order' => true,
'funnel_sales_step' => 4
]);
// Анонимный пользователь
$client->track('page_view', [
'anonymous_id' => session_id(),
'page' => '/products'
]);
// С кастомным временем
$client->track('custom_event', [
'user_id' => 'user_123'
], [], time() - 3600); // час назад
| Параметр | Тип | Описание |
|---|---|---|
$event |
string | Название события |
$properties |
array | Свойства события (должен содержать user_id или anonymous_id) |
$metadata |
array | Метаданные события |
$timestamp |
int|null | Unix timestamp события (опционально) |
identify()
Идентификация пользователя
Устанавливает атрибуты пользователя.
<?php
// Простая идентификация
$client->identify('user_123', [
'email' => 'user@example.com',
'name' => 'Иван Петров',
'plan' => 'premium'
]);
// С метаданными атрибутов
$client->identify('user_123', [
'email' => 'user@example.com',
'plan' => 'premium'
], [
'plan' => [
'attribute_display_name' => 'Тариф',
'attribute_category' => 'Подписка'
]
]);
// При регистрации
$client->identify($user->id, [
'email' => $user->email,
'name' => $user->name,
'registered_at' => date('Y-m-d H:i:s')
]);
alias()
Связывание идентификаторов
Связывает анонимный ID с авторизованным пользователем.
<?php
// При авторизации
$client->alias(session_id(), $user->id);
// Если пользователь был анонимным
$anonymousId = $_COOKIE['anonymous_id'] ?? session_id();
$client->alias($anonymousId, $user->id);
trackBatch()
Пакетная отправка
Отправка нескольких событий одним запросом.
<?php
$events = [
[
'event' => 'page_view',
'properties' => ['user_id' => 'user_1', 'page' => '/home']
],
[
'event' => 'page_view',
'properties' => ['user_id' => 'user_2', 'page' => '/products']
],
[
'event' => 'purchase',
'properties' => ['user_id' => 'user_1', 'amount' => 100],
'metadata' => ['is_order' => true]
]
];
$client->trackBatch($events);
flush()
Принудительная отправка
Принудительно отправляет накопленные события из буфера.
<?php
// В конце скрипта
$client->flush();
// В деструкторе класса
public function __destruct()
{
$this->client->flush();
}
Интеграция с Laravel
Service Provider
<?php
// config/instantbase.php
return [
'api_key' => env('INSTANTBASE_KEY'),
'environment' => env('APP_ENV') === 'production' ? 'production' : 'development',
'debug' => env('APP_DEBUG', false),
'batch_size' => 50,
'queue_enabled' => true
];
<?php
// app/Providers/InstantBaseServiceProvider.php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use InstantBase\Client;
use InstantBase\Configuration;
class InstantBaseServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->singleton(Client::class, function ($app) {
$config = Configuration::fromArray([
'api_key' => config('instantbase.api_key'),
'environment' => config('instantbase.environment'),
'debug' => config('instantbase.debug'),
'batch_size' => config('instantbase.batch_size'),
'queue_enabled' => config('instantbase.queue_enabled')
]);
return new Client($config);
});
}
public function boot()
{
// Регистрируем фасад
$this->app->alias(Client::class, 'instantbase');
}
}
<?php
// app/Http/Middleware/TrackPageViews.php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
use InstantBase\Client;
class TrackPageViews
{
protected $client;
public function __construct(Client $client)
{
$this->client = $client;
}
public function handle($request, Closure $next)
{
$response = $next($request);
// Отслеживаем просмотр страницы
$userId = Auth::id();
$this->client->track('page_view', [
'user_id' => $userId ? (string) $userId : null,
'anonymous_id' => $request->session()->getId(),
'url' => $request->fullUrl(),
'path' => $request->path(),
'method' => $request->method()
]);
return $response;
}
}
Использование в контроллерах
<?php
namespace App\Http\Controllers;
use InstantBase\Client;
class OrderController extends Controller
{
protected $client;
public function __construct(Client $client)
{
$this->client = $client;
}
public function show($id)
{
$order = Order::findOrFail($id);
// Отслеживаем просмотр заказа
$this->client->track('order_view', [
'user_id' => (string) auth()->id(),
'order_id' => $order->id,
'amount' => (float) $order->total
], [
'funnel_sales_step' => 3
]);
return view('orders.show', compact('order'));
}
public function store(Request $request)
{
$order = Order::create($request->validated());
// Отслеживаем создание заказа
$this->client->track('order_created', [
'user_id' => (string) auth()->id(),
'order_id' => $order->id,
'amount' => (float) $order->total
], [
'is_order' => true,
'funnel_sales_step' => 4
]);
return redirect()->route('orders.show', $order);
}
}
Job для очередей
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use InstantBase\Client;
class TrackEventJob implements ShouldQueue
{
use InteractsWithQueue, Queueable, SerializesModels;
protected $event;
protected $properties;
protected $metadata;
public function __construct($event, $properties, $metadata = [])
{
$this->event = $event;
$this->properties = $properties;
$this->metadata = $metadata;
}
public function handle(Client $client)
{
try {
$client->track($this->event, $this->properties, $this->metadata);
} catch (\Exception $e) {
// Логируем ошибку
\Log::error('Failed to track event: ' . $e->getMessage());
// Повторяем задачу через 60 секунд
$this->release(60);
}
}
}
// Использование
TrackEventJob::dispatch('purchase', [
'user_id' => (string) $user->id,
'amount'' => $order->total
], ['is_order' => true]);
Интеграция с Symfony
# config/packages/instantbase.yaml
instantbase:
api_key: '%env(INSTANTBASE_KEY)%'
environment: '%kernel.environment%'
debug: '%kernel.debug%'
batch_size: 50
queue_enabled: true
<?php
// src/Service/InstantBaseService.php
namespace App\Service;
use InstantBase\Client;
use InstantBase\Configuration;
class InstantBaseService
{
private $client;
public function __construct(string $apiKey, string $environment, bool $debug)
{
$config = Configuration::create()
->withApiKey($apiKey)
->withEnvironment($environment)
->withDebug($debug);
$this->client = new Client($config);
}
public function getClient(): Client
{
return $this->client;
}
}
<?php
// src/EventSubscriber/TrackingSubscriber.php
namespace App\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\Security;
use App\Service\InstantBaseService;
class TrackingSubscriber implements EventSubscriberInterface
{
private $tracking;
private $security;
public function __construct(InstantBaseService $tracking, Security $security)
{
$this->tracking = $tracking->getClient();
$this->security = $security;
}
public function onKernelResponse(ResponseEvent $event)
{
$request = $event->getRequest();
// Не отслеживаем AJAX запросы
if ($request->isXmlHttpRequest()) {
return;
}
$user = $this->security->getUser();
$this->tracking->track('page_view', [
'user_id' => $user ? $user->getId() : null,
'anonymous_id' => session_id(),
'route' => $request->attributes->get('_route'),
'url' => $request->getUri()
]);
}
public static function getSubscribedEvents()
{
return [
KernelEvents::RESPONSE => ['onKernelResponse', -10]
];
}
}
Интеграция с WordPress
<?php
/**
* Plugin Name: InstantBase Tracking
* Description: Интеграция InstantBase с WordPress
* Version: 1.0.0
*/
require_once plugin_dir_path(__FILE__) . 'vendor/autoload.php';
use InstantBase\Client;
use InstantBase\Configuration;
class InstantBaseWordPress
{
private $client;
public function __construct()
{
$apiKey = get_option('instantbase_api_key');
if ($apiKey) {
$config = Configuration::create()
->withApiKey($apiKey)
->withEnvironment(wp_get_environment_type())
->withDebug(defined('WP_DEBUG') && WP_DEBUG);
$this->client = new Client($config);
}
add_action('init', [$this, 'init']);
add_action('wp_footer', [$this, 'trackPageView']);
add_action('user_register', [$this, 'trackUserRegister']);
add_action('woocommerce_thankyou', [$this, 'trackWooCommerceOrder']);
}
public function init()
{
// Инициализация сессии для anonymous_id
if (!session_id()) {
session_start();
}
}
public function trackPageView()
{
if (!$this->client) {
return;
}
$userId = get_current_user_id();
$this->client->track('page_view', [
'user_id' => $userId ? (string) $userId : null,
'anonymous_id' => session_id(),
'page' => get_the_title(),
'url' => get_permalink(),
'post_type' => get_post_type()
]);
}
public function trackUserRegister($userId)
{
if (!$this->client) {
return;
}
$user = get_userdata($userId);
$this->client->identify((string) $userId, [
'email' => $user->user_email,
'name' => $user->display_name,
'role' => implode(', ', $user->roles)
]);
$this->client->track('user_register', [
'user_id' => (string) $userId,
'method' => 'wordpress'
], [
'is_activation' => true
]);
}
public function trackWooCommerceOrder($orderId)
{
if (!$this->client) {
return;
}
$order = wc_get_order($orderId);
$userId = $order->get_user_id();
$items = [];
foreach ($order->get_items() as $item) {
$product = $item->get_product();
$items[] = [
'id' => $product->get_id(),
'name' => $product->get_name(),
'price' => (float) $product->get_price(),
'quantity' => $item->get_quantity(),
'category' => $this->getProductCategory($product->get_id())
];
}
$this->client->track('purchase', [
'user_id' => $userId ? (string) $userId : null,
'anonymous_id' => session_id(),
'order_id' => $orderId,
'amount' => (float) $order->get_total(),
'items' => $items
], [
'is_order' => true
]);
}
private function getProductCategory($productId)
{
$terms = wp_get_post_terms($productId, 'product_cat');
return !empty($terms) ? $terms[0]->name : '';
}
}
new InstantBaseWordPress();
Интеграция с Yii2
<?php
// config/web.php
return [
'components' => [
'instantbase' => [
'class' => 'app\components\InstantBaseComponent',
'apiKey' => env('INSTANTBASE_KEY'),
'environment' => YII_ENV,
'debug' => YII_DEBUG
],
],
];
<?php
// app/components/InstantBaseComponent.php
namespace app\components;
use yii\base\Component;
use InstantBase\Client;
use InstantBase\Configuration;
class InstantBaseComponent extends Component
{
public $apiKey;
public $environment = 'production';
public $debug = false;
private $_client;
public function init()
{
parent::init();
$config = Configuration::create()
->withApiKey($this->apiKey)
->withEnvironment($this->environment)
->withDebug($this->debug);
$this->_client = new Client($config);
}
public function getClient()
{
return $this->_client;
}
}
<?php
// app/controllers/SiteController.php
namespace app\controllers;
use Yii;
use yii\web\Controller;
class SiteController extends Controller
{
public function actionProduct($id)
{
$product = Product::findOne($id);
// Отслеживаем просмотр товара
Yii::$app->instantbase->getClient()->track('product_view', [
'user_id' => Yii::$app->user->id ? (string) Yii::$app->user->id : null,
'anonymous_id' => Yii::$app->session->getId(),
'product_id' => $product->id,
'product_name' => $product->name,
'price' => (float) $product->price
], [
'funnel_sales_step' => 1
]);
return $this->render('product', ['product' => $product]);
}
}
Работа с очередями
Для высоконагруженных проектов рекомендуется использовать очередь:
<?php
use InstantBase\Queue\RedisQueue;
use InstantBase\Client;
use InstantBase\Configuration;
// Настройка очереди
$queue = new RedisQueue([
'host' => 'localhost',
'port' => 6379,
'queue_name' => 'instantbase_events'
]);
// Конфигурация с очередью
$config = Configuration::create()
->withApiKey($_ENV['INSTANTBASE_KEY'])
->withQueueEnabled(true)
->withQueue($queue);
$client = new Client($config);
// События будут помещаться в очередь
$client->track('purchase', $properties);
// Отдельный процесс для обработки очереди
// bin/console instantbase:queue:process
public function processQueue()
{
$queue = new RedisQueue();
while ($event = $queue->pop()) {
try {
$this->httpClient->post($event);
} catch (\Exception $e) {
$queue->pushDeadLetter($event);
}
}
}
Обработка ошибок
<?php
use InstantBase\Exception\RateLimitException;
use InstantBase\Exception\AuthException;
use InstantBase\Exception\ValidationException;
try {
$client->track('purchase', [
'user_id' => 'user_123',
'amount' => 100
]);
} catch (RateLimitException $e) {
// Превышен лимит запросов
sleep($e->getRetryAfter());
// Повторяем
} catch (AuthException $e) {
// Проблема с API ключом
Log::error('Invalid API key');
} catch (ValidationException $e) {
// Ошибка валидации
Log::error('Invalid event data: ' . $e->getMessage());
} catch (\Exception $e) {
// Другие ошибки
Log::error('Failed to track event: ' . $e->getMessage());
}
// Глобальный обработчик ошибок
$client->onError(function ($event, $error) {
Log::error("Failed to track event $event: $error");
});
Сравнение с прямыми HTTP-запросами
| Характеристика | Прямые HTTP-запросы | PHP SDK |
|---|---|---|
| Простота использования | ❌ Нужно писать curl | ✅ Простой API |
| Пакетная отправка | ❌ Нет | ✅ Автоматически |
| Повторные попытки | ❌ Нет | ✅ Автоматически |
| Валидация данных | ❌ Нет | ✅ Автоматическая |
| Интеграция с фреймворками | ❌ Нет | ✅ Готовая |
Рекомендации
- Используйте очередь в продакшне — чтобы не замедлять ответ пользователю
- Настраивайте batch_size под нагрузку — 20-50 событий обычно оптимально
- Всегда обрабатывайте ошибки — чтобы не терять события
- Для Laravel используйте фасад — это удобно и читаемо
- Храните API ключи в .env — никогда не коммитьте их в репозиторий
- В WordPress используйте хуки — для автоматического отслеживания
⚠️ ВАЖНО: Production API-ключи должны храниться в безопасном месте. Используйте переменные окружения или секретные менеджеры. Для WordPress используйте плагины для защиты конфигурации.
Что дальше?
Нужна помощь с PHP SDK?
Напишите нам, и мы поможем настроить интеграцию