本人开发的框架在2021年年初开发完成,后面没有再做过任何维护和修改。是仅供大家参考交流的学习项目,请勿使用在生产环境,也勿用作商业用途。
框架地址:
https://github.com/yijiebaiyi/fast_framework
首先我们先了解概念。框架中的容器指的是什么?什么是依赖注入?
容器(当前所指)是一个用于管理和存储应用程序中各种对象的工具。它允许你注册、创建和解析对象,以及管理它们之间的依赖关系。当前框架中的容器通常使用关联数组来存储对象和服务。
依赖注入是一种设计模式,它允许你将一个对象的依赖关系传递给它,而不是在对象内部直接创建或管理依赖关系。
这可以使代码更加可测试、可维护和可扩展,因为它将对象的依赖性解耦,并使它们更容易替换和修改。
依赖注入通常通过构造函数注入、方法注入或属性注入来实现。
在当前框架中,依赖注入和容器一起使用,容器负责实例化和解析对象,并自动注入它们的依赖关系。
那么如何实现呢?通过php的反射,来获取类的相关信息来解决依赖。
我们从容器中拿一个服务对象,如果没有拿到,则需要创建。创建的时候通过下面几步我们来解决依赖。
$reflection = new \ReflectionClass($className)
$reflection->getConstructor()
$constructorParameters = $constructor->getParameters()
foreach ($constructorParameters as $param) {
if (version_compare(PHP_VERSION, '5.6.0', '>=') && $param->isVariadic()) {
break;
} elseif ($param->isDefaultValueAvailable()) {
$dependencies[] = $param->getDefaultValue();
} else {
$c = $param->getClass();
$dependencies[] = $this->get($c->getName(), $this->_params[$c->getName()] ?? []);
}
}
注:请避免出现循环嵌套,否则会出现未知问题
创建的完整代码:
public function build(string $className, array $params = []): ?object
{
if (isset($this->_reflections[$className])) {
$reflection = $this->_reflections[$className];
} else {
try {
$reflection = new \ReflectionClass($className);
} catch (ReflectionException $exception) {
throw new Exception("Failed to reflect class " . $className . ", error: " . $exception->getMessage());
}
$this->_reflections[$className] = $reflection;
}
if (!$reflection->isInstantiable()) {
throw new Exception("Is not instantiable:" . $reflection->name);
}
$dependencies = [];
$constructor = $reflection->getConstructor();
if ($constructor !== null) {
$constructorParameters = $constructor->getParameters();
foreach ($constructorParameters as $param) {
if (version_compare(PHP_VERSION, '5.6.0', '>=') && $param->isVariadic()) {
break;
} elseif ($param->isDefaultValueAvailable()) {
$dependencies[] = $param->getDefaultValue();
} else {
$c = $param->getClass();
$dependencies[] = $this->get($c->getName(), $this->_params[$c->getName()] ?? []);
}
}
}
$this->_dependencies[$className] = Arr::arrayMergeBase($dependencies, $params);
$object = $reflection->newInstanceArgs($this->_dependencies[$className]);
$this->_objects[$className] = $object;
return $object;
}
}
解决完依赖,我们就把改服务存入容器中。
业务层调用:
$container = new Container();
$container->set("app\service\Group", [123]);
$container->set("app\service\User");
$container->set("app\service\UserList");
$group = $container->get("app\service\Group");
$userList = $container->get("app\service\UserList");
$group->getA();
$userList->getUserList();
Group.php:
User.php:
UserList.php:
至此,这款简易的php框架的实现过程就介绍完了。更多详细的内容请异步:
https://github.com/yijiebaiyi/fast_framework
这里有详细的代码示例和完整的实现过程。