Por que o PHP ainda domina no Enterprise e como não fazer feio
\n\nQuando você ouve "PHP", a primeira coisa que vem à mente é uma landing page feita em uma noite ou um blog simples no WordPress. Mas abra as vagas de grandes bancos, varejistas ou empresas de telecomunicações — há toneladas de oportunidades para desenvolvedores PHP. E não se trata de "codar rápido". Isso é PHP Enterprise. Uma indústria inteira com suas próprias regras, padrões arquiteturais e cultura de code review.
\n\nQual a diferença entre desenvolver PHP em uma grande empresa e em uma startup? Você não está apenas escrevendo "código que funciona". Você está construindo um sistema que precisa durar anos, sobreviver a dezenas de releases e suportar a carga de milhares de usuários. Neste artigo, vou abordar os principais aspectos do desenvolvimento Enterprise em PHP: da arquitetura ao deploy. Muito código, dicas práticas e nada de enrolação.
\n\nArquitetura: SOLID, camadas e nada de mágica
\n\nNo Enterprise, a primeira regra é: o código deve ser previsível e facilmente testável. Não adianta pensar "aqui vou meter uma query direto no controller". Em projetos grandes, você precisa seguir os princípios SOLID e separar claramente as responsabilidades entre as camadas.
\n\nA arquitetura típica de uma aplicação Enterprise em PHP é assim:
\n\n- \n
- Camada de Apresentação — controllers, rotas, Middleware. \n
- Camada de Aplicação — serviços, DTOs, comandos/handlers (CQRS). \n
- Camada de Domínio — entidades, Value Objects, repositórios (interfaces). \n
- Camada de Infraestrutura — ORM, APIs externas, cache, filas. \n
Veja como fica na prática. Em vez de escrever SQL diretamente no controller:
\n\n// ❌ Ruim: misturando camadas\nclass OrderController {\n public function create(Request $request) {\n $db = new PDO('mysql:...');\n $db->exec("INSERT INTO orders (user_id, total) VALUES ({$request->get('user_id')}, {$request->get('total')})");\n return new JsonResponse(['status' => 'ok']);\n }\n}\n\nNo Enterprise, você verá algo assim:
\n\n// ✅ Bom: separação de responsabilidades\nclass OrderController {\n public function __construct(\n private OrderService $orderService\n ) {}\n\n public function create(CreateOrderRequest $request): JsonResponse {\n $dto = new CreateOrderDTO(\n userId: $request->getUserId(),\n total: $request->getTotal()\n );\n\n $order = $this->orderService->createOrder($dto);\n\n return new JsonResponse(['id' => $order->getId()]);\n }\n}\n\nclass OrderService {\n public function __construct(\n private OrderRepositoryInterface $orderRepository,\n private EventDispatcher $eventDispatcher\n ) {}\n\n public function createOrder(CreateOrderDTO $dto): Order {\n $order = new Order($dto->userId, $dto->total);\n $this->orderRepository->save($order);\n $this->eventDispatcher->dispatch(new OrderCreatedEvent($order));\n return $order;\n }\n}\n\nPercebeu a diferença? A segunda versão pode ser testada, reutilizada e modificada facilmente. Isso é PHP Enterprise — quando o código não apenas funciona, mas é bem projetado.
\n\nValue Objects e tipagem forte
\n\nEm projetos grandes, você não verá string $email nos parâmetros. Em vez disso, são usados Value Objects. Isso gera código autodocumentado que previne erros em tempo de compilação.
class Email {\n public function __construct(private string $value) {\n if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {\n throw new \\InvalidArgumentException('Email inválido');\n }\n }\n\n public function getValue(): string {\n return $this->value;\n }\n}\n\nclass User {\n public function __construct(\n private UserId $id,\n private Email $email