この記事ではJavaのアノテーションに似た形でセットインジェクションを実装します
まずはDIコンテナコード
require 'DocParser.php';class Container { /** * 利用容器来实例化对象,外部调用接口 *@param $name 为类名 eg. 'User' */ public function get($name) { static $cache = array(); if(isset($cache[$name])) { return $cache[$name]; } require 'models/' . ucfirst($name) . '.php'; $reflection = new ReflectionClass($name); $depends = $this->getDependency($reflection); $cache[$name] = $this->createObject($reflection, $depends); return $cache[$name]; } /** * 利用反射获取类需要的依赖条件,注释中包含@inject 注解的public 变量 * @param $reflection ReflectionClass */ public function getDependency($reflection) { $depends = array(); $props = $reflection->getProperties(ReflectionProperty::IS_PUBLIC); foreach ($props as $prop) { $str = $prop->getDocComment(); $parser = new DocParser(); $anotations = $parser->parse($str); if(isset($anotations['inject'])) { $depends[$prop->getName()] = $anotations['inject']; } } return $depends; } /** * 实例化对象的方法 * @param $instance ReflectionClass * @param $depends array( 'field' => 'Class' ), field 为注入的变量名,class为注入的类 */ public function createObject($instance, $depends) { $instance = $instance->newInstanceArgs(array()); foreach ($depends as $key => $value) { $instance->{$key} = $this->get($value); } return $instance; }}
その中でDocParser.phpはphpのアノテーションを解析するためのツールクラスです。
class User { /** * 使用inject注解来标明该变量需要注入,后面跟着需要注入的类名 * @inject Email */ public $email; public function sendEmail() { $this->email->sendEmail(); }}
新しいEmail.phpを作成します
class Email { public function sendEmail() { echo 'send email!'; }}
ルートディレクトリに新しいindex.phpを作成します
require 'Container.php';$di = new Container();$user = $di->get('User');$user->sendEmail();
インデックスを実行します.php を実行すると、結果が表示されます。
この記事は IOC の実装プロセスを説明するだけであり、実際の使用シナリオは考慮されていません。
ソースコードのダウンロードアドレス