Padrões PSR
Nesta aula, você aprenderá sobre os Padrões PSR do PHP-FIG, essenciais para interoperabilidade entre bibliotecas e frameworks. Abordaremos os padrões de estilo de código (PSR-1 e PSR-12), autoloading (PSR-4) e uma visão geral dos padrões HTTP (PSR-7 e PSR-15), com exemplos práticos e exercícios para fixação.
Os Padrões PSR (PHP Standards Recommendations) são um conjunto de especificações criadas pelo PHP-FIG (PHP Framework Interop Group) para padronizar a forma como bibliotecas e frameworks PHP se comunicam e resolvem problemas comuns. Eles garantem que componentes de diferentes autores possam trabalhar juntos sem conflitos, promovendo interoperabilidade e boas práticas no ecossistema PHP.
Nesta aula, vamos explorar os padrões mais relevantes: os de estilo de código (PSR-1 e PSR-12), o de autoloading (PSR-4) e uma visão geral dos padrões HTTP (PSR-7 e PSR-15). Compreender esses padrões é fundamental para qualquer desenvolvedor PHP moderno, pois eles são adotados pela maioria dos frameworks (Laravel, Symfony, etc.) e bibliotecas populares.
O que são
Os Padrões PSR são recomendações que visam resolver problemas comuns no desenvolvimento PHP, como convenções de nomenclatura, estrutura de arquivos, carregamento automático de classes e padronização de interfaces para requisições e respostas HTTP. Eles não são obrigatórios, mas seguí-los facilita a colaboração e a reutilização de código.
O PHP-FIG é um grupo de projetos que inclui mantenedores de frameworks e bibliotecas renomadas. Eles discutem e votam propostas que, se aprovadas, tornam-se recomendações oficiais. Cada PSR é identificada por um número e pode ser marcada como 'Aceita', 'Em revisão' ou 'Depreciada'.
Para ilustrar, imagine que você está criando uma biblioteca que precisa ser usada em diferentes frameworks. Se você seguir a PSR-4, qualquer framework que respeite esse padrão poderá carregar suas classes automaticamente, sem configuração extra. Isso é essencial para a interoperabilidade.
PSR-1/PSR-12 (estilo)
A PSR-1 define as regras básicas de codificação, como a obrigatoriedade de tags PHP (<?php), uso de UTF-8 sem BOM, e a nomenclatura de classes, métodos e constantes. Ela é complementada pela PSR-12, que é uma extensão mais detalhada, substituindo a antiga PSR-2. Juntas, elas formam o guia de estilo oficial para código PHP.
Algumas regras importantes da PSR-1 incluem: arquivos devem usar apenas <?php ou <?=; classes devem ser nomeadas em StudlyCaps; métodos em camelCase; constantes em UPPER_CASE com underscores. A PSR-12 adiciona regras sobre indentação (4 espaços), chaves, espaçamento, uso de declare(strict_types=1) e muito mais.
Exemplo de código seguindo PSR-12:
<?php
declare(strict_types=1);
namespace App\Models;
use App\Contracts\ModelInterface;
class User implements ModelInterface
{
private string $name;
public function __construct(string $name)
{
$this->name = $name;
}
public function getName(): string
{
return $this->name;
}
}
Perceba a indentação com 4 espaços, as chaves na mesma linha da declaração, os espaços após palavras-chave e a presença de declare(strict_types=1) no início do arquivo.
PSR-4 (autoload)
A PSR-4 especifica como as classes devem ser mapeadas para seus arquivos, permitindo o autoloading sem a necessidade de incluir manualmente cada arquivo. Ela define que a estrutura de namespaces deve corresponder à estrutura de diretórios, e que o prefixo do namespace é mapeado para um diretório base.
Por exemplo, se você tem o namespace App\ apontando para o diretório src/, a classe App\Models\User estará em src/Models/User.php. Isso é configurado no composer.json através da chave autoload.
Exemplo de configuração no composer.json:
{
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}
Após rodar composer dump-autoload, o Composer gera o autoloader que carrega as classes automaticamente quando são referenciadas. Isso elimina a necessidade de require manual e melhora a organização do projeto.
Exemplo de uso:
<?php
require 'vendor/autoload.php';
$user = new \App\Models\User('João');
echo $user->getName();
Sem a PSR-4, você precisaria fazer require_once 'src/Models/User.php' antes de usar a classe. Com ela, o autoloader resolve a classe automaticamente.
PSR-7/PSR-15 (HTTP, visão geral)
A PSR-7 define interfaces padronizadas para mensagens HTTP, incluindo requisições (RequestInterface), respostas (ResponseInterface) e streams (StreamInterface). Ela permite que bibliotecas e frameworks manipulem HTTP de forma consistente, independentemente da implementação concreta.
A PSR-15 define interfaces para middleware, que são componentes que processam requisições e respostas em um pipeline. O middleware pode modificar a requisição, a resposta ou interromper o fluxo. Isso é fundamental para frameworks modernos como Laravel e Slim.
Exemplo de uso de PSR-7 com uma implementação como o Nyholm Psr7:
<?php
use Nyholm\Psr7\Factory\Psr17Factory;
use Nyholm\Psr7\ServerRequest;
$factory = new Psr17Factory();
$request = $factory->createServerRequest('GET', 'https://api.exemplo.com/users');
$response = $factory->createResponse(200);
Exemplo de um middleware PSR-15:
<?php
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Psr\Http\Server\MiddlewareInterface;
class AuthMiddleware implements MiddlewareInterface
{
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
if (!isset($_SESSION['user'])) {
return new \Nyholm\Psr7\Response(401);
}
return $handler->handle($request);
}
}
Esses padrões são a base para construir aplicações PHP modernas, desacopladas e testáveis.
Boas práticas e observações finais
Ao adotar os padrões PSR, você garante que seu código seja legível, interoperável e fácil de manter. Algumas boas práticas incluem: usar sempre a PSR-12 (ou PSR-1) como guia de estilo, configurar o autoload via Composer com PSR-4, e utilizar as interfaces PSR-7/PSR-15 em bibliotecas que manipulam HTTP.
Lembre-se de que os padrões evoluem, então consulte sempre a documentação oficial do PHP-FIG para estar atualizado. Além disso, ferramentas como PHP_CodeSniffer podem ajudar a verificar a conformidade com PSR-12 automaticamente.
Referências
- PHP-FIG - PSRs
- PSR-1: Basic Coding Standard
- PSR-12: Extended Coding Style Guide
- PSR-4: Autoloader
- PSR-7: HTTP message interfaces
- PSR-15: HTTP Server Request Handlers
Exercícios
- Explique a diferença entre PSR-1 e PSR-12. Dê um exemplo de regra que está na PSR-12 mas não na PSR-1.✓ Resposta: A PSR-1 define as regras básicas, como nomenclatura de classes, métodos e constantes, e o uso de tags PHP. A PSR-12 é uma extensão mais detalhada, cobrindo indentação, espaçamento, uso de
declare(strict_types=1), entre outros. Um exemplo de regra exclusiva da PSR-12 é a obrigatoriedade de usar 4 espaços para indentação, enquanto a PSR-1 não especifica isso. - Como você configuraria o Composer para usar a PSR-4 para a namespace
MinhaApp\apontando para o diretóriolib/?✓ Resposta: Nocomposer.json, adicione:
Depois execute{ "autoload": { "psr-4": { "MinhaApp\\": "lib/" } } }composer dump-autoload. - Qual é a principal vantagem de usar a PSR-4 em relação ao autoload com
requiremanual?✓ Resposta: A PSR-4 permite o carregamento automático das classes, eliminando a necessidade de incluir manualmente cada arquivo comrequire. Isso facilita a manutenção, evita erros de caminho e permite que bibliotecas sejam usadas sem configuração adicional. - Cite dois padrões PSR relacionados a HTTP e explique brevemente o que cada um define.✓ Resposta: PSR-7 define interfaces para mensagens HTTP (requisições, respostas, streams), e PSR-15 define interfaces para middleware e request handlers. Juntas, elas permitem que aplicações processem HTTP de forma padronizada e componível.
- Escreva um exemplo de classe que implementa a interface
MiddlewareInterfaceda PSR-15, que adiciona um cabeçalho à resposta.✓ Resposta:<?php use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Server\RequestHandlerInterface; use Psr\Http\Server\MiddlewareInterface; class HeaderMiddleware implements MiddlewareInterface { public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface { $response = $handler->handle($request); return $response->withHeader('X-Custom', 'Valor'); } }