Symfony Integration
The bext/symfony package provides a Symfony Flex bundle that auto-registers bext's cache, real-time, and task services for dependency injection.
Installation
composer require bext/symfony
Requirements: PHP >= 8.2, Symfony 6.4 or 7.0
The bundle is auto-registered via Symfony Flex — no manual configuration needed.
Autowiring
Inject bext services into any controller or service:
use Bext\Symfony\BextCache;
use Bext\Symfony\BextRealtime;
use Bext\Symfony\BextTasks;
class ProductController extends AbstractController
{
public function __construct(
private BextCache $cache,
private BextRealtime $realtime,
private BextTasks $tasks,
) {}
#[Route('/api/products/{id}', methods: ['PUT'])]
public function update(string $id, Request $request): JsonResponse
{
$product = $this->productRepo->update($id, $request->toArray());
$this->cache->invalidate("products");
$this->realtime->publish("products", [
"action" => "updated",
"id" => $id,
]);
return $this->json($product);
}
}
Container Aliases
Services are also available via container aliases:
$this->container->get('bext.cache');
$this->container->get('bext.realtime');
$this->container->get('bext.tasks');
Global Helpers
Same helper functions as the Laravel adapter:
bext_invalidate("products");
bext_publish("orders", ["id" => 123]);
bext_task("cleanup", "0 2 * * *", "cache::gc");
Cache API
class BextCache
{
public function invalidate(string $tag): bool;
public function invalidatePath(string $pattern): bool;
public function flush(): bool;
}
Real-Time API
class BextRealtime
{
public function publish(string $topic, mixed $data = null): bool;
}
Task Scheduling API
class BextTasks
{
public function register(string $name, string $cron, string $command): bool;
public function list(): array;
public function cancel(string $name): bool;
}
Worker Mode
Like the Laravel adapter, Symfony supports worker mode for high-performance request handling.
Setup
Create a worker.php:
<?php
require __DIR__ . '/vendor/autoload.php';
$kernel = new \App\Kernel(
$_SERVER['APP_ENV'] ?? 'prod',
(bool) ($_SERVER['APP_DEBUG'] ?? false)
);
\Bext\Symfony\Worker::run($kernel);
Configure in bext.config.toml:
[php]
enabled = true
document_root = "./public"
workers = 4
worker_script = "./worker.php"
max_requests = 10000
Performance
| Mode | Latency | Throughput |
|---|---|---|
| Classic | 1–5ms | ~1K req/s |
| Worker | 34us | ~15K req/s |
The worker keeps Symfony's DI container, route matcher, and event dispatcher loaded in memory. Only request-specific state is re-created per request.
React SSR Bridge
Render React components from Symfony controllers:
use function Bext\Symfony\react;
#[Route('/dashboard')]
public function dashboard(): Response
{
$html = react("Dashboard", [
"user" => $this->getUser(),
"metrics" => $this->metricsService->getSummary(),
]);
return new Response($html);
}
Uses the same FFI-accelerated rendering path as the Laravel adapter when running in worker mode.
Event Subscriber Integration
You can integrate bext services with Symfony's event system:
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class CacheInvalidationSubscriber implements EventSubscriberInterface
{
public function __construct(private BextCache $cache) {}
public static function getSubscribedEvents(): array
{
return [
ProductUpdatedEvent::class => 'onProductUpdated',
];
}
public function onProductUpdated(ProductUpdatedEvent $event): void
{
$this->cache->invalidate("products");
$this->cache->invalidatePath("/products/{$event->getProductId()}");
}
}