目录
1、使用容器实现框架加载类运行
2、 创建框架容器类core/fm/Di.php
什么是容器?容器就相当于盒子,把很多类放里面,重复利用,防止多次实例化,节约资源等
<?php
namespace fm;
use ArrayAccess;
class Di implements ArrayAccess{
protected static $instance;
protected $instances = [];//已实例化类
protected $bind=[
'core'=>core::class,
];//服务列表
//单例模式 防止多次new
public static function getInstance(){
if(self::$instance){
return self::$instance;
}
static::$instance = new static;
return static::$instance ;
}
//获取实例化类
public static function get($abstract, $vars = []){
return static::getInstance()->make($abstract, $vars = []);
}
//获取类库
public function make($abstract, $vars = []){
//先从已经实例化的列表中查找
if (isset($this->instances[$abstract])) {
return $this->instances[$abstract];
}
//检测有没有注册该服务
if(!isset($this->bind[$abstract])){
return null;
}
$concrete = $this->bind[$abstract];//对象具体注册内容
$obj = null;
//匿名函数方式
if($concrete instanceof \Closure){
$obj = call_user_func_array($concrete,$vars);
}elseif(is_string($concrete)){//字符串方式
if(empty($vars)){
$obj = new $concrete;
}else{
//带参数的类实例化,使用反射
$class = new \ReflectionClass($concrete);
$obj = $class->newInstanceArgs($vars);
}
}
return $obj;
}
public function bindTo($abstract, $concrete = null)
{
if (is_array($abstract)) {
$this->bind = array_merge($this->bind, $abstract);
} elseif ($concrete instanceof Closure) {
$this->bind[$abstract] = $concrete;
} elseif (is_object($concrete)) {
if (isset($this->bind[$abstract])) {
$abstract = $this->bind[$abstract];
}
$this->instances[$abstract] = $concrete;
} else {
$this->bind[$abstract] = $concrete;
}
return $this;
}
//检测是否已经绑定
public function has($abstract){
return isset($this->bind[$abstract]) || isset($this->instances[$abstract]);
}
//卸载服务
public function remove($abstract){
return static::getInstance()->delete($abstract);
}
public function delete($abstract)
{
unset($this->instances[$abstract]);
}
//继承接口必要继承方法
public function offsetExists($offset) {
return $this->has($offset);
}
public function offsetGet($offset) {
return $this->make($offset);
}
public function offsetSet($offset, $value) {
$this->bindTo($offset, $value);
}
public function offsetUnset($offset) {
return $this->remove($offset);
}
public function getIterator() {
return new ArrayIterator($this->instances);
}
public function count() {
return count($this->instances);
}
}
3、框架使用容器类来执行public/index.php
<?php
namespace fm;
error_reporting(E_ALL);
ini_set('display_errors', 'On');
// 加载基础文件
require __DIR__ . '/../core/base.php';
Di::get('core')->run();