企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
## 安装[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` 对应。