PHP compatibility and project lifecycle
Unknown. The supplied source lists documentation versions 3.16, 3.14, 3.13, 3.12, 2.14 and 1.0 but gives no PHP version requirements. Support for PHP 8.4 or 8.5 is not confirmed. Verify against the official Installation page.
Official sources checked 2026-10-22. Browser lessons on this site run PHP 8.5.
Sources and evidence limits
The only evidence supplied is the table of contents of the official Spiral documentation, so the guide describes what that page lists. Anything the page does not state is marked unknown.
What Spiral is
Spiral is an application framework for PHP. It is not a PHP runtime, interpreter or CMS. PHP core is the language engine, and Spiral is code that runs on top of it. This differs from a CMS product such as Drupal, which ships content management features as an end-user product. Spiral belongs on the framework side of that line: it supplies building blocks for applications, and the application itself is what you write.
The documentation menu groups its topics as follows:
- Overview: About Framework, Design Approach, Application Lifecycle, Contributing, Versioning and License.
- Getting started: Installation, Long running, Directory Structure, Configuration, First HTTP controller, First CLI command, First background job, and Deployment.
- Framework internals: Kernel and Environment, Bootloaders, Config Objects, Dispatchers, Interceptors and Finalizers.
- Container and DI: auto wiring, attributes, IOC scopes and injectors.
- Feature areas: HTTP, request validation, data grid, security, testing, console, WebSockets, queues and jobs, Temporal, GRPC, views and templating.
- A Keeper section whose purpose the page does not describe beyond its subtopic titles.
The focus here is the framework's integration with RoadRunner, which the site lists as a related product next to Cycle ORM.
Architecture and execution model
The menu names a Kernel, Bootloaders, Dispatchers, Interceptors and Finalizers. From those titles, the framework appears to start a kernel, boot components, hand work to a dispatcher for a given entry type such as HTTP or console, and run cleanup steps afterward. The supplied page gives no details on how these parts behave, so check the Application Lifecycle and Dispatchers pages before relying on this reading.
The menu also has a Long running page and a RoadRunner integration page under Queue and Jobs. This points to a persistent-worker model, in which one PHP process handles many units of work. That is different from the classic request lifetime, where the web server starts PHP state for each request and discards it at the end.
RoadRunner is a separate project, and so are async libraries and framework adapters in general. None of them is a standalone PHP runtime. Swoole and Open Swoole are also distinct projects, and this source says nothing about either, so do not assume Spiral works with them.
State leakage and cleanup
In a persistent worker, anything stored in static properties, singletons or long-lived services survives past one request. If that data belongs to a user or a request, the next request may see it. This is state leakage, and it can expose one user's data to another or cause memory growth.
The usual defenses are to avoid mutable static state, keep request data in request-scoped objects, and reset shared services when the unit of work finishes. The menu lists IOC Scopes, Finalizers and Static Memory, which are likely places to look for the framework's own answers. The page does not describe them, so read those pages directly.
The example below does not use Spiral. It is a framework-neutral simulation that shows a leaking static collector next to a collector that is reset after each simulated request.
Practical use cases
The documented feature list suggests these uses:
- HTTP applications with routing, middleware, cookies, CSRF protection and OpenAPI documentation.
- Console tools and scheduled tasks.
- Background jobs with RoadRunner integration.
- WebSocket and broadcasting features, with a Centrifugo API page.
- GRPC services and Temporal workflows.
Which of these is the best fit for a particular project is a decision for you. The supplied source does not give recommendations.
Installation approach
The docs have an Installation page and a Long running page. The supplied packet does not include their contents, so exact install commands, required PHP versions and required extensions are unknown here. Follow the Installation page for the version you choose. The framework section of the Docs lists versions 3.16, 3.14, 3.13, 3.12, 2.14 and 1.0 in its selector. Which of them is current or supported is unknown from this evidence, so lifecycle is recorded as unknown.
This learning track uses PHP 8.4, with PHP 8.5 planned. Whether Spiral supports either version is unknown. Confirm it in the official docs before building anything on it.
Strengths
Based only on the table of contents:
- A broad documented surface that covers HTTP, console, queues, WebSockets, GRPC, Temporal, testing and validation.
- Dedicated pages for long-running operation and RoadRunner.
- A container with auto wiring, attributes and scopes.
- Validation pages for Spiral, Symfony and Laravel validators.
- Several documented versions.
No claims about speed, maturity or popularity are made here.
Limitations
- The evidence is a table of contents only, so behavior, APIs and requirements are unverified.
- License, PHP compatibility and support status are unknown from this source. The docs have a License page that you should read.
- Persistent workers need disciplined state handling.
- Runtime examples need Composer and network access, and they are not browser exercises.
Deployment
The docs include a Deployment page, but its contents were not supplied. Keep development servers bound to 127.0.0.1 and never expose internal worker or FastCGI interfaces publicly. Treat production deployment guidance as unknown until you have read the official page.
The example
The included example uses plain PHP 8.4 and no dependencies. It simulates three requests in one process. The static collector accumulates values across requests, which is the leak. The scoped collector is reset after each request. Run it from the example directory with the commands listed. This example illustrates a concept only and does not show how Spiral implements cleanup.
Links
The official Spiral documentation is the only source used for this guide. Verify every detail there before relying on it.
Practical examples
These examples have not been run in a live environment yet. Commands and versions follow the official documentation linked on this page; check them before relying on them, and report a problem if one does not work.
Persistent worker state leakage simulation (framework-neutral)
A dependency-free PHP 8.4 CLI script that simulates three requests handled by one long-lived process. It contrasts a static collector that leaks data between requests with an instance collector reset after each request. It does not use Spiral APIs and only illustrates the cleanup concept relevant to persistent workers.
composer.json
{
"name": "learnphponline/worker-state-demo",
"description": "Framework-neutral demo of state leakage in persistent workers",
"type": "project",
"require": {
"php": "^8.4"
}
}
src/LeakyCollector.php
declare(strict_types=1);
final class LeakyCollector
{
/** @var list<string> */
private static array $items = [];
public static function add(string $item): void
{
self::$items[] = $item;
}
/** @return list<string> */
public static function all(): array
{
return self::$items;
}
}
src/ScopedCollector.php
declare(strict_types=1);
final class ScopedCollector
{
/** @var list<string> */
private array $items = [];
public function add(string $item): void
{
$this->items[] = $item;
}
/** @return list<string> */
public function all(): array
{
return $this->items;
}
public function reset(): void
{
$this->items = [];
}
}
bin/demo.php
declare(strict_types=1);
require_once __DIR__ . '/../src/LeakyCollector.php';
require_once __DIR__ . '/../src/ScopedCollector.php';
$users = ['alice', 'bob', 'carol'];
$scoped = new ScopedCollector();
foreach ($users as $number => $user) {
LeakyCollector::add($user);
$scoped->add($user);
echo sprintf(
"request %d leaky=[%s] scoped=[%s]\n",
$number + 1,
implode(',', LeakyCollector::all()),
implode(',', $scoped->all())
);
// Cleanup step at the end of each simulated request.
$scoped->reset();
}
Install and run
php --version
composer validate
php bin/demo.phpExpected behavior
Requires PHP 8.4 and Composer for the optional validate step. The script prints three lines. The leaky list grows from alice to alice,bob to alice,bob,carol, while the scoped list shows only the current user on each line. This output is an expectation, not a tested result.
This is a conceptual simulation, not Spiral code, and it does not show how Spiral manages scopes or finalizers. It needs a local PHP 8.4 CLI and runs outside the browser.