Injeção de Dependência em PHP: Guia Completo com Exemplos

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução ao Dependency Injection em PHP



O desenvolvimento moderno em PHP é impensável sem os princípios de design orientado a objetos. Um dos padrões-chave que permite construir aplicações flexíveis, testáveis e de fácil manutenção é o Dependency Injection (DI) ou injeção de dependências.



A essência do padrão é simples: em vez de criar objetos dependentes dentro da classe, nós os passamos (injetamos) de fora. Isso muda radicalmente a arquitetura da aplicação, tornando as classes independentes de implementações específicas e simplificando seus testes.



Neste artigo, vamos analisar o que é Dependency Injection em PHP, quais são as formas de implementá-lo e como usar contêineres DI para automatizar o processo.



O problema: por que é ruim sem DI?



Vamos considerar um exemplo típico. A classe UserController é responsável por processar requisições relacionadas a usuários. Ela usa um banco de dados através da classe MysqlDatabase:



<?php

class MysqlDatabase { public function query(string $sql): array { // ... conexão com MySQL e execução da consulta return []; }}

class UserController { private MysqlDatabase $database;

public function __construct() { // Acoplamento rígido a uma implementação específica $this->database = new MysqlDatabase(); }

public function listUsers(): array { return $this->database->query('SELECT * FROM users'); }}

$controller = new UserController();


Quais são os problemas deste código?



  • Alto acoplamento: UserController está rigidamente ligado a MysqlDatabase. Se quisermos migrar para PostgreSQL ou usar armazenamento em arquivo, teremos que alterar o código do controller.
  • Dificuldade de teste: Você não conseguirá substituir o banco de dados por um objeto mock em testes unitários. Cada teste acessará o banco real, o que é lento e inconveniente.
  • Violação do princípio da responsabilidade única: O controller não deveria saber como criar uma conexão com o banco de dados. Sua função é processar requisições.


A solução para este problema é aplicar o princípio da Inversão de Controle (IoC) e usar Dependency Injection.



Formas de injeção de dependências em PHP



Existem três formas principais de injetar uma dependência em uma classe:



1. Injeção via construtor (Constructor Injection)



A forma mais comum e recomendada. A dependência é passada através do parâmetro do construtor e geralmente é armazenada como uma propriedade privada da classe.



<?php

interface DatabaseInterface { public function query(string $sql): array;}

class MysqlDatabase implements DatabaseInterface { public function query(string $sql): array { // Implementação para MySQL return []; }}

class PostgresDatabase implements DatabaseInterface { public function query(string $sql): array { // Implementação para PostgreSQL return []; }}

class UserController { private DatabaseInterface $database;

// A dependência é injetada através do construtor public function __construct(DatabaseInterface $database) { $this->database = $database; }

public function listUsers(): array { return $this->database->query('SELECT * FROM users'); }}

// Uso$mysqlDb = new MysqlDatabase();$controller = new UserController($mysqlDb);

// Facilmente trocamos para outro BD$postgresDb = new PostgresDatabase();$controller2 = new UserController($postgresDb);


Vantagens: A dependência é explicitamente visível, o objeto é criado em um estado válido (a dependência é obrigatória).



2. Injeção via setters (Setter Injection)



Adequado para dependências opcionais ou quando as dependên

Blogs

Book Recommendations