| Name | Modified | Size | Downloads / Week |
|---|---|---|---|
| Parent folder | |||
| README.md | 2026-10-27 | 4.2 kB | |
| v3.18.0 source code.tar.gz | 2026-10-27 | 440.0 kB | |
| v3.18.0 source code.zip | 2026-10-27 | 1.1 MB | |
| Totals: 3 Items | 1.5 MB | 0 | |
New features
1. QUERY HTTP verb
The router supports the QUERY method from RFC 10008: a safe, idempotent request that carries its query in the body. Routes without explicit verbs accept it too, and route:list shows it in its own color.
:::php
use Spiral\Router\Annotation\Route;
#[Route(route: '/products/search', methods: ['QUERY'])]
public function search(ServerRequestInterface $request): array
{
// the search criteria come in the request body
}
QUERY is not in CsrfFirewall::ALLOW_METHODS, so such requests still require a CSRF token.
by @gam6itko in https://github.com/spiral/framework/pull/1314
2. HTTP spans follow the stable OpenTelemetry semantic conventions
The server span written by spiral/http now uses the stable HTTP semantic conventions, so tracing backends (Jaeger, Tempo, Grafana, Datadog, Honeycomb, …) recognise it in their HTTP views and RED metrics.
- The span is named after the request method (
GET) instead of the full URL, which removes unbounded span-name cardinality. - Request headers (
http.headers) are no longer exported, soAuthorizationandCookievalues do not reach the tracing backend. - The status stays unset below 500 instead of
OK; a 5xx setsERRORanderror.type.
| Before | Now |
|---|---|
http.method |
http.request.method |
http.url |
url.scheme, url.path, url.query, server.address, server.port |
http.status_code |
http.response.status_code |
http.response_content_length |
http.response.body.size |
http.headers |
removed |
| — | client.address, user_agent.original, network.protocol.version |
The middleware spans of the deprecated Pipeline get the same status and response attribute changes.
by @roxblnfk in https://github.com/spiral/framework/pull/1312
3. MailerInterface can be overridden or decorated
MailerBootloader used to bind MailerInterface from its boot() method, which runs after every bootloader has registered its bindings, so an application binding of the mailer was always overwritten. The binding now lives in the singleton map next to an explicit MailQueue binding, and the usual last-registration-wins order applies:
:::php
final class AppMailerBootloader extends Bootloader
{
protected const SINGLETONS = [
MailerInterface::class => [self::class, 'mailer'],
];
private function mailer(MailQueue $queue, LoggerInterface $logger): MailerInterface
{
return new LoggingMailer($queue, $logger);
}
}
by @gam6itko in https://github.com/spiral/framework/pull/1302
Upgrade notes
- Telemetry: dashboards, alerts and queries that filter on the old attributes, the old span name or status
OKneed to switch to the new keys. There is no dual-emission mode; if you need a transition period, rename the attributes in your OpenTelemetry Collector (transformprocessor). - Mailer:
MailerBootloader::boot()no longer takesBinderInterface; a subclass overridingboot()must drop that parameter. An application binding ofMailerInterfacenow takes effect instead of being silently replaced byMailQueue. - SendIt: HTML comments are now stripped from the HTML part of emails built on
sendit:builder. Outlook conditional comments and the content of<style>,<script>,<textarea>and<title>are kept. - Development branch:
masteris renamed to3.xinspiral/frameworkand in every split package, and thedev-masterbranch aliases are gone. If you require a development version, replacedev-masterwith3.x-dev.
Other
- [spiral/sendit] Strip HTML comments from the rendered HTML part by @gam6itko in https://github.com/spiral/framework/pull/1315
- [spiral/http] Pass
EventDispatcherinto the HTTP core by @roxblnfk in https://github.com/spiral/framework/pull/1292 - Releases are now prepared by release-please from conventional-commit PR titles by @roxblnfk in https://github.com/spiral/framework/pull/1317
Full Changelog: https://github.com/spiral/framework/compare/3.17.2...3.18.0