## 安装[PSR-11 容器接口]
`composer require psr/container`
![](https://img.kancloud.cn/a9/58/a958c45e8c7f6af10efe3fe8372c19f2_686x218.png)
安装完成可以看到 `vendor` 有 `psr/container`。
## 编辑app.php
```
<?php
define('FRAME_BASE_PATH', __DIR__); // 框架目录
define('FRAME_START_TIME', microtime(true)); // 开始时间
define('FRAME_START_MEMORY',memory_get_usage()); // 开始内存
class App implements Psr\Container\ContainerInterface {
public $binding = []; // 绑定关系
private static $instance; // 这个类的实例
protected $instances = []; // 所有实例的存放
private function __construct()
{
self::$instance = $this; // App类的实例
$this->register(); // 注册绑定
$this->boot(); // 服务注册了 才能启动
}
public function get($abstract)
{
if( isset($this->instances[$abstract])) // 此服务已经实例化过了
return $this->instances[$abstract];
$instance = $this->binding[$abstract]['concrete']($this); // 因为服务是闭包 加()就可以执行了
if( $this->binding[$abstract]['is_singleton']) // 设置为单例
$this->instances[$abstract] = $instance;
return $instance;
}
// 是否有此服务
public function has($id)
{
}
// 当前的App实例 单例
public static function getContainer()
{
return self::$instance ?? self::$instance = new self();
}
/**
*@param string $abstract 就是key
*@param void|string $concrete 就是value
*@param boolean $is_singleton 这个服务要不要变成单例
*/
public function bind($abstract, $concrete,$is_singleton = false)
{
if(! $concrete instanceof \Closure) // 如果具体实现不是闭包 那就生成闭包
$concrete = function ($app) use ($concrete) {
return $app->build($concrete);
};
$this->binding[$abstract] = compact('concrete','is_singleton'); // 存到$binding大数组里面
}
protected function getDependencies($paramters) {
$dependencies = []; // 当前类的所有依赖
foreach ($paramters as $paramter)
if( $paramter->getClass())
$dependencies[] = $this->get($paramter->getClass()->name);
return $dependencies;
}
// 解析依赖
public function build($concrete) {
$reflector = new ReflectionClass($concrete); // 反射
$constructor = $reflector->getConstructor(); // 获取构造函数
if( is_null($constructor))
return $reflector->newInstance(); // 没有构造函数? 那就是没有依赖 直接返回实例
$dependencies = $constructor->getParameters(); // 获取构造函数的参数
$instances = $this->getDependencies($dependencies); // 当前类的所有实例化的依赖
return $reflector->newInstanceArgs($instances); // 跟new 类($instances); 一样了
}
protected function register()
{
}
protected function boot()
{
}
}
```
## 编辑index.php
```
<?php
require __DIR__.'/../vendor/autoload.php';
require_once __DIR__.'/../app.php';
App::getContainer()->bind('str',function (){
return 'hello str';
});
echo App::getContainer()->get('str');
```
![](https://img.kancloud.cn/0e/24/0e24ae3d97ab7c9ba992093eaa7b0112_352x40.png)
## 关于此容器
看这些文章就可以解释了:
1. [注册树模式](https://learnku.com/docs/study-php-design-patterns/1.0/registration-tree-mode/8074)
2. [# 如何实现Ioc容器和服务提供者是什么概念](https://learnku.com/docs/laravel-core-concept/5.5/Ioc%E5%AE%B9%E5%99%A8,%E6%9C%8D%E5%8A%A1%E6%8F%90%E4%BE%9B%E8%80%85/3019) (很推荐看这个 看懂这个 本教程的容器你也懂了)
容器就是一个 [注册树模式](https://learnku.com/docs/study-php-design-patterns/1.0/registration-tree-mode/8074)
`注册树` 就是一个大数组, 数组嘛 就是 `key` 和 `value` 对应。
- 前言
- 基础篇
- 1. 第一步 创建框架目录结构
- 2. 引入composer自动加载
- 3. php自动加载 (解释篇)
- 4. 创建容器 注册树模式
- 5. 关于psr规范解释
- 6. 关于"容器" "契约" "依赖注入" (解释篇)
- 7. 添加函数文件helpers.php
- 8. 初始化请求(Request)
- 9. 响应 (Response)
- 10. 路由一 (路由组实现)
- 11. 路由二 (加入中间件)
- 12. 配置信息 (类似laravel)
- 13. 数据库连接 (多例模式)
- 14. 查询构造器 (query builder)
- MVC实现
- M 模型实现 (数据映射 + 原型 模式)
- C 控制器实现 + 控制器中间件
- V 视图实现 (Laravel Blade 引擎)
- V 视图切换成 ThinkPhp 模板 引擎)
- 其他轮子
- 日志
- 自定义异常 (异常托管)
- 单元测试 (phpunit)
- 替换成swoole的http服务器
- 协程上下文解决request问题
- qps测试
- 发布到packagist.org