tp给我们提供啦一个容器的概念,用来储存我们生产的类实例。在下次需要使用类实例时可以快速获取。
那app()助手函数是如何工作的:
通过查看助手文件得到他其实调用的是:Container::get()方法。
function app($name = 'think\App', $args = [], $newInstance = false)
{
return Container::get($name, $args, $newInstance);
}我们在去看Container::get()方法。
public static function get($abstract, $vars = [], $newInstance = false)
{
//通过getInstance方法创建一个当前容器的实例(单例模式)再去调用make()方法
return static::getInstance()->make($abstract, $vars, $newInstance);
} 我们来看make()方法:这个方法很重要,门面其实也是通过这个方法来创建对象。
public function make($abstract, $vars = [], $newInstance = false)
{
if (true === $vars) {
// 总是创建新的实例化对象
$newInstance = true;
$vars = [];
}
static $i = 0;
$abstract = isset($this->name[$abstract]) ? $this->name[$abstract] : $abstract;
//通过容器获取类的对象
if (isset($this->instances[$abstract]) && !$newInstance) {
// echo '容器中'.$i++.'<br>';
return $this->instances[$abstract];
}
//通过反射创建类的对象
if (isset($this->bind[$abstract])) {
$concrete = $this->bind[$abstract];
if ($concrete instanceof Closure) {
$object = $this->invokeFunction($concrete, $vars);
echo '反射'.$i++.PHP_EOL;
} else {
$this->name[$abstract] = $concrete;
return $this->make($concrete, $vars, $newInstance);
}
} else {
echo '反射'.$i++.PHP_EOL;
$object = $this->invokeClass($abstract, $vars);
}
if (!$newInstance) {
$this->instances[$abstract] = $object;
}
return $object;
}我为了证明app()在调用的时候是通过容器来获取对象的还是通过反射来获取对象的,在这个类中定义了一个:static $i = 0;和echo '反射'.$i++.PHP_EOL;来输出调用的方法和次数。方便观察。
当我的方法为空时:

输出为:

为什么会使出 17次的放射呢?
因为在框架初始化的时候会来获取一些默认的类对象(大概是这个意思)。所以这前17次输出都和我们没有关系。
现在我在方法里调用一次我自己定义的一个类文件。

再看输出
![1594693375570232.png 50T]]L@V{OB5V_25(%IS)EG.png](https://img.php.cn/upload/image/777/924/330/1594693375570232.png)
这是输出多啦一次 ‘反射’这说明当我们通过app()来获取一个我们未向容器注册过的类的时候,他会通过我们提供的命名空间,用反射来创建这个类的对象。
当我们调用两次app()来获取相同的类对象时:
public function lize(){
// bind('Redis',new \Redis);
$redis = app('Redis');
$redis = app('Redis');
}再看输出:
并没有多输出一次‘反射’,这说明我们第二次调用的时候并没有通过反射来获取类对象。而是做的容器。
总结:
当我们通过app()来获取一个类对象时,先会在容器里获取,获取不到去通过反射来获取。反射获取对象成功后,在吧这个对象放到容器里。下次获取的时候直接去容器里获取。(去不去容器里获取还可以通过,app()的第二个参数来决定,当为true时就不会走容器,不管容器里有没有。)
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号