控制反转(Ioc)

需要外部依赖的操作时,不需要修改自身代码,由外部依赖处理的方式就是控制反转。

代码演示

// 定义接口规范
interface Log
{
    public function write();
}
// 文件日志
class FileLog implements Log
{
    public function write()
    {
        echo "file log...";
    }
}
// 数据库日志
class DatabaseLog implements Log
{
    public function write()
    {
        echo "database log...";
    }
}

// 用户业务类,依赖日志存储
class User
{
    protected $log;
    public function __construct(Log $log)
    {
        $this->log = $log;
    }
    public function Login()
    {
        // 登录操作
        // todo..
        $this->log->write();
    }
}

$user = new User(new FileLog());
$user->login();

依赖注入

上面的例子也算依赖入驻,概念就是不是自己内部new对象而是通过方法或者构造函数的参数传入。

反射

通过类名返回该类的所有信息,如成员变量、方法、命名空间等。

反射类reflectionClass

// 以User类举例
$class = new reflectionClass('User'); // 建立User这个反射类
$user = $class->newInstanceArgs($args) // 获取User类实例

$properties = $class->getProperties(); // 获取User类所有的属性
foreach ($properties as $property) {
    echo $property->getName() . "\n"; // 获取属性名
}
// 获取private 需要传递额外参数如下
ReflectionProperty::IS_STATIC // 静态
ReflectionProperty::IS_PUBLIC // 公共
ReflectionProperty::IS_PROTECTED // 受保护
ReflectionProperty::IS_PRIVATE // 私有
// 还有如下方法
getMethods()       // 来获取到类的所有methods。
hasMethod(string)  // 是否存在某个方法
getMethod(string)  // 获取方法
getConstructor() // 获取构造函数
getParameters() // 获取构造函数的所需参数

代码实现

function make($concrete){

    $reflector = new ReflectionClass($concrete);
    $constructor = $reflector->getConstructor();
    // 为什么这样写的? 主要是递归。比如创建FileLog不需要传入参数。
    if(is_null($constructor)) {
        return $reflector->newInstance();
    }else {
        // 构造函数依赖的参数
        $dependencies = $constructor->getParameters();
        // 根据参数返回实例,如FileLog
        $instances = getDependencies($dependencies);
        return $reflector->newInstanceArgs($instances);
    }

}

function getDependencies($paramters) {
    $dependencies = [];
    foreach ($paramters as $paramter) {
        $dependencies[] = make($paramter->getClass()->name);
    }
    return $dependencies;
}
最后修改:2019 年 09 月 11 日 12 : 06 AM
如果觉得我的文章对你有用,请随意赞赏