PHP PSRs : PSR-2 & PSR-12 Parte 1

Antonio Silva - Oct 7 '23 - - Dev Community

PSR-2 (CODING STYLE GUIDE)

A PSR-2 surgiu com o objetivo de tornar a escrita e a legibilidade do código mais simples e fácil para os desenvolvedores.

INFORMAÇÃO IMPORTANTE
A PSR-2 foi descontinuada/substituda pela PSR-12 devido a inúmeras funcionalidades que foram surgindo no PHP.

PSR-12 (EXTENDED CODING STYLE)

A PSR-12 é uma extensão da PSR-2 e possui o mesmo objetivo que ela, porém com um contexto mais moderno e novas funcionalidades que seguem a evolução do PHP.

Como o PHP 7 teve muitas mudanças, a reescrita da PSR-2 em uma nova PSR foi necessária para atender a todas as novidades disponíveis no PHP 7.

Regras

  • Regra 1:

Os códigos PHP DEVEM seguir os padrões estabelecidos na
PSR-1. Por ser uma extensão da PSR-1, seu código primeiramente deve estar em conformidade com a PSR-1 antes de aplicar a PSR-12.

O termo StudlyCaps no PSR-1 DEVE ser interpretado como PascalCase , onde a primeira letra de cada palavra é maiúscula.

  • Regra 2:

Arquivos PHP DEVEM possuir o padrão UNIX de terminação de linha.

  • CRLF: retorno de carro + avanço de linha, Unicode caracteres D + 000A 000
  • LF: alimentação de linha, caracteres Unicode 000A
  • NEL: próxima linha, o caractere Unicode 0085
  • LS: separador de linha, caractere Unicode 2028
  • PS: separador de parágrafo, caractere Unicode 2029

O padrão UNIX adotado pela PSR-12 é o LF. Geralmente, as IDEs já vêm configuradas para o padrão UNIX, mas isso pode ser alterado facilmente dependendo da IDE utilizada.

  • Regra 3:

Arquivos contendo apenas código PHP DEVEM possuir uma linha em branco ao final. Após toda a lógica aplicada, deve haver uma linha em branco ao final do arquivo.

  • Regra 4:

Arquivos contendo apenas PHP DEVEM ter a TAG de fechamento omitida. A regra não se aplica aos arquivos contendo HTML + PHP.

  • Regra 5:

O comprimento máximo de uma linha de código DEVE ser de 120 caracteres. Verificadores de estilo automatizado DEVEM avisar, mas NÃO DEVEM exibir erro.

As linhas de código NÃO DEVEM ter mais de 80 caracteres. Linhas de código mais longas DEVEM ser quebradas em várias linhas subsequentes de no máximo 80 caracteres.

Portanto, atente-se para que a cada 80 caracteres você possa quebrar a linha de modo que fique legível e, caso não consiga, você ainda possui o limite de 120 caracteres.

  • Regra 6:

Linhas que possuem conteúdo NÃO DEVEM possuir espaços em branco ao final de seu conteúdo.

  • Regra 7:

Para facilitar a interpretação do código, linhas em branco PODEM ser adicionadas. Você pode adicionar linhas em branco para tornar a interpretação do código mais fácil.

<?php

    class Usuario
    {

      private $nome;

      private $idade;

      private $sexo;

      public function __construct($nome, $idade, $sexo)
      {
      }

    }
// linha em branco no final do código
Enter fullscreen mode Exit fullscreen mode
  • Regra 8:

NÃO DEVE haver múltiplas declarações em uma única linha cada declaração de variável deve ser feita em uma nova linha.

Maneira certa:

<?php

    $nome = 'Jhones';

    $sobrenome = 'S. Clementino';
Enter fullscreen mode Exit fullscreen mode

Maneira errada:

<?php

    $nome = 'Jhones'; $sobrenome = 'S. Clementino';
Enter fullscreen mode Exit fullscreen mode
  • Regra 9:

Códigos PHP DEVEM possuir indentação com 4 espaços e não com TABs. Algumas IDEs já vêm com o padrão de 4 espaços ao teclar o TAB.

  • Regra 10:

As palavras-chaves, tipos reservados e constantes true, false e null DEVEM ser escritas com letras minúsculas.

Quaisquer novos tipos e palavras-chaves adicionados em versões futuras do PHP DEVEM estar em minúsculas.

É necessário usar uma forma abreviada de palavras-chaves do
tipo de dado, ou seja, bool em vez de boolean, int em vez de
integer etc.

  • Regra 11:

Se o cabeçalho estiver presente, cada um dos blocos a seguir DEVE ser separado por uma única linha em branco e NÃO DEVE conter uma linha em branco.

Cada bloco DEVE estar na ordem listada a seguir, mas os blocos que não são relevantes podem ser omitidos.

  • Tag de abertura <?php do PHP;
  • Docblock /** Descrição */ no nível do arquivo;
  • Uma ou mais declarações declare() ;
  • A definição do namespace do arquivo;
  • Uma ou mais instruções de importação use baseadas em classes;
  • Uma ou mais instruções de importação use baseadas em funções;
  • Uma ou mais instruções de importação use baseadas em constantes;
  • O restante do código.

Vamos conferir um exemplo a seguir que ilustra a aplicação da sequência definida pela PSR-12 citada anteriormente:

<?php

    /**
     * Descrição do arquivo
     */

    declare(strict_types=1);

    namespace App\Controller\Usuario;

    use App\Controller\{AbstractController as Abc, ControllerInterface, BaseController as Base};
    use App\Entity\Usuario;

    use function App\Functions\{functionA, functionN, functionC};
    use function App\Repository\Functions\insert;

    use const App\Controller\{RESPONSE_JSON, RESPONSE_XML, RESPONSE_ERROR};
    use const App\Service\{CONSTANT_A}

    /**
     * Classe de exemplo
     */
    class UsuarioController
    {
      //Código...
    }

Enter fullscreen mode Exit fullscreen mode
  • Regra 12:

Os namespaces compostos com profundidade superior a dois NÃO DEVEM ser utilizados.

O exemplo a seguir demonstra a utilização máxima de composição permitida:

<?php

    use App\Service\{
        Usuario\UsuarioService,
        Contato\ContatoService,
        ServiceAbstract,
    }

Enter fullscreen mode Exit fullscreen mode

O exemplo a seguir não é permitido pela PSR-12:

<?php

    use App\Service\{
        Usuario\Admin\UsuarioService,
        Contato\ContatoService,
        ServiceAbstract,
    }

Enter fullscreen mode Exit fullscreen mode
  • Regra 13:

Se desejar declarar tipos estritos em arquivos contendo marcação HTML fora das TAGs de abertura <?php e fechamento ?> do PHP, a declaração DEVE estar na primeira linha do arquivo e incluir uma TAG de abertura <?php do PHP, a declaração de tipos estritos e em seguida TAG de fechamento ?> do PHP.

<?php declare(strict_types=1) ?>
<html>
<body>
    <?php //Código PHP... ?>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Instruções declare() NÃO DEVEM conter espaços e DEVEM ser declaradas exatamente da maneira a seguir: declare(strict_types=1). O ponto e vírgula no final da instrução é opcional.

  • Regra 14:

As declarações de bloco declare contendo o código a ser executado são permitidas e DEVEM ser formatadas como demonstrado no exemplo a seguir. Observe a posição das chaves e o espaçamento:

<?php

    declare(ticks=1) {
      // código...
    }

Enter fullscreen mode Exit fullscreen mode
  • Regra 15:

Após qualquer chave de fechamento, NÃO DEVE haver nenhum comentário ou declaração na mesma linha.

Ao instanciar uma nova classe, os parênteses DEVEM estar
sempre presentes, mesmo quando não houver parâmetros
passados para o construtor.

<?php

    new Usuario();

Enter fullscreen mode Exit fullscreen mode
  • Regra 16:

As palavras-chaves extends e implements DEVEM ser declaradas na mesma linha que contém o nome da classe.

A chave de abertura { da classe DEVE ser inserida em uma
nova linha e NÃO DEVE ser precedida ou seguida por uma linha em branco.

A chave de fechamento } da classe também DEVE ser inserida em uma nova linha logo após a definição do corpo da
classe e NÃO DEVE ser precedida ou seguida por uma linha em branco.

<?php

    class UsuarioController extends ControllerAbstract implements Countable
    {
      //Definição do corpo da classe...
    }
Enter fullscreen mode Exit fullscreen mode
  • Regra 17:

Quando houver a necessidade de múltiplos implements , eles PODEM ser divididos em múltiplas linhas, sendo que cada linha subsequente é recuada uma veze DEVE possuir somente uma interface por linha.

<?php

    class UsuarioController extends ControllerAbstract implements 
       \Countable,
       \Serializable
    {
      //Definição do corpo da classe...
    }
Enter fullscreen mode Exit fullscreen mode
  • Regra 18:

Para utilizar Traits e usufruir da herança vertical dentro das classes, a instrução use DEVE ser declarada na próxima linha após a chave { de abertura da classe.

<?php

    namespace App\Controller\Usuario;

    use App\Usuario\UsuarioTrait;

    class UsuarioController
    {
      use UsuarioTrait;
    }

Enter fullscreen mode Exit fullscreen mode
  • Regra 19:

Cada Trait a ser utilizada dentro da classe DEVE ser incluída uma por linha, sendo que cada Trait DEVE ter a sua própria declaração de uso use.

<?php

    namespace App\Controller\Usuario;

    use App\Usuario\UsuarioTrait;
    use App\Contato\ContatoTrait;
    use App\Endereco\EnderecoTrait;

    class UsuarioController
    {
      use UsuarioTrait;
      use ContatoTrait;
      use EnderecoTrait;
    }

Enter fullscreen mode Exit fullscreen mode
  • Regra 20:

Quando a classe não tem nada após a declaração de uso use, a chave de fechamento da classe DEVE estar na linha subsequente.

Se a classe tiver conteúdo após a declaração de uso da Trait DEVE ter uma linha em branco após a declaração de uso use.

<?php

    namespace App\Controller\Usuario;

    use App\Usuario\UsuarioTrait;

    class UsuarioController
    {
      use UsuarioTrait;

      private $usuario;
    }

Enter fullscreen mode Exit fullscreen mode
  • Regra 21:

O uso dos operadores insteadof e as DEVE ser feito da seguinte maneira, percebendo recuo, espaçamento e novas linhas:

<?php

    namespace App\Controller\Usuario;

    use App\Usuario\UsuarioTrait;
    use App\Contato\ContatoTrait;
    use App\Endereco\EnderecoTrait;

    class UsuarioController
    {
      use A, B, C {
          B::getUsuario insteadof A;
          A::getContato insteadof B;
          C::getEndereco as Endereco;
      }
    }

Enter fullscreen mode Exit fullscreen mode
  • Regra 22:

A visibilidade ou modificadores de acesso DEVEM ser definidos em todas as propriedades. Toda propriedade que for definida deve possuir o modificador de acesso definido antes do seu nome.

<?php

    class Usuario
    {
      private $nome;
      protected static $sexo;
      public int $indade;
    }

Enter fullscreen mode Exit fullscreen mode
  • Regra 23:

A palavra-chave var NÃO DEVE ser utilizada para a definição de propriedades da classe.

<?php

    class Usuario
    {
      var $nome;
      var $sobrenome;
      var $sexo;
      var $idade;
    }

Enter fullscreen mode Exit fullscreen mode

Apesar de não ser correto, o código será interpretado corretamente, e automaticamente todas as propriedades assumirão a visibilidade pública.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .