PHP Padrões PSR
Cada programador tem as suas manias: chaves na mesma linha ou na de baixo, calcular_total ou calcularTotal, tab ou espaços. E cada biblioteca tinha o seu jeito de registrar logs, de carregar classes, de representar uma requisição HTTP. As PSRs são acordos da comunidade PHP para que todo mundo escreva do mesmo jeito e para que bibliotecas diferentes se encaixem como peças de LEGO.
- O que é uma PSR e quem é o PHP-FIG.
- As regras de estilo: PSR-1 (o básico) e PSR-12 (a formatação), e o sucessor PER Coding Style.
- A PSR-4 (autoload), em uma frase.
- A PSR-3: uma interface de log que todas as bibliotecas entendem.
- A ideia da PSR-7 e da PSR-15 (requisições HTTP e middlewares).
- Ferramentas que conferem e consertam o estilo: PHP_CodeSniffer e PHP-CS-Fixer.
A ideia: tomadas padronizadas
Qualquer aparelho comprado no Brasil encaixa em qualquer tomada brasileira, porque fabricantes concordaram com um padrão. Ninguém é obrigado por lei da física a seguir o padrão, mas quem não segue fica sem clientes.
As PSRs são isso para o PHP. PSR quer dizer PHP Standards Recommendation, "Recomendação de Padrão do PHP". São documentos numerados (PSR-1, PSR-3, PSR-4…) escritos pelo PHP-FIG (PHP Framework Interop Group, "Grupo de Interoperabilidade de Frameworks PHP"), um grupo formado em 2009 por representantes de grandes projetos PHP. "Interoperabilidade" é a palavra-chave: fazer peças de projetos diferentes funcionarem juntas.
O PHP roda código que não segue nenhuma PSR (você vai ver isso daqui a pouco). As PSRs não fazem parte da linguagem; são acordos. Mas o ecossistema inteiro (Composer, Laravel, Symfony, as bibliotecas do Packagist) segue as principais, e quem trabalha em equipe também.
Existem dois tipos de PSR:
| Tipo | O que define | Exemplos |
|---|---|---|
| Regras de escrita | Como escrever e organizar o código | PSR-1, PSR-12 (estilo), PSR-4 (autoload) |
| Interfaces | Um contrato (uma interface) que várias bibliotecas implementam, para serem trocáveis | PSR-3 (log), PSR-7 (HTTP), PSR-11 (contêiner), PSR-15 (middleware), PSR-18 (cliente HTTP) |
PSR-1: o estilo básico
A PSR-1 tem poucas regras, e todas importantes. As principais:
| Regra | Certo | Errado |
|---|---|---|
Arquivos começam com <?php (ou <?=), nunca <? sozinho | <?php | <? |
| Arquivos em UTF-8 sem BOM | "UTF-8" | "UTF-8 com BOM" |
Um arquivo declara coisas (classes, funções) ou faz coisas (echo, mudar configurações), não os dois | Produto.php só com a classe | Classe e echo no mesmo arquivo |
| Classes em PascalCase (cada palavra com maiúscula, sem separador) | CarrinhoDeCompras | carrinho_de_compras |
| Métodos em camelCase (como PascalCase, mas começando minúsculo) | calcularTotal() | Calcular_Total() |
Constantes de classe em MAIÚSCULAS com _ | TAXA_ENTREGA | taxaEntrega |
| Namespaces e classes seguem uma PSR de autoload (a PSR-4) | Ana\Lojinha\Pedido em src/Pedido.php | Várias classes num arquivo só |
A PSR-1 não decide o estilo das propriedades e variáveis; o importante é ser consistente. A maioria dos projetos usa camelCase também ($precoTotal).
PSR-12: a formatação
A PSR-12 continua a PSR-1 e decide o resto: espaços, chaves, linhas em branco. É um documento longo; você não precisa decorá-lo, porque as ferramentas conferem e consertam sozinhas (próxima seção). Mas reconheça o formato:
<?php
declare(strict_types=1);
namespace Ana\Lojinha;
use InvalidArgumentException;
class Carrinho
{
public const TAXA = 0.05;
private array $itens = [];
public function adicionarItem(string $nome, float $preco): void
{
if ($preco <= 0) {
throw new InvalidArgumentException("Preço inválido: $preco");
}
$this->itens[$nome] = $preco;
}
public function calcularTotal(): float
{
$total = array_sum($this->itens);
return $total > 100 ? $total : $total * (1 + self::TAXA);
}
}
| Regra da PSR-12 | No exemplo |
|---|---|
| Indentação de 4 espaços, nunca tab | Todo o corpo da classe |
Uma linha em branco entre os blocos do topo: <?php, declare, namespace, use | Linhas 2, 4, 6 e 8 |
| Chave de classe e método na linha de baixo | class Carrinho ↵ { |
Chave de if, foreach, while na mesma linha | if ($preco <= 0) { |
Um espaço depois de if, foreach…, e nenhum depois do ( | if ($preco, não if( $preco |
| Espaço dos dois lados dos operadores | $total * (1 + self::TAXA) |
Visibilidade sempre declarada (public, private…), inclusive nas constantes | public const TAXA |
| Espaço depois da vírgula, nenhum antes | adicionarItem(string $nome, float $preco) |
| Palavras do PHP em minúsculas | true, null, array |
Arquivo só com PHP termina sem ?> e com uma linha em branco | Último } seguido de quebra de linha |
Você vai encontrar três nomes. A PSR-2 foi a primeira regra de formatação (2012) e está obsoleta. A PSR-12 (2019) a substituiu. Como o PHP ganhou recursos depois disso (enums, match, atributos, property hooks), o PHP-FIG passou a manter o PER Coding Style (PER = "PHP Evolving Recommendation", recomendação que evolui), que estende a PSR-12 para a sintaxe nova. Na prática, quem segue a PSR-12 já segue quase tudo.
Conferindo o estilo com ferramentas
A Ana escreveu este arquivo com pressa:
<?php
namespace Ana\Lojinha;
class carrinho_de_compras {
const taxa=0.05;
private $Itens = array();
function Adicionar_Item($nome,$preco){
$this->Itens[$nome]=$preco;
}
public function calcular_total() {
$total=0;
foreach($this->Itens as $preco){ $total+=$preco; }
if($total>100) {return $total;}
else {
return $total*(1+self::taxa);
}
}
}
Para o PHP, está tudo certo:
$ php ruim.php && echo "rodou sem erro" rodou sem erro
A ferramenta mais tradicional para conferir estilo é o PHP_CodeSniffer (o "farejador de código"), que traz dois comandos: phpcs (aponta os problemas) e phpcbf (conserta o que der). Ele se instala com o Composer, como ferramenta de desenvolvimento:
$ composer require --dev squizlabs/php_codesniffer
./composer.json has been created
Running composer update squizlabs/php_codesniffer
…
- Installing squizlabs/php_codesniffer (4.0.4): Extracting archive
…
Using version ^4.0 for squizlabs/php_codesniffer
$ vendor/bin/phpcs --standard=PSR12 ruim.php
FILE: /home/ana/estilo/ruim.php
--------------------------------------------------------------------------------
FOUND 34 ERRORS AND 1 WARNING AFFECTING 11 LINES
--------------------------------------------------------------------------------
1 | ERROR | [x] Header blocks must be separated by a single blank line
2 | ERROR | [x] Header blocks must be separated by a single blank line
3 | ERROR | [ ] Class name "carrinho_de_compras" is not in PascalCase
| | format
3 | ERROR | [x] Opening brace of a class must be on the line after the
| | definition
4 | WARNING | [ ] Visibility must be declared on all constants if your
| | project supports PHP 7.1 or later
4 | ERROR | [ ] Class constants must be uppercase; expected TAXA but found
| | taxa
4 | ERROR | [x] Expected at least 1 space before "="; 0 found
4 | ERROR | [x] Expected at least 1 space after "="; 0 found
6 | ERROR | [ ] Method name "carrinho_de_compras::Adicionar_Item" is not in
| | camel caps format
6 | ERROR | [ ] Visibility must be declared on method "Adicionar_Item"
6 | ERROR | [x] Expected 1 space between comma and argument "$preco"; 0
| | found
6 | ERROR | [x] Opening brace should be on a new line
7 | ERROR | [x] Line indented incorrectly; expected at least 8 spaces,
| | found 6
…
12 | ERROR | [x] Expected 1 space after IF keyword; 0 found
…
14 | ERROR | [x] Expected at least 1 space after "+"; 0 found
--------------------------------------------------------------------------------
PHPCBF CAN FIX THE 29 MARKED SNIFF VIOLATIONS AUTOMATICALLY
--------------------------------------------------------------------------------
Time: 52ms; Memory: 6MB
- vendor/bin/phpcs
- O programa instalado pelo Composer. Ferramentas de pacotes ficam em
vendor/bin/. - --standard=PSR12
- Qual padrão usar para conferir.
- FOUND 34 ERRORS AND 1 WARNING
- 35 problemas de estilo em 11 linhas. Cada linha da tabela: número da linha do arquivo, gravidade, e a regra quebrada (em inglês).
- [x]
- Problema que o
phpcbfconsegue consertar sozinho (espaços, chaves).[ ]= só você pode consertar (nomes, porque mudar um nome pode quebrar quem o usa).
Algumas mensagens traduzidas: Class name … is not in PascalCase format = "o nome da classe não está em PascalCase"; Visibility must be declared on method = "declare a visibilidade do método"; Expected at least 1 space before "="; 0 found = "esperava pelo menos 1 espaço antes do =; encontrei 0". Agora o conserto automático:
$ cp ruim.php consertado.php
$ vendor/bin/phpcbf --standard=PSR12 consertado.php
PHPCBF RESULT SUMMARY
----------------------------------------------------------------------
FILE FIXED REMAINING
----------------------------------------------------------------------
/home/ana/estilo/consertado.php 29 6
----------------------------------------------------------------------
A TOTAL OF 29 ERRORS WERE FIXED IN 1 FILE
----------------------------------------------------------------------
Time: 62ms; Memory: 6MB
$ cat consertado.php
<?php
namespace Ana\Lojinha;
class carrinho_de_compras
{
const taxa = 0.05;
private $Itens = array();
function Adicionar_Item($nome, $preco)
{
$this->Itens[$nome] = $preco;
}
public function calcular_total()
{
$total = 0;
foreach ($this->Itens as $preco) {
$total += $preco;
}
if ($total > 100) {
return $total;
} else {
return $total * (1 + self::taxa);
}
}
}
$ vendor/bin/phpcs --standard=PSR12 consertado.php
FILE: /home/ana/estilo/consertado.php
--------------------------------------------------------------------------------
FOUND 5 ERRORS AND 1 WARNING AFFECTING 4 LINES
--------------------------------------------------------------------------------
5 | ERROR | Class name "carrinho_de_compras" is not in PascalCase format
7 | WARNING | Visibility must be declared on all constants if your project
| | supports PHP 7.1 or later
7 | ERROR | Class constants must be uppercase; expected TAXA but found taxa
9 | ERROR | Method name "carrinho_de_compras::Adicionar_Item" is not in
| | camel caps format
9 | ERROR | Visibility must be declared on method "Adicionar_Item"
13 | ERROR | Method name "carrinho_de_compras::calcular_total" is not in
| | camel caps format
--------------------------------------------------------------------------------
Time: 51ms; Memory: 6MB
Todos os espaços, chaves e linhas em branco foram arrumados. Sobraram os 6 problemas de nomes e visibilidade, que são decisões suas.
E o Carrinho.php do exemplo da seção anterior, escrito no padrão, passa sem nenhuma reclamação (só a linha do tempo gasto aparece):
$ vendor/bin/phpcs --standard=PSR12 Carrinho.php && echo "sem problemas" Time: 59ms; Memory: 6MB sem problemas
Os nomes e a visibilidade que sobraram no consertado.php são exatamente o trabalho da missão abaixo.
Missão: termine o trabalho que o phpcbf não pode fazer. Renomeie a classe para CarrinhoDeCompras (PascalCase), os métodos para adicionarItem e calcularTotal (camelCase), a constante para TAXA, e declare public na constante e no método que está sem visibilidade. Lembre de atualizar também as linhas que usam esses nomes. A saída deve continuar Total: 52.5.
<?php
class carrinho_de_compras
{
const taxa = 0.05;
private array $itens = [];
function Adicionar_Item(string $nome, float $preco): void
{
$this->itens[$nome] = $preco;
}
public function calcular_total(): float
{
return array_sum($this->itens) * (1 + self::taxa);
}
}
$c = new carrinho_de_compras();
$c->Adicionar_Item("Caneca", 20);
$c->Adicionar_Item("Camiseta", 30);
echo "Total: ", $c->calcular_total(), "\n";
<?php
class CarrinhoDeCompras
{
public const TAXA = 0.05;
private array $itens = [];
public function adicionarItem(string $nome, float $preco): void
{
$this->itens[$nome] = $preco;
}
public function calcularTotal(): float
{
return array_sum($this->itens) * (1 + self::TAXA);
}
}
$c = new CarrinhoDeCompras();
$c->adicionarItem("Caneca", 20);
$c->adicionarItem("Camiseta", 30);
echo "Total: ", $c->calcularTotal(), "\n";
(Este exemplo junta a classe e o código que a usa num arquivo só, para caber no editor; num projeto, a PSR-1 pede arquivos separados.)
As ferramentas de estilo
| Ferramenta | Pacote | Como usar |
|---|---|---|
PHP_CodeSniffer (phpcs/phpcbf) | squizlabs/php_codesniffer | Confere e conserta; ótimo para "barrar" código fora do padrão |
| PHP-CS-Fixer | friendsofphp/php-cs-fixer | Focado em consertar; muitas regras configuráveis (vendor/bin/php-cs-fixer fix src) |
| Laravel Pint | laravel/pint | Uma "casca" do PHP-CS-Fixer com configuração pronta |
| O seu editor | — | VS Code e PhpStorm formatam no padrão PSR-12 ao salvar (veja Editores e IDEs) |
O jeito mais comum de usar: um script do Composer ("estilo": "phpcs --standard=PSR12 src") que todo mundo roda antes de enviar o código.
PSR-4: o autoload
Você já conhece: é a regra "prefixo de namespace → pasta base; o resto do nome vira subpastas; a classe vira Classe.php". Ana\Lojinha\Pagamento\Pix com o prefixo Ana\Lojinha\ em src/ fica em src/Pagamento/Pix.php. Veja os detalhes em Autoload e PSR-4. (A antiga PSR-0, que fazia algo parecido, está obsoleta.)
PSR-3: uma interface de log para todos
Na aula do Composer, a classe Pedido da Ana recebia um LoggerInterface, e não um Monolog\Logger. Essa interface vem do pacote psr/log, que é a PSR-3 em forma de código. Ela define os métodos que todo "registrador de log" deve ter:
| Método | Para quê |
|---|---|
emergency() | O sistema está fora do ar |
alert() | Alguém precisa agir já (ex.: banco de dados inacessível) |
critical() | Erro grave (ex.: exceção não esperada) |
error() | Erro que não para o sistema, mas deve ser investigado |
warning() | Algo estranho que não é erro (estoque baixo, recurso obsoleto) |
notice() | Evento normal, mas importante |
info() | Evento interessante (pedido fechado, usuário entrou) |
debug() | Detalhes para depurar |
log($nivel, …) | Registra em qualquer nível |
Todos recebem (string|Stringable $message, array $context = []). A PSR-3 também combina que a mensagem pode ter marcadores entre chaves, como {cliente}, trocados pelos valores do $context.
Por que isso importa: trocar sem mexer
Como o Pedido depende só da interface, qualquer classe que a implemente serve. A Ana escreveu um logger caseiro, que só mostra na tela, estendendo a classe AbstractLogger do próprio psr/log (ela já implementa os oito métodos chamando o log(); basta escrever esse):
<?php
declare(strict_types=1);
namespace Ana\Lojinha;
use Psr\Log\AbstractLogger;
use Stringable;
class LoggerDeTela extends AbstractLogger
{
public function log($level, string|Stringable $message, array $context = []): void
{
// troca {chave} pelo valor do contexto, como a PSR-3 sugere
$trocas = [];
foreach ($context as $chave => $valor) {
$trocas['{' . $chave . '}'] = $valor;
}
echo strtoupper($level), ": ", strtr((string) $message, $trocas), "\n";
}
}
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use Ana\Lojinha\LoggerDeTela;
use Ana\Lojinha\Pedido;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
$monolog = new Logger('loja');
$monolog->pushHandler(new StreamHandler('php://stdout'));
$caseiro = new LoggerDeTela();
(new Pedido($monolog))->fechar('Bruno', 69.8);
(new Pedido($caseiro))->fechar('Bruno', 69.8);
$caseiro->warning('Estoque baixo: {produto}', ['produto' => 'Caneca']);
$ php troca.php
[2026-10-16T23:53:07.283831+00:00] loja.INFO: Pedido fechado {"cliente":"Bruno","total":69.8} []
INFO: Pedido fechado
WARNING: Estoque baixo: Caneca
A mesma classe Pedido, sem nenhuma mudança, funcionou com o Monolog e com o logger caseiro. E uma classe que parece um logger, mas não declara a interface, é recusada pelo tipo do parâmetro:
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use Ana\Lojinha\Pedido;
class MeuLog
{
public function info(string $m, array $c = []): void { echo $m, "\n"; }
}
(new Pedido(new MeuLog()))->fechar('Bruno', 69.8);
$ php errado.php
Fatal error: Uncaught TypeError: Ana\Lojinha\Pedido::__construct(): Argument #1 ($log) must be of type Psr\Log\LoggerInterface, MeuLog given, called in /home/ana/lojinha/errado.php on line 14 and defined in /home/ana/lojinha/src/Pedido.php:11
Stack trace:
#0 /home/ana/lojinha/errado.php(14): Ana\Lojinha\Pedido->__construct(Object(MeuLog))
#1 {main}
thrown in /home/ana/lojinha/src/Pedido.php on line 11
"O argumento 1 precisa ser do tipo LoggerInterface, mas veio um MeuLog". Ter um método info() não basta: a classe precisa dizer implements LoggerInterface (ou estender AbstractLogger). Veja Interfaces.
Missão: o editor do guia não tem o pacote psr/log, então este exemplo traz uma versão mínima da interface. Complete o método log() para trocar cada marcador {chave} pelo valor do $context, como a PSR-3 descreve. Dica: monte um array ['{cliente}' => 'Bruno', …] e use strtr(). A saída deve ser INFO: Pedido de Bruno fechado: R$ 69.8.
<?php
// Versão mínima da LoggerInterface da PSR-3 (a real tem 9 métodos)
interface LoggerInterface
{
public function info(string $message, array $context = []): void;
}
class LoggerDeTela implements LoggerInterface
{
public function info(string $message, array $context = []): void
{
$this->log('info', $message, $context);
}
private function log(string $level, string $message, array $context): void
{
// troque os {marcadores} aqui
echo strtoupper($level), ": ", $message, "\n";
}
}
$log = new LoggerDeTela();
$log->info('Pedido de {cliente} fechado: R$ {total}', ['cliente' => 'Bruno', 'total' => 69.8]);
<?php
// Versão mínima da LoggerInterface da PSR-3 (a real tem 9 métodos)
interface LoggerInterface
{
public function info(string $message, array $context = []): void;
}
class LoggerDeTela implements LoggerInterface
{
public function info(string $message, array $context = []): void
{
$this->log('info', $message, $context);
}
private function log(string $level, string $message, array $context): void
{
$trocas = [];
foreach ($context as $chave => $valor) {
$trocas['{' . $chave . '}'] = $valor;
}
echo strtoupper($level), ": ", strtr($message, $trocas), "\n";
}
}
$log = new LoggerDeTela();
$log->info('Pedido de {cliente} fechado: R$ {total}', ['cliente' => 'Bruno', 'total' => 69.8]);
PSR-7 e PSR-15: HTTP como objetos (só a ideia)
Até aqui, no guia, uma requisição web é lida pelas superglobais ($_GET, $_POST, $_SERVER) e a resposta é feita com echo e header(). Funciona, mas espalha a requisição por variáveis globais e deixa a resposta "já enviada" assim que o primeiro echo roda.
A PSR-7 define interfaces para representar a conversa HTTP como objetos:
| Interface (PSR-7) | Representa | Exemplos de métodos |
|---|---|---|
ServerRequestInterface | A requisição que chegou | getMethod(), getQueryParams() (o $_GET), getParsedBody() (o $_POST), getHeaderLine('Accept') |
ResponseInterface | A resposta que vai sair | withStatus(404), withHeader('Content-Type', 'application/json'), getBody() |
UriInterface, StreamInterface… | O endereço, o corpo | getPath(), write() |
Um detalhe marcante: esses objetos são imutáveis. $resposta->withStatus(404) não muda a resposta; devolve uma cópia com o status novo (por isso o nome começa com with, "com").
A PSR-15 usa a PSR-7 para definir middlewares: "camadas" por onde a requisição passa antes de chegar à sua página (conferir login, registrar log, comprimir a resposta). Cada camada é uma classe com um único método:
<?php
// Só a forma da interface (do pacote psr/http-server-middleware):
interface MiddlewareInterface
{
public function process(
ServerRequestInterface $request,
RequestHandlerInterface $handler
): ResponseInterface;
}
// Cada middleware recebe a requisição, faz o seu trabalho
// e chama $handler->handle($request) para passar adiante.
Como são interfaces padrão, um middleware de login escrito para um framework funciona em outro. Frameworks como Slim e Mezzio são construídos assim; o Laravel e o Symfony têm formatos próprios, mas sabem converter para PSR-7. Você não precisa usar nada disso agora: quando encontrar $request->getParsedBody() num tutorial, já sabe de onde veio.
As PSRs que você vai encontrar
| PSR | Assunto | Situação |
|---|---|---|
| PSR-1 | Estilo básico (nomes, arquivos) | Aceita |
| PSR-12 | Formatação do código (substitui a PSR-2); continuada pelo PER Coding Style | Aceita |
| PSR-4 | Autoload (substitui a PSR-0) | Aceita |
| PSR-3 | Interface de log (psr/log) | Aceita |
| PSR-6 e PSR-16 | Cache (a 16 é a versão simples) | Aceitas |
| PSR-7 | Mensagens HTTP (requisição e resposta) | Aceita |
| PSR-11 | Contêiner de dependências ($container->get(…)) | Aceita |
| PSR-14 | Eventos | Aceita |
| PSR-15 | Middlewares HTTP | Aceita |
| PSR-17 | Fábricas de objetos HTTP | Aceita |
| PSR-18 | Cliente HTTP (fazer requisições para outras APIs) | Aceita |
| PSR-20 | Relógio (ClockInterface, útil em testes) | Aceita |
| PSR-0, PSR-2 | Autoload e estilo antigos | Obsoletas |
Os números pulados (5, 8, 9, 10…) são propostas que foram abandonadas ou ainda estão em discussão. A lista oficial fica em php-fig.org.
Quando dá errado
O que significa: o projeto exige PSR-12, e o seu código está fora do padrão. O PHP não reclama de estilo; a equipe, sim.
Como consertar: rode vendor/bin/phpcbf --standard=PSR12 src (ou o PHP-CS-Fixer) antes de enviar; depois confira com phpcs e conserte à mão os nomes.
O que significa: você passou um objeto que tem os métodos certos, mas a classe não declara a interface. Para o PHP, "parecer" não basta.
Como consertar: class MeuLog implements LoggerInterface (com todos os métodos) ou class MeuLog extends AbstractLogger (só o log()).
O que significa: o conserto automático não muda nomes, porque trocar o nome de uma classe ou método quebraria todo código que os usa.
Como consertar: renomeie à mão, ou com a função "Renomear" do editor, que atualiza todos os usos de uma vez.
Referência
| Item | O que é |
|---|---|
| PHP-FIG | O grupo que escreve as PSRs (php-fig.org) |
| PascalCase | Classes, interfaces, enums: CarrinhoDeCompras |
| camelCase | Métodos (e, por costume, variáveis e propriedades): calcularTotal |
| MAIÚSCULAS_COM_SUBLINHADO | Constantes: TAXA_ENTREGA |
vendor/bin/phpcs --standard=PSR12 arquivo | Aponta problemas de estilo |
vendor/bin/phpcbf --standard=PSR12 arquivo | Conserta o que der automaticamente |
vendor/bin/php-cs-fixer fix src | Conserta com o PHP-CS-Fixer |
Psr\Log\LoggerInterface | A interface da PSR-3 (pacote psr/log) |
Psr\Http\Message\ServerRequestInterface | A requisição da PSR-7 (pacote psr/http-message) |
Exercícios
1. Nome de classe
Escreva o nome pedido_de_venda no formato que a PSR-1 pede para classes:
2. Nome de método
Escreva o método Fechar_Pedido no formato da PSR-1:
3. Indentação
Quantos espaços a PSR-12 usa em cada nível de indentação?
4. O que acontece se você rodar um código fora da PSR-12 no PHP?
5. Qual a vantagem de uma classe receber LoggerInterface em vez de Monolog\Logger?
6. Na PSR-12, onde fica a chave { de um if e a de um método?
Resumo
- PSRs são recomendações do PHP-FIG para padronizar o estilo e permitir que bibliotecas se encaixem. O PHP não as exige; o ecossistema, sim.
- PSR-1:
<?php, UTF-8, classes em PascalCase, métodos em camelCase, constantes em MAIÚSCULAS. PSR-12 (e o PER Coding Style): 4 espaços, chaves de classe/método na linha de baixo, deifna mesma linha, visibilidade sempre. phpcsaponta,phpcbfe PHP-CS-Fixer consertam; nomes você troca à mão.- PSR-4: namespace → pasta (autoload).
- PSR-3:
LoggerInterface, cominfo(),warning(),error()… e marcadores{chave}. Dependa da interface, não da biblioteca. - PSR-7: requisição e resposta HTTP como objetos imutáveis; PSR-15: middlewares que usam esses objetos.