Estilo de código no PHP: as recomendações da PSR-1 e PSR-12
Tags: php, psr, standards, codestyle
Published: 2022-04-03 15:44:55

As PSRs, ou PHP Standards Recommendations, são uma série de especificações para o PHP elaboradas pela <a href="https://www.php-fig.org/" target="_blank">PHP-FIG (PHP Framework Interop Group)</a>, visando criar um padrão de código para os diferentes frameworks da linguagem, como autoloading, interfaces, requisições e respostas HTTP e estilo de códigos. Neste artigo falarei das PSR-1 e PSR-12, que tratam dos padrões de estilo de código.  
  

## PSR-1 - Basic Coding Standard

Como o próprio nome dessa PSR diz, ela aborda o padrão básico para escrever um código PHP.  

### O arquivo PHP
As tags que indicam que é um arquivo PHP devem ser somente `<?php ?>` e `<?= ?>` (em arquivos somente com código PHP o fechamento da tag `?>` não deve ser realizado, conforme especificado na PSR-12).  
Um arquivo PHP não deve misturar declarações de classes, funções constantes etc, com lógica externa a esses (*side effects*), como conectar a um serviço externo, alterar configurações, fazer `require` ou `include` de arquivos, ler e escrever arquivos etc. O exemplo abaixo mostra um código PHP misturando a declaração de classes com *side effects*, não recomendado:
```php
<?php
// side effect: alteração de configuração ini do PHP
ini_set('error_reporting', E_ALL);

// side file: carregando um arquivo
include "file.php";

// side effect: gerando saída HTML
echo "<html>\n";

// declaração de função
function myFunction()
{
    // corpo da função
}
```  
  
### Nomes de classes e *namespaces*
O *namespace* deve seguir o padrão determinado na <a href="https://www.php-fig.org/psr/psr-4/" target="_blank">PSR-4</a> e os nomes de classes devem seguir o padrão StudlyCaps (também conhecido como PascalCase, UpperCamelCase):
```php
<?php
namespace Project\Model;

class MyClass
{
    // corpo da classe
}
```
  
### Propriedades, métodos e constantes de classes
As constantes de classes devem seguir o padrão SCREAMING_SNAKE_CASE:
```php
<?php
namespace Project\Model;

class MyClass
{
    const DATE_APPROVED = '2022-04-03';
}
```  
A PSR-1 não define que o nome da propriedade seja no estilo StudlyCaps, camelCase or $under_score, ela apenas reforça que um único estilo seja usado em todo o escopo do projeto. Por convenção, o mais adotado é o camelCase: `private string $firstName`.  
Já os nomes dos métodos devem seguir o estilo camelCase: `    private function myFunction()`.  


## PSR-12: Extended Coding Style

A PSR-12 é uma recomendação bem mais longa, estendendo a PSR-1 e substituindo a PSR-2. Falarei aqui sobre como essa PSR trata do tamanho de linhas, indentação, estrutura de uma classe, palavras-chave e estruturas de controle.
  
### Linhas, indentação, palavras-chave e tipos
O comprimento recomendado de uma linha é de 80 caracteres. Declarações que extrapolam esse comprimento deve ser quebradas em mais linhas. Não deve haver espaços em branco no final de cada linha e é permitido inserir quebras de linha para facilitar a leitura do código, salvo em casos que isso é proibido. A indentação deve ser realizada com 4 espaços em cada nível.  
A escrita de palavras-chave e tipos deve ser em *lower case* e usar a forma curta quando disponível: `int`, `bool`, `false`, `echo` etc.  

### Estrutura de uma classe
Basicamente, a estrutura de uma classe deve ser: abertura da tag do PHP, declaração do *namespace*, importações com *use* e o corpo da classe.
Na escrita de uma classe o uso de `extends` e `implements` deve ser realizado na mesma linha do nome da classe. A abertura da chaves deve ser realizada após a linha do nome da classe e fechada após o corpo da classe.  
A visibilidade de uma propriedade, constante ou método deve ser explicitamente declarada. A abertura e fechamento de chaves dos métodos segue o mesmo padrão para as classes. Quando um método tem parâmetros sempre deve haver um espaço em branco após a vírgula e um parâmetro com valor padrão deve ser sempre colocado por último.
```php
<?php

namespace Vendor\Package;

use FooClass;

class MyClass extends ParentClass implements \ArrayAccess
{
    private int $myNumber;
    private string $myName;

    public function myFunction(int $number, string $name = ''): void
    {
        $this->myNumber = $number;
        $this->myName = $name;
    }
}
```
  
### Estruturas de controle
As recomendações gerais para todas as estruturas de controle são:
* entre o nome da estrutura de controle e a abertura do parênteses da estrutura deve haver um espaço em branco
* não deve ter espaço em branco após o fechamento do parênteses
* entre o fechamento do parênteses e a abertura da chave da estrutura de controle deve haver um espaço em branco
* o corpo da estrutura deve ser delimitado por chaves e a abertura da chave deve ser realizada na mesma linha da declaração da estrutura
* o corpo da estrutura deve ser iniciado na próxima linha após a abertura da chave e deve ser recuado uma vez

Exemplo com `if`:
```php
<?php

if ($variable) {
    // código
} else {
    // código
}
```


Para o restante das recomendações da PSR-12 <a href="https://www.php-fig.org/psr/psr-12/" target="_blank">acesse a documentação</a>.