PHP 8: Modern PHP Development · Composer, Autoloading and PSR Standards
PSR Standards You Should Know
PSR-3 logging, PSR-7/15/17/18 HTTP, PSR-11 containers, PSR-20 clocks and PER coding style.
The PHP Framework Interop Group (PHP-FIG) publishes standards that let libraries interoperate. Key ones: PSR-1/PSR-12 and PER Coding Style (formatting), PSR-3 (LoggerInterface), PSR-4 (autoloading), PSR-6/16 (caching), PSR-7 (HTTP messages), PSR-11 (containers), PSR-14 (event dispatcher), PSR-15 (HTTP middleware), PSR-17 (HTTP factories), PSR-18 (HTTP client) and PSR-20 (clock). Type-hint against these interfaces to stay framework-agnostic.
<?php
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 TimingMiddleware implements MiddlewareInterface // PSR-15
{
public function __construct(private LoggerInterface $logger) {} // PSR-3
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$start = hrtime(true);
$response = $handler->handle($request);
$this->logger->info('request', [
'path' => $request->getUri()->getPath(),
'status' => $response->getStatusCode(),
'ms' => (hrtime(true) - $start) / 1e6,
]);
return $response->withHeader('Server-Timing', 'app'); // PSR-7 is immutable
}
}
Common pitfalls
- Mutating PSR-7 messages —
with*()returns a new instance; ignoring the return value loses the change. - Coupling libraries to a specific framework's logger instead of PSR-3.
- Using the container as a service locator everywhere (PSR-11 is for composition roots).
Key points
- PSRs make libraries interoperable
- PSR-7 messages are immutable
- Type-hint PSR interfaces in reusable code
Further reading: PHP-FIG PSR index
Practice questions
Why does $response->withHeader('X', '1'); alone not add the header?
Answer
PSR-7 messages are immutable; withHeader() returns a new response. You must use the returned value: $response = $response->withHeader(...).
What problem does PSR-3 solve?
Answer
It defines a common LoggerInterface, so libraries can log without depending on a specific logging implementation; the application chooses Monolog or another PSR-3 logger.
Open in the app to mark lessons complete, take notes and track your progress.