“在之前的文章中我们简单的梳理了一下容器类,接下来就是对其中一个细节进行深度分析。 ” Container实例调用make方法 本文没有太多文字解析,都在代码注释中说明了执行过程。 代码static::getInstance() 返回了Container的实例后,就会去调用本类的make方法,接下来就是对make方法进行详解了。 在开始阅读make方法里边的源码之前,我们需要先对几个属性进行简单的梳理一下。
这四个属性一定要有点印象,并且一定要区别instance和instances。 这俩个属性一个是单例模式返回当前类的实例,一个是容器中的所有的实例。 第一次执行结果
public function make($abstract, $vars = [], $newInstance = false) { if (true === $vars) { $newInstance = true; $vars = []; }
$abstract = isset($this->name[$abstract]) ? $this->name[$abstract] : $abstract; if (isset($this->instances[$abstract]) && !$newInstance) { return $this->instances[$abstract]; }
if (isset($this->bind[$abstract])) { $concrete = $this->bind[$abstract]; if ($concrete instanceof Closure) { $object = $this->invokeFunction($concrete, $vars); } else { $this->name[$abstract] = $concrete; return $this->make($concrete, $vars, $newInstance); } } else { $object = $this->invokeClass($abstract, $vars); }
if (!$newInstance) { $this->instances[$abstract] = $object; }
return $object; }
这是第二次执行流程 public function make($abstract, $vars = [], $newInstance = false) { if (true === $vars) { $newInstance = true; $vars = []; }
$abstract = isset($this->name[$abstract]) ? $this->name[$abstract] : $abstract;
if (isset($this->instances[$abstract]) && !$newInstance) { return $this->instances[$abstract]; }
if (isset($this->bind[$abstract])) { $concrete = $this->bind[$abstract]; if ($concrete instanceof Closure) { $object = $this->invokeFunction($concrete, $vars); } else { $this->name[$abstract] = $concrete; return $this->make($concrete, $vars, $newInstance); } } else { $object = $this->invokeClass($abstract, $vars); }
if (!$newInstance) { $this->instances[$abstract] = $object; }
return $object; }
public function invokeClass($class, $vars = []) { try {
$reflect = new ReflectionClass($class);
if ($reflect->hasMethod('__make')) { $method = new ReflectionMethod($class, '__make');
if ($method->isPublic() && $method->isStatic()) { $args = $this->bindParams($method, $vars); return $method->invokeArgs(null, $args); } } $constructor = $reflect->getConstructor();
$args = $constructor ? $this->bindParams($constructor, $vars) : []; return $reflect->newInstanceArgs($args);
} catch (ReflectionException $e) { throw new ClassNotFoundException('class not exists: ' . $class, $class); } }
执行流程图 既然把代码都理清楚了,这时来理一下执行的流程图可以看的更清晰。  “坚持学习、坚持写博、坚持分享是咔咔从业以来一直所秉持的信念。希望在偌大互联网中咔咔的文章能带给你一丝丝帮助。我是咔咔,下期见。 ” 以上就是ThinkPHP容器之容器是如何返回实例的的详细内容,更多请关注模板之家(www.mb5.com.cn)其它相关文章! |