O que o PHP moderno mudou na prática
Durante anos o PHP carregou a fama de linguagem de script sem contrato. A linha 8 mudou esse quadro: tipos em propriedades, enums, classes readonly, promoção de construtor, match, argumentos nomeados e union types. Em um sistema corporativo o efeito não é estético. Tipo explícito vira contrato verificável, e ferramentas de análise estática (PHPStan, Psalm) apontam erro antes do deploy. Um declare(strict_types=1) no topo do arquivo elimina a coerção silenciosa que só aparece quando alguém digita a matrícula com máscara e o código aceita.
Enums merecem destaque porque resolvem um problema recorrente de retaguarda: status de pedido, de nota fiscal ou de proposta como string solta espalhada pelo código. Com enum, o status é um conjunto fechado, o match obriga a tratar todos os casos e qualquer valor novo quebra a análise em vez de quebrar a produção.
O modelo de execução também importa para quem decide. Em PHP-FPM cada requisição nasce e morre isolada, sem estado compartilhado entre chamadas, o que simplifica o raciocínio sobre vazamento de memória e facilita escala horizontal atrás de um balanceador. Com Opcache configurado, o custo de interpretar o código a cada requisição praticamente desaparece.
O que o Laravel entrega pronto e o que continua sendo responsabilidade do time
- Container e injeção de dependências: integrações com ERP, gateways e serviços internos entram por contrato, o que permite substituir a implementação em teste.
- Form Requests: validação de entrada declarativa, com regras versionadas junto ao código em vez de espalhadas em condicionais.
- Policies e Gates: alçada de aprovação e permissão por unidade passam a ser regra testável, não checagem manual na tela.
- Filas (Redis, SQS ou a própria tabela): chamadas a sistemas legados saem do ciclo da requisição, com retry e timeout explícitos.
- Migrations e seeders: o esquema do banco é versionado e revisado como código.
- Testes de feature com banco real: cobrem o fluxo inteiro, de rota a persistência.
- Scheduler com trava: rotinas noturnas de conciliação não rodam duas vezes por engano em múltiplas instâncias.
O que o framework não resolve: modelagem. Eloquent é conveniente para CRUD e caro em relatórios; lazy loading ingênuo gera N+1 na listagem de pedidos com centenas de itens. Regra de negócio em controller ou em model gordo é dívida que o framework não impede.
Um caso concreto: distribuidora com alçada de desconto
Uma distribuidora de autopeças com equipe interna enxuta mantinha um portal de pedidos em que o desconto era aprovado por e-mail. As regras: até certo percentual o supervisor libera, acima disso entra a gerência regional e, em outro patamar, a diretoria comercial. Não havia registro confiável de quem aprovou o quê.
Na reescrita em Laravel, a alçada virou Policy, o cálculo virou serviço com teste unitário, a validação do pedido ficou em Form Request e o envio ao ERP virou job em fila com idempotência (a chave do pedido evita duplicidade em retry). O portal responde mesmo com o ERP lento, e a trilha de auditoria passou a existir por construção. O ganho não veio do framework: veio de colocar a regra em um lugar testável.
Na prática
- Aplique
strict_types=1nos arquivos novos e trate os antigos conforme for mexendo. - Suba o nível do PHPStan aos poucos; cada nível revela um contrato quebrado.
- Troque strings de status por enum e deixe o
matchobrigar o tratamento de todos os casos. - Valide entrada em Form Request, nunca confiando apenas na tela.
- Coloque autorização em Policy, não em condicional de controller.
- Isole integração externa em job com timeout, retry e chave de idempotência.
- Antes de publicar uma listagem, revise N+1 olhando o log de queries.
- Mantenha regra de negócio em classe de serviço coberta por teste de feature.