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();
