<h2>O que são PSR Standards e por que importam</h2>
<p>PSR (PHP Standards Recommendations) são diretrizes de codificação criadas pelo PHP-FIG (Framework Interop Group) para padronizar como escreveremos código PHP. Pense nelas como as "regras de trânsito" da comunidade PHP: sem elas, cada desenvolvedor dirigiria do jeito que quisesse, causando caos. Com elas, qualquer pessoa que abra seu código consegue ler e entender rapidamente. As PSRs que trabalharemos — PSR-1, PSR-2, PSR-4 e PSR-12 — cobrem desde convenções básicas de nomenclatura até autoloading automático de classes.</p>
<p>Por anos trabalhei em projetos onde cada time seguia seus próprios padrões. O resultado? Código inconsistente, dificuldade de manutenção e onboarding lento de novos desenvolvedores. Quando adotamos PSRs, a produtividade aumentou significativamente. Você verá por quê.</p>
<h2>PSR-1 e PSR-2: Fundações Sólidas</h2>
<h3>PSR-1: Basic Coding Standard</h3>
<p>PSR-1 define as convenções básicas inegociáveis. Aqui estão os pontos-chave: arquivos PHP devem usar apenas a tag <code><?php</code> (nunca a abreviada <code><?</code>), deve-se usar UTF-8 sem BOM, e nomes de classes devem estar em PascalCase enquanto métodos em camelCase.</p>
<pre><code class="language-php"><?php
namespace App\User;
class UserRepository
{
private $database;
public function __construct($database)
{
$this->database = $database;
}
public function getUserById($id)
{
return $this->database->query('SELECT * FROM users WHERE id = ?', [$id]);
}
public function createNewUser($email, $password)
{
// implementação
}
}</code></pre>
<p>Repare: <code>UserRepository</code> em PascalCase, métodos como <code>getUserById()</code> em camelCase, namespace declarado no topo, tag <code><?php</code> correta. Simples? Sim, mas crucial.</p>
<h3>PSR-2: Coding Style Guide</h3>
<p>PSR-2 é mais rigorosa. Especifica indentação de 4 espaços (não tabs), abertura de chaves na mesma linha, limitação de linhas (80 caracteres é recomendado), e regras precisas para estruturas de controle.</p>
<pre><code class="language-php"><?php
namespace App\User;
class UserService
{
private $repository;
public function __construct(UserRepository $repository)
{
$this->repository = $repository;
}
public function registerUser($email, $password)
{
if (empty($email) || empty($password)) {
throw new InvalidArgumentException('Email e senha são obrigatórios');
}
if ($this->userExists($email)) {
throw new RuntimeException('Usuário já cadastrado');
}
return $this->repository->createNewUser($email, $password);
}
private function userExists($email)
{
return $this->repository->findByEmail($email) !== null;
}
}</code></pre>
<p>Repare a indentação consistente de 4 espaços, a abertura de chave na mesma linha do <code>if</code>, e espaçamento ao redor de operadores. Na prática, use ferramentas como PHP-CS-Fixer ou PHPCS para automatizar isso — ninguém digita manualmente.</p>
<h2>PSR-4: Autoloading de Classes</h2>
<h3>Como Funciona PSR-4</h3>
<p>PSR-4 define como carregar classes automaticamente baseado em namespaces. Não é necessário mais fazer <code>require</code> ou <code>include</code> para cada arquivo. Você define um mapeamento entre namespace e diretório, e o autoloader cuida do resto. A regra é simples: um arquivo, uma classe; a estrutura de diretórios reflete os namespaces.</p>
<pre><code class="language-php">// composer.json
{
"autoload": {
"psr-4": {
"App\\": "src/",
"Tests\\": "tests/"
}
}
}
// src/User/UserRepository.php
<?php
namespace App\User;
class UserRepository
{
// implementação
}
// index.php - uso automático
<?php
require 'vendor/autoload.php';
$repository = new \App\User\UserRepository();</code></pre>
<p>No seu <code>composer.json</code>, você mapeia <code>App\\</code> para o diretório <code>src/</code>. Quando o código chama <code>new \App\User\UserRepository()</code>, o autoloader procura em <code>src/User/UserRepository.php</code>. Nenhum require necessário. Isso é ouro puro em projetos grandes.</p>
<h2>PSR-12: Modern PHP Coding Style</h2>
<h3>A Evolução Necessária</h3>
<p>PSR-12 substitui PSR-2 com regras modernizadas para PHP 7+. Mantém o essencial, mas adiciona clareza para sintaxes mais recentes como tipos de retorno, tipos de propriedades e tipos de argumento.</p>
<pre><code class="language-php"><?php
namespace App\Order;
use App\User\User;
use Doctrine\ORM\EntityRepository;
class OrderService
{
private EntityRepository $repository;
public function __construct(EntityRepository $repository)
{
$this->repository = $repository;
}
public function processOrder(User $user, array $items): Order
{
if (empty($items)) {
throw new InvalidArgumentException('Pedido sem itens');
}
$order = new Order(
user: $user,
items: $items,
createdAt: new DateTime()
);
return $this->repository->save($order);
}
public function getOrderStatus(int $orderId): ?string
{
$order = $this->repository->find($orderId);
return $order?->getStatus();
}
}</code></pre>
<p>Veja: tipagem forte (<code>User</code>, <code>array</code>, <code>Order</code>), propriedade tipada (<code>EntityRepository $repository</code>), named arguments (<code>user:</code>, <code>items:</code>), nullsafe operator (<code>$order?-></code>). PSR-12 abrange tudo isso com elegância e clareza.</p>
<h3>Namespaces e Use Statements</h3>
<p>PSR-12 também padroniza imports. Ordene alfabeticamente dentro de cada grupo: classes, depois interfaces, depois traits. Uma linha em branco separa cada grupo.</p>
<pre><code class="language-php"><?php
namespace App\Order;
use App\Notification\EmailService;
use App\Notification\SlackService;
use App\Repository\OrderRepository;
use DateTime;
use Throwable;</code></pre>
<p>Organizado e legível. Ferramentas como PHP-CS-Fixer fazem isso automaticamente.</p>
<h2>Conclusão</h2>
<p>Três aprendizados principais: <strong>Primeiro</strong>, PSR-1 e PSR-2 são o alicerce — nomenclatura consistente e formatação padrão economizam horas de debug. <strong>Segundo</strong>, PSR-4 com Composer elimina gerenciamento manual de includes, deixando você focar na lógica. <strong>Terceiro</strong>, PSR-12 moderniza seu código para PHP 7+, aproveitando tipagem e sintaxe contemporânea. Juntas, essas padrões transformam código caótico em código profissional, legível e mantível por qualquer desenvolvedor.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://www.php-fig.org/psr/" target="_blank" rel="noopener noreferrer">PHP-FIG Official Standards</a></li>
<li><a href="https://www.php-fig.org/psr/psr-1/" target="_blank" rel="noopener noreferrer">PSR-1: Basic Coding Standard</a></li>
<li><a href="https://www.php-fig.org/psr/psr-2/" target="_blank" rel="noopener noreferrer">PSR-2: Coding Style Guide</a></li>
<li><a href="https://www.php-fig.org/psr/psr-4/" target="_blank" rel="noopener noreferrer">PSR-4: Autoloading Standard</a></li>
<li><a href="https://www.php-fig.org/psr/psr-12/" target="_blank" rel="noopener noreferrer">PSR-12: Extended Coding Style Guide</a></li>
</ul>