Container /** * 容器 * Class Container * @Auth: kingofzihua */class Container{ /** * 所有的绑定的类和实例 * @Auth: kingofzihua * @var array */ protected $bindings = []; /** * 绑定容器 * @Auth: kingofzihua * @param $abstract 抽
/** * 容器 * Class Container * @Auth: kingofzihua */ class Container { /** * 所有的绑定的类和实例 * @Auth: kingofzihua * @var array */ protected $bindings = []; /** * 绑定容器 * @Auth: kingofzihua * @param $abstract 抽象类 * @param null $concrete 实际的类 * @param bool $shared */ public function bind($abstract, $concrete = null, $shared = false) { if (!$concrete instanceof Closure) { $concrete = $this->getClosure($abstract, $concrete); } $this->bindings[$abstract] = compact('concrete', 'shared'); } /** * 获取闭包函数 * @Auth: kingofzihua * @param $abstract * @param $concrete * @return Closure */ public function getClosure($abstract, $concrete) { return function ($c, $parameters = []) use ($abstract, $concrete) { $method = ($abstract == $concrete) ? 'build' : 'make'; return $c->$method($concrete, $parameters); }; } /** * 取出指定的类[实例化指定的类] * @Auth: kingofzihua * @param $abstract * @param array $parameters * @return mixed|object|string */ public function make($abstract, $parameters = []) { $concrete = $this->getConcrete($abstract); //取出 if ($this->isBuildable($concrete, $abstract)) { //判断是否是可以 实例化的 $object = $this->build($concrete, $parameters); //构造 } else { $object = $this->make($concrete, $parameters); } return $object; } /** * 判断是否可以实例化 * @Auth: kingofzihua * @param $concrete * @param $abstract * @return bool */ protected function isBuildable($concrete, $abstract) { return $concrete === $abstract || $concrete instanceof Closure; } /** * 通过接口类获取类的实例 * @Auth: kingofzihua * @param $abstract * @return mixed */ protected function getConcrete($abstract) { if (!isset($this->bindings[$abstract])) { return $abstract; } return $this->bindings[$abstract]['concrete']; } /** * 构建类 * @desc 实例化指定的类 依赖注入 * @Auth: kingofzihua * @param $concrete * @param array $parameters * @return mixed|object|string */ public function build($concrete, $parameters = []) { if ($concrete instanceof Closure) { //如果是闭包函数 那么调用当前闭包 返回 绑定的类名 return $concrete($this, $parameters); } $reflector = new ReflectionClass($concrete); //反射获取类 Message if (!$reflector->isInstantiable()) { //判断是否是可以实例化的 return $message = "Target [$concrete] is not instantiable."; } $constructor = $reflector->getConstructor(); //获取构造方法 if (is_null($constructor)) { //如果没有构造方法 直接返回实例化的对象 return new $concrete; } $dependencies = $constructor->getParameters(); //获取构造方法的参数 $instances = $this->getDependencies($dependencies, $parameters); //获取实例 return $reflector->newInstanceArgs($instances); } /** * 获取依赖注入的类 * @Auth: kingofzihua * @param $parameters 构造方法的 所需要的 * @param array $primitives 额外参数 * @return array */ protected function getDependencies($parameters, array $primitives = []) { foreach ($parameters as $parameter) { $dependency = $parameter->getClass(); if (array_key_exists($parameter->name, $primitives)) { $dependencies[] = $primitives[$parameter->name]; } else if (is_null($dependency)) { // $dependencies[] = NULL; } else { $dependencies[] = $this->resolveClass($parameter); } } return (array)$dependencies; } /** * 获取类的实例 * @Auth: kingofzihua * @param ReflectionParameter $parameter * @return mixed|object|string */ protected function resolveClass(ReflectionParameter $parameter) { return $this->make($parameter->getClass()->name); } }sendMessage
/** * 通知 * @Auth: kingofzihua * Interface Notify */ interface Notify { /** * 发送通知 * @Auth: kingofzihua * @return mixed */ public function send(); } /** * 短信 * Class SMS * @Auth: kingofzihua */ class SMS implements Notify { /** * 发送通知 * @Auth: kingofzihua * @return mixed */ public function send() { echo 'SMS send'; } } /** * Mail * Class SMS * @Auth: kingofzihua */ class Mail implements Notify { /** * 发送通知 * @Auth: kingofzihua * @return mixed */ public function send() { echo 'Mail send'; } } /** * 发送 * Class Push * @Auth: kingofzihua */ class Push implements Notify { /** * 发送 * @Auth: kingofzihua */ public function send() { echo 'Push send'; } } /** * 消息 * Class Message * @Auth: kingofzihua */ class Message { /** * @Auth: kingofzihua * @var Notify */ protected $notifyTool; /** * @Auth: kingofzihua * @var array */ protected $config; /** * @Auth: kingofzihua * Message constructor. * @param Notify $notify * @param array $parameters */ public function __construct(Notify $notify, $parameters = []) { $this->notifyTool = $notify; $this->config = $parameters; } /** * 发送消息 * @Auth: kingofzihua */ public function sendMessage() { dump($this->notifyTool); $this->notifyTool->send(); } } $app = new Container(); $app->bind('Notify', 'Sms'); $app->bind('message', 'Message'); $msg = $app->make('message', ['parameters' => '额外参数']); $msg->sendMessage(); die();