# PHP-FIG Standards: PSRs and Coding Style — PHP

Source: https://www.skillbyai.com/en/php/x-psr

> Use the key PSR interfaces and coding style standards.

## Shared interfaces across the ecosystem

The **PHP Framework Interop Group (PHP-FIG)** publishes **PSRs** (PHP Standards Recommendations) so libraries and frameworks can work together. Key ones: **PSR-4** (autoloading), **PSR-3** (`LoggerInterface`), **PSR-7** (HTTP message interfaces: immutable request and response objects), **PSR-15** (HTTP server request handlers and **middleware**), **PSR-17** (HTTP factories), **PSR-18** (HTTP client), **PSR-11** (container interface), **PSR-6** and **PSR-16** (caching) and **PSR-14** (event dispatcher). Coding style is defined by the **PER Coding Style** (the evolving successor to PSR-12): four-space indentation, braces placement, `declare(strict_types=1)` placement, and so on. Enforce it automatically with **PHP-CS-Fixer** or **PHP_CodeSniffer**, so reviews focus on design rather than spaces. **Middleware** following PSR-15 wraps a handler: each middleware can inspect or change the request, call the next handler, and modify the response, which is how authentication, logging, CORS and rate limiting are layered in frameworks such as Slim and Mezzio.

## Middleware layers

A request passes inward through middleware to the handler, and the response travels back out.

![Concentric rings around a central core, with an arrow passing inward through each ring and another returning outward.](assets/figures/php/section-7-map.svg) — Figure 7.1 — PSR-15 middleware wrapping a request handler.

## A PSR-15 middleware

Adds a request ID and measures timing for every request.

```php
<?php
declare(strict_types=1);

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Psr\Log\LoggerInterface;

final class RequestTiming implements MiddlewareInterface
{
    public function __construct(private readonly LoggerInterface $logger) {}

    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        $id = $request->getHeaderLine('X-Request-Id') ?: bin2hex(random_bytes(8));
        $start = hrtime(true);

        $response = $handler->handle($request->withAttribute('request_id', $id));   // PSR-7 objects are immutable

        $ms = (hrtime(true) - $start) / 1e6;
        $this->logger->info('request', ['id' => $id, 'path' => $request->getUri()->getPath(), 'ms' => round($ms, 1)]);
        return $response->withHeader('X-Request-Id', $id);
    }
}

// vendor/bin/php-cs-fixer fix src --rules=@PER-CS   (automatic code style)
```

## PSR-7 objects are immutable

`$request->withAttribute(...)` returns a new request; it does not change the original. Forgetting to use the returned object is a common bug when writing middleware.

**Quiz:** What does PSR-15 standardise?

- [x] HTTP server request handlers and middleware
- [ ] Autoloading
- [ ] Logging
- [ ] Coding style

*Answer:* HTTP server request handlers and middleware. PSR-15 defines MiddlewareInterface and RequestHandlerInterface.
