이 기사는 PHP 종속성 주입 컨테이너 구현에 관한 시리즈의 첫 번째 장입니다.
오늘은 컨테이너에 대해 이야기하지 않겠습니다. 먼저 몇 가지 구체적인 예를 사용하여 종속성 주입의 개념을 소개하여 이 모델이 해결할 수 있는 문제와 개발자에게 어떤 이점을 가져올 수 있는지 증명하겠습니다.
이미 종속성 주입의 개념을 알고 있다면 이 기사를 건너뛰어도 됩니다.
종속성 주입은 제가 아는 가장 간단한 디자인 패턴 중 하나일 수 있습니다. 많은 경우 무의식적으로 종속성 주입을 사용했을 수도 있습니다. 그러나 그것은 설명하기 가장 어려운 것 중 하나이기도 하다. 그 이유 중 하나는 의존성 주입을 도입하는 대부분의 예제에 실질적인 의미가 부족하고 이해하기 어렵다는 점이라고 생각합니다. PHP는 주로 웹 개발에 사용되므로 먼저 간단한 웹 개발 예제를 살펴보겠습니다.
HTTP 자체는 상태 비저장 연결 프로토콜입니다. 클라이언트가 WEB 요청을 시작할 때 애플리케이션이 사용자 정보를 저장하도록 지원하려면 저장 상태 상호 작용을 달성하는 기술을 사용해야 합니다. 물론 가장 쉬운 방법은 쿠키를 사용하는 것이고 더 좋은 방법은 PHP에 내장된 세션 메커니즘을 사용하는 것입니다.
$_SESSION['language'] = 'fr';
위 코드는 사용자 언어를 언어라는 세션 변수에 저장하므로 사용자의 후속 요청 시 전역 배열 $_SESSION:
$user_language = $_SESSION['language'];을 통해 언어를 얻을 수 있습니다. 🎜>종속성 주입은 주로 객체 지향 개발에 사용됩니다. 이제 PHP 세션 메커니즘을 캡슐화하는 SessionStorage 클래스가 있다고 가정해 보겠습니다.
class SessionStorage { function __construct($cookieName = 'PHP_SESS_ID') { session_name($cookieName); session_start(); } function set($key, $value) { $_SESSION[$key] = $value; } function get($key) { return $_SESSION[$key]; } // ... }더 고급 기능을 제공하는 User 클래스도 있습니다. 캡슐화:
class User { protected $storage; function __construct() { $this->storage = new SessionStorage(); } function setLanguage($language) { $this->storage->set('language', $language); } function getLanguage() { return $this->storage->get('language'); } // ... }코드는 매우 간단하며 User 클래스를 사용하는 것도 매우 간단합니다.
$user = new User(); $user->setLanguage('fr'); $user_language = $user->getLanguage();프로그램에 더 나은 확장성이 필요하지 않은 한 모든 것이 괜찮습니다. 이제 session_id를 저장하는 COOKIE 키 값을 변경한다고 가정해 보겠습니다. 다음은 몇 가지 대체 방법입니다. User 클래스에서 SessionStorage 인스턴스를 생성할 때 SessionStorage 생성자에 하드 코딩된 'SESSION_ID' 문자열을 사용합니다.
class User { function __construct() { $this->storage = new SessionStorage('SESSION_ID'); } // ... }User 클래스 외부에 상수 설정(STORAGE_SESSION_NAME)
class User { function __construct() { $this->storage = new SessionStorage(STORAGE_SESSION_NAME); } // ... } define('STORAGE_SESSION_NAME', 'SESSION_ID');User 클래스 생성자의 매개변수를 통해 세션 이름 전달
class User { function __construct($sessionName) { $this->storage = new SessionStorage($sessionName); } // ... } $user = new User('SESSION_ID');세션 이름은 여전히 User 클래스 생성자의 매개변수를 통해 전달되지만 이번에는 매개변수가 배열 형식입니다.
class User { function __construct($storageOptions) { $this->storage = new SessionStorage($storageOptions['session_name']); } // ... } $user = new User(array('session_name' => 'SESSION_ID'));위의 내용은 모두 나쁜 의미입니다.
나중에 session_id를 저장하는 COOKIE 키 값을 변경해야 한다면 user 클래스에 세션 이름을 하드코딩해도 문제가 해결되지 않습니다. (User 클래스는 신경 쓰지 않아도 됩니다.) COOKIE 키 값에 대해).
상수 사용 방법도 좋지 않아 User 클래스가 상수 설정에 의존하게 됩니다.
User 클래스 생성자의 매개변수나 배열을 통해 세션 이름을 전달하는 것이 상대적으로 더 좋지만, 세션을 저장하는 방법이 사용자 클래스 생성자의 매개변수와 충돌하므로 완벽하지는 않습니다. 사용자 클래스는 주의해야 합니다. 사용자 클래스는 이들과 연관되어서는 안됩니다.
class User { function __construct($storage) { $this->storage = $storage; } // ... }이것은 의존성 주입의 가장 전형적인 사례입니다. 이제 User 클래스 사용에 대한 몇 가지 작은 변경 사항이 있습니다. 먼저 SessionStorage 개체를 만들어야 합니다.
$storage = new SessionStorage('SESSION_ID'); $user = new User($storage);이제 세션 저장소 개체를 구성하는 것도 매우 간단하고, 세션 저장소 개체를 변경하는 것도 매우 간단합니다. 이 모든 작업은 User 클래스를 업데이트할 필요가 없으므로 비즈니스 수업.
Pico Container의 웹사이트에서는 종속성 주입에 대해 다음과 같이 설명합니다.
class User { function __construct($storage) { $this->storage = $storage; } // ... }세터 메서드 주입
class User { function setSessionStorage($storage) { $this->storage = $storage; } // ... }직접 속성 주입
class User { public $sessionStorage; } $user->sessionStorage = $storage;
根据经验,一般通过构造函数注入的是强依赖关系的组件,setter方式用来注入可选的依赖组件。
现在,大多数流行的PHP框架都采用了依赖注入的模式实现业务组件间的高内聚低耦合。
// symfony: 构造函数注入的例子 $dispatcher = new sfEventDispatcher(); $storage = new sfMySQLSessionStorage(array('database' => 'session', 'db_table' => 'session')); $user = new sfUser($dispatcher, $storage, array('default_culture' => 'en')); // Zend Framework: setter方式注入的例子 $transport = new Zend_Mail_Transport_Smtp('smtp.gmail.com', array( 'auth' => 'login', 'username' => 'foo', 'password' => 'bar', 'ssl' => 'ssl', 'port' => 465, )); $mailer = new Zend_Mail(); $mailer->setDefaultTransport($transport);
以上就是理解PHP依赖注入容器系列(一) 什么是的内容,更多相关内容请关注PHP中文网(www.php.cn)!