spiral/framework
Spiral Framework is a high-performance, long-running full-stack PHP framework built for RoadRunner. PSR-compliant components, resident memory kernel, and native support for queues, GRPC, WebSockets, and background workers.
Installation:
composer create-project spiral/app my-app
Or add to an existing Laravel project via:
composer require spiral/framework
First Use Case:
index.php with Spiral’s public/index.php (if using standalone).spiral/sapi-bridge to proxy requests:
use Spiral\Sapi\Bridge\Laravel\SapiBridge;
$bridge = new SapiBridge();
$bridge->run();
Key Entry Points:
config/app.php (Spiral’s equivalent of Laravel’s AppServiceProvider).src/Http/Controller/Route.php (or via annotations).php spiral [command] (e.g., spiral scaffolder:controller).First Command: Generate a controller:
php spiral scaffolder:controller User --action=list --action=show
Dependency Injection (DI):
@Inject for constructor injection (e.g., @Inject private Database $db).#[Inject]
private Queue $queue;
$this->container->runInScope(ContainerScope::QUEUE, fn() => $job->handle());
Routing:
#[Route("users", methods: ["GET"])]
public function listUsers(): Response
{
return new Response("Users list");
}
$router->group("/api", function (Router $router) {
$router->get("/users", [UserController::class, "list"]);
});
Queue Jobs:
@Job:
#[Job]
class SendEmailJob implements JobInterface
{
public function __construct(private string $email) {}
public function run(): void
{
// Logic here
}
}
QueueInterface:
$this->queue->dispatch(new SendEmailJob("user@example.com"));
Bootloaders:
Bootloader for custom logic:
class AppBootloader extends Bootloader
{
public function init(): void
{
$this->provideSingleton(MyService::class);
}
}
config/app.php:
'bootloaders' => [
AppBootloader::class,
],
Scaffolding:
php spiral scaffolder:crud User --namespace=App\\Http\\Controller
Spiral\Scaffolder\Template\TemplateInterface.HTTP Middleware:
#[Middleware(AuthMiddleware::class)]
class UserController extends Controller
{
// ...
}
Service Binding: Bind Laravel services to Spiral’s container:
$this->container->bindSingleton(Auth::class, fn() => app('auth'));
Event Dispatcher:
Proxy Laravel events to Spiral’s EventDispatcher:
event(new UserRegistered($user));
// Spiral will dispatch via its event system
Database:
Use spiral/cycle-bridge for Cycle ORM integration:
$this->container->bindSingleton(DB::class, fn() => Cycle\ORM\ORM::create());
Memory Leaks:
Spiral\Core\Memory\MemoryManager to monitor leaks:
$this->memoryManager->collectGarbage();
RoadRunner Integration:
roadrunner.json is configured for PHP workers:
{
"workers": {
"php": {
"pool": "default",
"memory_limit": "256M"
}
}
}
rr serve) will cause silent failures.Queue Retries:
$this->queue->defineInterceptor(
RetryPolicyInterceptor::class,
new RetryPolicy(3, 1000) // 3 retries, 1s delay
);
Annotations vs Attributes:
// ❌ Legacy (annotations)
/** @Inject */
private Database $db;
// ✅ Modern (attributes)
#[Inject]
private Database $db;
Singleton Scope:
// ❌ Risky
$this->container->bindSingleton(LoggerInterface::class, MonologLogger::class);
// ✅ Safer
$this->container->bindSingleton(MonologLogger::class);
Route Caching:
php spiral cache:clear
Tokenizer Issues:
php spiral tokenizer:validate
php spiral tokenizer:info
Container Scope:
$this->container->runInScope(ContainerScope::QUEUE, fn() => $job->handle());
RoadRunner Logs:
storage/logs/roadrunner.log for worker/queue issues.Performance:
Spiral\Debug\Debug for runtime metrics:
Debug::memoryUsage(); // Check memory spikes
Custom Bootloaders:
Spiral\Boot\Bootloader to add app-specific logic (e.g., database migrations).Interceptors:
$this->queue->defineInterceptor(MyInterceptor::class);
Template Engines:
TemplateEngineInterface.Auth Backends:
Spiral\Auth\AuthBackendInterface for custom providers (e.g., OAuth2).Event Listeners:
Spiral\Event\EventDispatcher for pub/sub:
$this->eventDispatcher->listen(UserRegistered::class, [UserNotifier::class, "notify"]);
Environment Variables:
SPIRAL_ (e.g., SPIRAL_QUEUE_CONNECTION=database).Debug Mode:
.env:
APP_DEBUG=true
RoadRunner Settings:
roadrunner.json (not .env):
{
"server": "http://0.0.0.0:8080",
"static": "./public"
}
Cache Directories:
storage/cache. Override in config/cache.php.Scaffolding Shortcuts:
php spiral scaffolder:module Admin --namespace=App\\Modules\\Admin
Queue Supervision:
Spiral\Queue\Supervisor to monitor failed jobs:
$this->queue->supervisor()->retryFailed();
GRPC Integration:
src/Grpc/Service/*.proto and use spiral/roadrunner-bridge.Temporal Workflows:
spiral/temporal-bridge:
$workflow = $this->temporal->startWorkflow(
new OrderWorkflow($orderId),
new WorkflowOptions()
);
Testing:
Spiral\Testing\TestCase for isolated tests:
use Spiral\Testing\TestCase;
class UserTest extends TestCase
{
public function testListUsers()
{
$this->get("/users")->assertOk();
}
}
How can I help you explore Laravel packages today?