php 简单实现依赖注入工厂单例类模式
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");
寻梦xunm
2年前 . LV.0
[secret] 测试一下[/secret]
寻梦xunm
2年前 . LV.0
@寻梦xunm