PHP 实现 IOC set 注入

本文采用类似java中annotation的形式实现set注入
首先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注释的工具类。

  • 使用方法篇
    在同级目录下新建models文件夹,新建User.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();

运行一下index.php就能看到结果了。
本文只是演示IOC的实现过程,没有考虑实际使用场景。

源码 下载地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值