Por que code review não é só sobre "encontrar bugs"
\n\nImagine: você escreveu um código perfeito. Ele funciona, passa nos testes, até o cliente está satisfeito. Mas chega o code review com um colega e... começa. "Por que aqui é == e não ===?", "Esse método faz 5 coisas ao mesmo tempo", "Cadê o tratamento de exceções?". Familiar?
Na verdade, code review em PHP não é uma caça aos bugs (embora também seja). É uma forma de tornar o código legível, seguro e sustentável. Especialmente no PHP, que em 25 anos de evolução acumulou muitas "armadilhas".
\n\nNeste artigo, vamos abordar o que verificar em um code review de PHP para que o código não apenas funcione, mas seja um padrão de qualidade. Preparado? Vamos nessa!
\n\n1. Tipagem e modos estritos
\n\nO PHP 7+ e 8 nos deram ferramentas poderosas para controle de tipos. Mas muitos projetos ainda vivem no "modo caos".
\n\nO que verificar:
\n\n- \n
- Os tipos dos argumentos e valores de retorno estão declarados? Se o método espera
inte você passastring— é motivo para conversa. \n - Tem
declare(strict_types=1);no início do arquivo? Sem isso, o PHP fará conversão implícita de tipos, o que frequentemente leva a erros ocultos. \n
<?php\ndeclare(strict_types=1);\n\n// Ruim: sem tipos\nfunction calculate($a, $b) {\n return $a + $b;\n}\n\n// Bom: tipagem estrita\nfunction calculate(int $a, int $b): int {\n return $a + $b;\n}\n?>\n\n\nDica para code review: se você vir mixed ou array sem especificação — pergunte "O que exatamente é esperado aqui?".
2. Segurança: Injeção SQL e XSS
\n\nPHP é como um canivete suíço: muitas funções, e muitas delas são perigosas. Especialmente em código legado.
\n\nTop 3 bandeiras vermelhas:
\n\n- \n
- Concatenação em consultas SQL. Se você vir
"SELECT * FROM usuarios WHERE id = ".$_GET['id']— é um grito de socorro. \n - Exibir dados sem escapamento.
echo $userInput;— olá XSS. \n - Armazenar senhas em texto puro. Sério, isso ainda acontece. \n
<?php\n// Perigoso!\n$sql = "SELECT * FROM usuarios WHERE email = '" . $email . "'";\n\n// Seguro (PDO)\n$stmt = $pdo->prepare("SELECT * FROM usuarios WHERE email = :email");\n$stmt->execute(['email' => $email]);\n?>\n\n\nEm um code review de PHP, sempre verifique o trabalho com dados externos. Qualquer $_GET, $_POST, $_COOKIE deve passar por filtragem.
3. Seguir os padrões PSR
\n\nA comunidade PHP criou os PSR (PHP Standards Recommendations) não por formalidade. É a linguagem que todos os desenvolvedores PHP falam.
\n\nO que deve estar em cada PR:
\n\n- \n
- PSR-12 (estilo de codificação): indentação de 4 espaços, chaves em nova linha para classes, espaços ao redor de operadores. \n
- PSR-4 (autoloading): os namespaces devem coincidir com o caminho do arquivo. \n
- Nomes de classes —
StudlyCaps, métodos —camelCase, constantes —UPPER_CASE. \n
<?php\nnamespace App\\Service;\n\nclass UserService // PSR-4: arquivo deve estar em src/Service/UserService.php\n{\n public function getUserById(int $id): ?User // camelCase\n {\n // ...\n }\n}\n?>\n\n\nDica: se o projeto não tem formatação automática (PHP CS Fixer, PHP_CodeSniffer) — esse é o primeiro ponto a melhorar.
\n\n4. Complexidade e arquitetura
\n\nCódigo bom é código que pode ser lido como um livro. E código ruim é como decifrar um manuscrito antigo.
\n\nNo que prestar atenção:
\n\n- \n
- Tamanho do método. Se o método tem mais de 20-30 linhas, provavelmente está fazendo demais. Considere extrair funções menores. \n
- Responsabilidade única. Cada classe deve ter um motivo claro para existir. Se você não consegue descrever o propósito dela em uma frase, talvez ela precise ser dividida. \n
- Acoplamento. Dependências ocultas, uso excessivo de singletons ou chamadas estáticas tornam o código difícil de testar. \n
<?php\n// Ruim: método faz tudo\npublic function processOrder($data) {\n // valida dados\n // calcula frete\n // aplica desconto\n // salva no banco\n // envia email\n}\n\n// Bom: cada responsabilidade em seu lugar\npublic function processOrder(OrderData $data): void {\n $this->validator->validate($data);\n $total = $this->pricingService->calculate($data);\n $order = $this->orderRepository->save($data, $total);\n $this->notificationService->sendConfirmation($order);\n}\n?>\n\n\n5. Tratamento de erros e exceções
\n\nNada pior que um sistema que "morre" silenciosamente ou exibe mensagens de erro para o usuário.
\n\nO que verificar no code review:
\n\n- \n
- Existem blocos try-catch onde necessário? Especialmente ao trabalhar com APIs externas, banco de dados ou arquivos. \n
- As mensagens de erro são informativas? "Erro ao processar" não ajuda ninguém. Inclua contexto. \n
- Exceções são registradas (log)? Um erro sem log é um erro que nunca aconteceu. \n
<?php\n// Ruim: engole o erro\ntry {\n $result = $api->call();\n} catch (Exception $e) {\n return null;\n}\n\n// Bom: registra e trata adequadamente\ntry {\n $result = $api->call();\n} catch (ApiException $e) {\n $this->logger->error('Falha na chamada da API: ' . $e->getMessage());\n throw new ServiceException('Serviço temporariamente indisponível', 503, $e);\n}\n?>\n\n\n6. Performance e consultas ao banco
\n\nPHP é rápido, mas consultas SQL mal escritas podem derrubar qualquer aplicação.
\n\nPontos de atenção:
\n\n- \n
- Consultas N+1. Se você vê um loop com consultas SQL dentro, é um alerta vermelho. \n
- Índices. As consultas mais frequentes usam índices? Verifique se há
EXPLAINnos planos de execução. \n - Carregamento preguiçoso (Lazy Loading) vs. Carregamento ansioso (Eager Loading). Em frameworks como Laravel ou Symfony, o uso incorreto pode gerar muitas consultas. \n
<?php\n// Ruim: N+1 problem\n$users = User::all();\nforeach ($users as $user) {\n echo $user->profile->bio; // uma consulta para cada usuário\n}\n\n// Bom: eager loading\n$users = User::with('profile')->get();\nforeach ($users as $user) {\n echo $user->profile->bio; // apenas 2 consultas\n}\n?>\n\n\n7. Testes e cobertura
\n\nCódigo sem testes é como um avião sem paraquedas. Pode até voar, mas o pouso é arriscado.
\n\nO que verificar:
\n\n- \n
- Testes unitários para a nova funcionalidade? Se não tem, o PR não deveria ser aprovado. \n
- Testes de integração? Especialmente para fluxos críticos como autenticação e pagamento. \n
- Os testes são significativos? Testes que só verificam se o método retorna algo sem validar a lógica não contam. \n
<?php\n// Exemplo de teste significativo\npublic function testCalculateTotalWithDiscount(): void {\n $order = new Order([\n 'items' => [['price' => 100, 'quantity' => 2]],\n 'discount' => 10\n ]);\n \n $total = $this->pricingService->calculateTotal($order);\n \n $this->assertEquals(180, $total); // (200 - 10%)\n}\n?>\n\n\n8. Documentação e comentários
\n\nComentários não devem explicar "o que" o código faz (o código já faz isso), mas sim "por que" ele faz de determinada forma.
\n\nO que procurar:
\n\n- \n
- Comentários desatualizados. Pior que não ter comentário é ter um comentário mentiroso. \n
- Documentação de APIs públicas. Métodos que serão usados por outros desenvolvedores devem ter PHPDoc claro. \n
- Código comentado. Se não está sendo usado, delete. Para isso existe o histórico do Git. \n
<?php\n// Ruim: comentário óbvio\n// Soma dois números\nfunction add(int $a, int $b): int {\n return $a + $b;\n}\n\n// Bom: explica o porquê\n// Usamos arredondamento para cima para evitar perda de centavos\nfunction calculateTax(float $amount): int {\n return (int) ceil($amount * 0.1);\n}\n?>\n\n\nChecklist final para seu Code Review em PHP
\n\nUse esta lista como guia rápido para suas revisões:
\n\n- \n
- ✅ Tipagem: strict_types, tipos declarados, sem mixed desnecessário \n
- ✅ Segurança: Prepared statements, escape de saída, sem dados sensíveis expostos \n
- ✅ Padrões: PSR-12, PSR-4, nomenclatura consistente \n
- ✅ Arquitetura: Métodos pequenos, responsabilidade única, baixo acoplamento \n
- ✅ Erros: Tratamento adequado, logs, mensagens claras \n
- ✅ Performance: Sem N+1, consultas otimizadas, índices \n
- ✅ Testes: Cobertura para novos códigos, testes significativos \n
- ✅ Documentação: Comentários úteis, PHPDoc, sem código morto \n
Lembre-se: code review em PHP não é sobre apontar erros, mas sobre construir um código melhor juntos. Seja respeitoso, seja objetivo e, acima de tudo, seja um desenvolvedor que ajuda outros a crescer.
\n\nTem alguma dica que faltou? Compartilhe nos comentários!