## 安裝[PSR-11 容器接口]
`composer require psr/container`

安裝完成可以看到 `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');
```

## 關于此容器
看這些文章就可以解釋了:
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