Padrões PSR
Nesta aula, você aprenderá sobre os Padrões PSR do PHP-FIG, começando pelo conceito e importância, passando pelos padrões de estilo de codificação PSR-1 e PSR-12, o autoload PSR-4, e uma visão geral dos padrões HTTP PSR-7 e PSR-15. Ao final, você terá exercícios práticos para consolidar o conhecimento.
Os Padrões PSR (PHP Standards Recommendations) são um conjunto de especificações criadas pelo PHP-FIG (PHP Framework Interop Group), um grupo colaborativo formado por representantes de diversos projetos PHP populares, como Composer, Laravel, Symfony, Zend Framework, entre outros. O objetivo principal é promover a interoperabilidade entre componentes e bibliotecas PHP, estabelecendo convenções comuns que facilitam a colaboração e a reutilização de código.
Nesta aula, vamos explorar os principais padrões PSR que você precisa conhecer como desenvolvedor PHP moderno: os padrões de estilo de codificação (PSR-1 e PSR-12), o padrão de autoload (PSR-4) e os padrões relacionados a HTTP (PSR-7 e PSR-15). Esses padrões são amplamente adotados no ecossistema PHP e compreendê-los é essencial para escrever código profissional, integrar bibliotecas e contribuir com projetos de código aberto.
O que são
Os Padrões PSR são recomendações (não obrigações) que definem boas práticas para o desenvolvimento em PHP. Eles surgiram da necessidade de unificar comportamentos que eram implementados de maneiras diferentes em cada framework ou biblioteca. Por exemplo, o autoload de classes era feito de formas distintas, o que dificultava a integração entre componentes de diferentes origens.
O PHP-FIG publica esses padrões após um processo de discussão e votação entre seus membros. Cada PSR é identificado por um número e pode ser classificado como:
- Aceito (Accepted): é um padrão oficial aprovado.
- Draft: está em discussão.
- Deprecated: foi substituído ou não é mais recomendado.
Os padrões mais utilizados no dia a dia são: PSR-1 (Basic Coding Standard), PSR-12 (Extended Coding Style), PSR-4 (Autoloading Standard) e PSR-7 (HTTP Message Interface), entre outros. Eles ajudam a garantir que o código seja legível, consistente e interoperável.
PSR-1/PSR-12 (estilo)
O PSR-1 define um conjunto mínimo de regras para a estruturação do código PHP. Ele cobre aspectos como: uso de tags PHP (somente <?php e <?=), codificação em UTF-8 sem BOM, definição de classes, propriedades e métodos, além de convenções de nomenclatura. Por exemplo, classes devem ser nomeadas em StudlyCaps (ex.: MinhaClasse), métodos em camelCase (ex.: meuMetodo), e constantes em MAIÚSCULAS_COM_UNDERSCORE (ex.: MINHA_CONSTANTE).
Já o PSR-12 é uma extensão do PSR-1 e define um estilo de codificação mais detalhado e moderno, baseado no PSR-2, mas atualizado para PHP 7.1+. Ele especifica regras de indentação (4 espaços), chaves em nova linha para classes e métodos, espaçamento em torno de operadores, e a obrigatoriedade de declaração de tipos estritos (declare(strict_types=1);) em arquivos. O PSR-12 também recomenda o uso de use para importar classes e a organização de declarações use em ordem alfabética.
Exemplo de código seguindo PSR-12:
<?php
declare(strict_types=1);
namespace App\Controllers;
use App\Models\User;
use RuntimeException;
class UserController
{
public function show(int $id): User
{
$user = User::find($id);
if ($user === null) {
throw new RuntimeException('Usuário não encontrado.');
}
return $user;
}
}
Perceba a indentação consistente, espaçamento adequado, uso de tipos e a organização das declarações use. Essas regras facilitam a leitura e a colaboração em equipe.
PSR-4 (autoload)
O PSR-4 define como as classes devem ser estruturadas em diretórios e como o autoloader deve encontrá-las. Ele é uma evolução do PSR-0, que era mais rígido. O PSR-4 permite mapear um namespace (prefixo) para um diretório base, e a partir daí, cada classe é carregada com base no seu nome totalmente qualificado.
Por exemplo, se você tem o namespace App\ mapeado para o diretório src/, então a classe App\Models\User será encontrada em src/Models/User.php. Isso simplifica a organização do código e elimina a necessidade de incluir manualmente cada arquivo.
O autoloader mais comum é o do Composer. No arquivo composer.json, você define o mapeamento:
{
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}
Após rodar composer dump-autoload, o Composer gera um autoloader que segue o PSR-4. No seu código, você pode simplesmente usar require 'vendor/autoload.php'; e instanciar classes sem se preocupar com includes.
Exemplo de uso:
<?php
require 'vendor/autoload.php';
use App\Models\User;
$user = new User();
O PSR-4 é um dos padrões mais importantes para o ecossistema PHP, pois permite que bibliotecas sejam instaladas via Composer e funcionem perfeitamente em qualquer projeto que siga o mesmo padrão.
PSR-7/PSR-15 (HTTP, visão geral)
O PSR-7 define interfaces para mensagens HTTP, como requisições (Request) e respostas (Response). Ele padroniza como essas mensagens devem ser representadas em PHP, permitindo que diferentes bibliotecas e frameworks trabalhem juntos. Por exemplo, um middleware pode receber uma Request e retornar uma Response, independentemente da implementação específica.
As principais interfaces do PSR-7 são: Psr\Http\Message\ServerRequestInterface, Psr\Http\Message\ResponseInterface, Psr\Http\Message\StreamInterface, entre outras. Elas definem métodos como getMethod(), getUri(), getBody(), etc.
Já o PSR-15 define interfaces para middlewares e request handlers. Um middleware é um componente que processa uma requisição e pode modificar a resposta ou delegar o processamento ao próximo middleware. O PSR-15 padroniza essa cadeia de responsabilidade, tornando os middlewares intercambiáveis entre diferentes frameworks.
Exemplo de um middleware simples:
<?php
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
class AuthMiddleware implements MiddlewareInterface
{
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
// Verifica se o usuário está autenticado
if (!isset($_SESSION['user'])) {
// Redireciona para login (criando uma resposta)
$response = new \GuzzleHttp\Psr7\Response(302, ['Location' => '/login']);
return $response;
}
// Passa a requisição para o próximo manipulador
return $handler->handle($request);
}
}
Esses padrões são fundamentais para o desenvolvimento de aplicações web modernas, pois permitem a criação de componentes reutilizáveis e independentes do framework.
Boas práticas e observações finais
Ao adotar os padrões PSR, você garante que seu código seja mais consistente, legível e interoperável. É importante que sua equipe escolha um conjunto de padrões e os siga rigorosamente. Utilize ferramentas como PHP_CodeSniffer ou PHP-CS-Fixer para automatizar a verificação e correção do estilo de código.
Lembre-se de que os padrões PSR são recomendações, mas a comunidade PHP as adota amplamente. Portanto, seguir esses padrões é uma forma de se alinhar às melhores práticas do ecossistema.
Referências
- PHP-FIG - PSRs
- PSR-1: Basic Coding Standard
- PSR-12: Extended Coding Style
- PSR-4: Autoloading Standard
- PSR-7: HTTP Message Interface
- PSR-15: HTTP Handlers
- Composer - Autoloading
Exercícios
- Explique a importância dos padrões PSR para a interoperabilidade no ecossistema PHP. Dê um exemplo de como a falta de padrões poderia afetar a integração entre bibliotecas.
- Escreva um trecho de código PHP que siga o PSR-12, declarando uma classe chamada
Produtono namespaceApp\Models, com uma propriedade privada$nomee um método públicogetNome()que retorna o nome. Inclua a declaração de tipos estritos. - Considere o seguinte mapeamento PSR-4:
"App\\": "src/". Onde a classeApp\Services\PedidoServicedeve estar localizada? Explique o caminho completo. - Descreva as principais diferenças entre PSR-7 e PSR-15. Como eles se complementam?
- Crie um middleware PSR-15 que adiciona um header
X-Content-Type-Options: nosniffà resposta. Use as interfaces do PSR-7 e PSR-15.
<?php
declare(strict_types=1);
namespace App\Models;
class Produto
{
private string $nome;
public function __construct(string $nome)
{
$this->nome = $nome;
}
public function getNome(): string
{
return $this->nome;
}
}
src/Services/PedidoService.php. O PSR-4 mapeia o namespace App\ para o diretório src/, então o restante do namespace (Services\) corresponde ao subdiretório Services/ e o nome da classe (PedidoService) corresponde ao arquivo PedidoService.php.<?php
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
class SecurityHeadersMiddleware implements MiddlewareInterface
{
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$response = $handler->handle($request);
return $response->withHeader('X-Content-Type-Options', 'nosniff');
}
}