PHP 实现 IOC set 注入
本文采用类似java中annotation的形式实现set注入
首先DI容器代码
<code class="language-php hljs "><span class="hljs-keyword">require</span> <span class="hljs-string">'DocParser.php'</span>;<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Container</span>{</span> <span class="hljs-comment">/** * 利用容器来实例化对象,外部调用接口 [email protected] $name 为类名 eg. 'User' */</span> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">get</span><span class="hljs-params">(<span class="hljs-variable">$name</span>)</span> {</span> <span class="hljs-keyword">static</span> <span class="hljs-variable">$cache</span> = <span class="hljs-keyword">array</span>(); <span class="hljs-keyword">if</span>(<span class="hljs-keyword">isset</span>(<span class="hljs-variable">$cache</span>[<span class="hljs-variable">$name</span>])) { <span class="hljs-keyword">return</span> <span class="hljs-variable">$cache</span>[<span class="hljs-variable">$name</span>]; } <span class="hljs-keyword">require</span> <span class="hljs-string">'models/'</span> . ucfirst(<span class="hljs-variable">$name</span>) . <span class="hljs-string">'.php'</span>; <span class="hljs-variable">$reflection</span> = <span class="hljs-keyword">new</span> ReflectionClass(<span class="hljs-variable">$name</span>); <span class="hljs-variable">$depends</span> = <span class="hljs-variable">$this</span>->getDependency(<span class="hljs-variable">$reflection</span>); <span class="hljs-variable">$cache</span>[<span class="hljs-variable">$name</span>] = <span class="hljs-variable">$this</span>->createObject(<span class="hljs-variable">$reflection</span>, <span class="hljs-variable">$depends</span>); <span class="hljs-keyword">return</span> <span class="hljs-variable">$cache</span>[<span class="hljs-variable">$name</span>]; } <span class="hljs-comment">/** * 利用反射获取类需要的依赖条件,[email protected] 注解的public 变量 *<span class="hljs-phpdoc"> @param</span> $reflection ReflectionClass */</span> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getDependency</span><span class="hljs-params">(<span class="hljs-variable">$reflection</span>)</span> {</span> <span class="hljs-variable">$depends</span> = <span class="hljs-keyword">array</span>(); <span class="hljs-variable">$props</span> = <span class="hljs-variable">$reflection</span>->getProperties(ReflectionProperty::IS_PUBLIC); <span class="hljs-keyword">foreach</span> (<span class="hljs-variable">$props</span> <span class="hljs-keyword">as</span> <span class="hljs-variable">$prop</span>) { <span class="hljs-variable">$str</span> = <span class="hljs-variable">$prop</span>->getDocComment(); <span class="hljs-variable">$parser</span> = <span class="hljs-keyword">new</span> DocParser(); <span class="hljs-variable">$anotations</span> = <span class="hljs-variable">$parser</span>->parse(<span class="hljs-variable">$str</span>); <span class="hljs-keyword">if</span>(<span class="hljs-keyword">isset</span>(<span class="hljs-variable">$anotations</span>[<span class="hljs-string">'inject'</span>])) { <span class="hljs-variable">$depends</span>[<span class="hljs-variable">$prop</span>->getName()] = <span class="hljs-variable">$anotations</span>[<span class="hljs-string">'inject'</span>]; } } <span class="hljs-keyword">return</span> <span class="hljs-variable">$depends</span>; } <span class="hljs-comment">/** * 实例化对象的方法 *<span class="hljs-phpdoc"> @param</span> $instance ReflectionClass *<span class="hljs-phpdoc"> @param</span> $depends array( 'field' => 'Class' ), field 为注入的变量名,class为注入的类 */</span> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createObject</span><span class="hljs-params">(<span class="hljs-variable">$instance</span>, <span class="hljs-variable">$depends</span>)</span> {</span> <span class="hljs-variable">$instance</span> = <span class="hljs-variable">$instance</span>->newInstanceArgs(<span class="hljs-keyword">array</span>()); <span class="hljs-keyword">foreach</span> (<span class="hljs-variable">$depends</span> <span class="hljs-keyword">as</span> <span class="hljs-variable">$key</span> => <span class="hljs-variable">$value</span>) { <span class="hljs-variable">$instance</span>->{<span class="hljs-variable">$key</span>} = <span class="hljs-variable">$this</span>->get(<span class="hljs-variable">$value</span>); } <span class="hljs-keyword">return</span> <span class="hljs-variable">$instance</span>; }}</code>
其中 DocParser.php
为解析php注释的工具类。
models
文件夹,新建User.php
<code class="language-php hljs "><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span>{</span> <span class="hljs-comment">/** * 使用inject注解来标明该变量需要注入,后面跟着需要注入的类名 *<span class="hljs-phpdoc"> @inject</span> Email */</span> <span class="hljs-keyword">public</span> <span class="hljs-variable">$email</span>; <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sendEmail</span><span class="hljs-params">()</span> {</span> <span class="hljs-variable">$this</span>->email->sendEmail(); }}</code>
新建Email.php
<code class="language-php hljs "><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Email</span>{</span> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sendEmail</span><span class="hljs-params">()</span> {</span> <span class="hljs-keyword">echo</span> <span class="hljs-string">'send email!'</span>; }}</code>
在根目录下新建index.php
<code class="language-php hljs "><span class="hljs-keyword">require</span> <span class="hljs-string">'Container.php'</span>;<span class="hljs-variable">$di</span> = <span class="hljs-keyword">new</span> Container();<span class="hljs-variable">$user</span> = <span class="hljs-variable">$di</span>->get(<span class="hljs-string">'User'</span>);<span class="hljs-variable">$user</span>->sendEmail();</code>
运行一下index.php
就能看到结果了。
本文只是演示IOC的实现过程,没有考虑实际使用场景。
源码 下载地址