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.

Você vai aprender
  • 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.

Recomendação, não lei

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:

TipoO que defineExemplos
Regras de escritaComo escrever e organizar o códigoPSR-1, PSR-12 (estilo), PSR-4 (autoload)
InterfacesUm contrato (uma interface) que várias bibliotecas implementam, para serem trocáveisPSR-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:

RegraCertoErrado
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 doisProduto.php só com a classeClasse e echo no mesmo arquivo
Classes em PascalCase (cada palavra com maiúscula, sem separador)CarrinhoDeComprascarrinho_de_compras
Métodos em camelCase (como PascalCase, mas começando minúsculo)calcularTotal()Calcular_Total()
Constantes de classe em MAIÚSCULAS com _TAXA_ENTREGAtaxaEntrega
Namespaces e classes seguem uma PSR de autoload (a PSR-4)Ana\Lojinha\Pedido em src/Pedido.phpVá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-12No exemplo
Indentação de 4 espaços, nunca tabTodo o corpo da classe
Uma linha em branco entre os blocos do topo: <?php, declare, namespace, useLinhas 2, 4, 6 e 8
Chave de classe e método na linha de baixoclass Carrinho ↵ {
Chave de if, foreach, while na mesma linhaif ($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 constantespublic const TAXA
Espaço depois da vírgula, nenhum antesadicionarItem(string $nome, float $preco)
Palavras do PHP em minúsculastrue, null, array
Arquivo só com PHP termina sem ?> e com uma linha em brancoÚltimo } seguido de quebra de linha
PSR-2, PSR-12 e PER Coding Style

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 phpcbf consegue 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

FerramentaPacoteComo usar
PHP_CodeSniffer (phpcs/phpcbf)squizlabs/php_codesnifferConfere e conserta; ótimo para "barrar" código fora do padrão
PHP-CS-Fixerfriendsofphp/php-cs-fixerFocado em consertar; muitas regras configuráveis (vendor/bin/php-cs-fixer fix src)
Laravel Pintlaravel/pintUma "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étodoPara 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)RepresentaExemplos de métodos
ServerRequestInterfaceA requisição que chegougetMethod(), getQueryParams() (o $_GET), getParsedBody() (o $_POST), getHeaderLine('Accept')
ResponseInterfaceA resposta que vai sairwithStatus(404), withHeader('Content-Type', 'application/json'), getBody()
UriInterface, StreamInterface…O endereço, o corpogetPath(), 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

PSRAssuntoSituação
PSR-1Estilo básico (nomes, arquivos)Aceita
PSR-12Formatação do código (substitui a PSR-2); continuada pelo PER Coding StyleAceita
PSR-4Autoload (substitui a PSR-0)Aceita
PSR-3Interface de log (psr/log)Aceita
PSR-6 e PSR-16Cache (a 16 é a versão simples)Aceitas
PSR-7Mensagens HTTP (requisição e resposta)Aceita
PSR-11Contêiner de dependências ($container->get(…))Aceita
PSR-14EventosAceita
PSR-15Middlewares HTTPAceita
PSR-17Fábricas de objetos HTTPAceita
PSR-18Cliente HTTP (fazer requisições para outras APIs)Aceita
PSR-20Relógio (ClockInterface, útil em testes)Aceita
PSR-0, PSR-2Autoload e estilo antigosObsoletas

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

"Funciona, mas o revisor recusou"

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.

must be of type Psr\Log\LoggerInterface, MeuLog given

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()).

phpcs: "Class name … is not in PascalCase format" depois do phpcbf

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

ItemO que é
PHP-FIGO grupo que escreve as PSRs (php-fig.org)
PascalCaseClasses, interfaces, enums: CarrinhoDeCompras
camelCaseMétodos (e, por costume, variáveis e propriedades): calcularTotal
MAIÚSCULAS_COM_SUBLINHADOConstantes: TAXA_ENTREGA
vendor/bin/phpcs --standard=PSR12 arquivoAponta problemas de estilo
vendor/bin/phpcbf --standard=PSR12 arquivoConserta o que der automaticamente
vendor/bin/php-cs-fixer fix srcConserta com o PHP-CS-Fixer
Psr\Log\LoggerInterfaceA interface da PSR-3 (pacote psr/log)
Psr\Http\Message\ServerRequestInterfaceA 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:

class

2. Nome de método

Escreva o método Fechar_Pedido no formato da PSR-1:

public function ()

3. Indentação

Quantos espaços a PSR-12 usa em cada nível de indentação?

espaços

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, de if na mesma linha, visibilidade sempre.
  • phpcs aponta, phpcbf e PHP-CS-Fixer consertam; nomes você troca à mão.
  • PSR-4: namespace → pasta (autoload).
  • PSR-3: LoggerInterface, com info(), 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.