php 简单实现依赖注入工厂单例类模式

PHP代码
124 2

请输入图片描述

第一步

随便创建一个php文件,把下面的代码复制到文件中保存。(重新修订版,添加支持单例模式类调用)

<?php

//命名空间声明(该类是在xm文件夹里面)(由于命名空间导致闭包无法获取)
//namespace xm;

/*
 单一工厂和依赖注入类(注意要想法实现单实例模式需要在类定义一个指定方法在进行具体;实现
 作用于类的实例化出来防止重复实例化和和各个类的依赖注入
*/

class gc{

//声明一个受保护的静态变量存储对象信息
protected static $object =[];

//存储类的依赖关系
public static $yilai = [];

/*
//创建一个静态方法

必须为字符串 $nm给要实例化的类取一个外号(例如:yyds)

$ys 类实例化的具体对象或者路径(可以使用闭包或者直接类的路径)
必须为字符串 $a 用于强制切换到单例模式
必须为数组 $c 为需要手动传入的值

*/
public static function run($nm, $ys, string $a= null,array $b=[]){

//对参数进行过滤
$nm = self::jian($nm);

//判断变量是否为空值
if (!empty($nm)){

if (!empty($ys)){

if ($a === null){
    
// 如果是匿名函数(Anonymous functions),也叫闭包函数(closures)
if ($ys instanceof Closure) {
    
      $ys=$ys(new self());
      
       self::bind($nm,$ys);
          
} else{

// 构造函数参数
$constructorParams = [];

// 反射类
$reflector = new \ReflectionClass($ys);
        
   // 检查类是否可实例化, 排除抽象类abstract和对象接口interfac
    if (!$reflector->isInstantiable()){
        
        return false;
        
    }


        // 是否需要处理构造函数
        if ($reflector->getConstructor()) {
            
            // 构造函数参数
            $params = $reflector->getConstructor()->getParameters();
            
            if (!empty($params)) {
                
                foreach ($params as $param) {
                    
                    //var_dump($param->getType()->getName());
                    // 反射参数类
                    $paramReflector = new \ReflectionClass($param->getType()->getName());
                    
                    // 参数类名
                    $paramClass = $paramReflector->name;
                    //var_dump(self::run($paramClass,$paramClass));
                    // 递归实例化参数
                    self::run($paramClass,$paramClass);
                    $constructorParams[] = self::get($paramClass);
                }
                
            }
            
        }
        //var_dump($constructorParams);
        if (!empty($constructorParams)) {
            
            //判断类是的定义
            if(class_exists($ys)){
  
            $obje = new $ys(...$constructorParams);
          
            
            self::bind($nm,$obje);
            
            }
            
        }else{
        
         //判断类是否定义
         if(class_exists($ys)){
             
        $object = new $ys();
        
        self::bind($nm,$object);
        
        }
        
        }
}


}else{

//判断类是否定义
if(class_exists($ys)){
   //这里就是对单例模式类进行调用处理      
  $object =  $ys::$a(...$b);
        
   self::bind($nm,$object);
        
}

}


}else{

echo exit("参数都不写,你要我怎么办?");

}

}else{

echo exit("怎么懒得连外号都不写一个");

}

}

/*
获取数组中的对象信息
必须为字符串 $gc 注册树中外号名
必须为布尔值 $bibao 判断获取的对象信息是否为//
*/
public static function get(string $gc){
    
//var_dump(self::$object);

//检查数组中是否存在该键名
if (array_key_exists($gc , self::$object)){

$nm= self::$object[$gc];

//判断注册树取到的结果是否为闭包

    
return $nm;



}else{

return false;

}

}

//删除一个对象信息
public static function del(string $gc){

//检查数组是否存在该键
if (array_key_exists($gc , self::$object)){

//写入日志
XLOG("删除数组".$gc."中对象信息");

unset(self::$object[$gc]);

return true;

}else{

return false;

}

}

//绑定数据到注册树中
protected static function bind($class, $closure_obj){
        
        self::$object[$class] = $closure_obj;
        
 }


//安全参数过滤
protected static function jian($name){
//var_dump($name);
//检查类外号名称是否为字母
if (STR(str_replace('\\','', $name)) == false){

//写入日志
    XLOG($name."参数不符合要求");
    
    echo exit($name."参数不符合要求");
  
  }else{
  
//进行参数过滤
$name= A($name,'xss');

//转义字符
$name =htmlspecialchars($name);

return $name;


}

}

}

第二步

也是随便创建一个php文件,复制下面的代码进行保存,在引入第一步创建的php文件



    class ffff{
 function hhh($rr){
echo $rr."是你爸爸";
}
}    
    
    
class Person
{

public function __construct(ffff $person)
    {
        echo $person->hhh('rrrrr乎学rr');
    }
    
 function hhh($rr){
echo $rr."是你爷爷";
}

}
 
class Student
{
    public function __construct(Person $Person)
    {
       return $Person;
    }
    function hoh($rr){
        echo $rr."是你爷爷";
    }
}

gc::run("c\c\urld",Student::class);

gc::get("c\c\urld")->hoh("6666");

最后更新 2022-05-11
评论 ( 2 )
OωO
隐私评论
  1. 哎呦喂,瞧给你聪明的!
    此条为私密评论,仅评论双方可见
    22天前回复