PHP PHP에서 의존성 주입 제대로 활용하는 법
페이지 정보

영삼이
본문
✅ PHP에서 의존성 주입 제대로 활용하는 법
의존성 주입(Dependency Injection, DI) 은 객체 간의 결합도를 낮추고 테스트 가능성과 확장성을 높이는 중요한 설계 기법입니다.
이 글에서는 PHP에서 DI를 어떻게 활용할 수 있는지 예제를 통해 소개합니다.
💡 의존성 주입이란?
기존 방식은 클래스가 직접 필요한 객체를 생성하거나 가져와서 사용합니다.
[code=php]
class UserService {
private $db;
public function __construct() {
$this->db = new DatabaseConnection(); // 강한 결합
}
}
[/code]
위 방식은 UserService
가 DatabaseConnection
에 강하게 결합되어 있어 테스트나 확장이 어렵습니다.
이를 해결하는 방식이 바로 "의존성 주입"입니다.
🔧 생성자 주입 (Constructor Injection)
가장 일반적인 DI 방식은 생성자를 통한 주입입니다.
[code=php]
class UserService {
private $db;
public function __construct(DatabaseConnection $db) {
$this->db = $db;
}
}
[/code]
이제 UserService
는 외부에서 DatabaseConnection
을 주입받기 때문에 테스트용 DB 모킹(mocking)도 가능해지고, 다양한 구현체로 대체할 수 있습니다.
🧪 인터페이스를 활용한 느슨한 결합
인터페이스를 도입하면 더욱 유연한 설계가 가능합니다.
[code=php]
interface DatabaseInterface {
public function query(string $sql);
}
class MySQLConnection implements DatabaseInterface {
public function query(string $sql) {
// MySQL 처리
}
}
class UserService {
private $db;
public function __construct(DatabaseInterface $db) {
$this->db = $db;
}
}
[/code]
이제 UserService
는 MySQLConnection
뿐만 아니라 PostgreSQLConnection
등 다른 구현체도 받을 수 있게 됩니다.
🧰 간단한 DI 컨테이너 구현 예시
간단한 DI 컨테이너를 직접 만들어보면 DI 개념이 더 잘 이해됩니다.
[code=php]
class Container {
private $bindings = [];
public function bind($abstract, $concrete) {
$this->bindings[$abstract] = $concrete;
}
public function make($abstract) {
$concrete = $this->bindings[$abstract];
// Reflection을 활용해 의존성 분석 및 주입
$reflector = new ReflectionClass($concrete);
$constructor = $reflector->getConstructor();
if (!$constructor) {
return new $concrete;
}
$params = $constructor->getParameters();
$dependencies = [];
foreach ($params as $param) {
$dependencies[] = $this->make($param->getType()->getName());
}
return $reflector->newInstanceArgs($dependencies);
}
}
[/code]
사용 예시:
[code=php]
$container = new Container();
$container->bind(DatabaseInterface::class, MySQLConnection::class);
$container->bind(UserService::class, UserService::class);
$userService = $container->make(UserService::class);
[/code]
🧠 마무리 팁
-
PHP에서는 Laravel, Symfony 등의 프레임워크가 강력한 DI 컨테이너를 내장하고 있습니다.
-
하지만 프레임워크 없이도 DI는 충분히 구현 가능하고, 실무 설계에서도 많은 이점을 줍니다.
-
클래스 간 결합도를 낮추고 테스트 가능성을 높이려면 꼭 DI를 적극 활용하세요.
- 이전글Laravel 없이 PHP로 PSR-4 오토로딩 구현하기 25.03.28
댓글목록
등록된 댓글이 없습니다.