Laravel 门面类:Facade简记
2017-07-06 14:43
429 查看
这是另一位大哥写的,感觉写的很好,在此感谢他的分享。这位大哥的这篇文章详细介绍了原理,但是感觉初次看的人可能需要下面这个前期知识储备:
static:: 静态延迟绑定
还有一点就是我的实际代码和他的有点不同,这里再贴一下实际的源码,顺道也再整理一下思路:
这里拿
当我们外部这样调用时:
时,根据服务容器的自动依赖注入,(Facade类是App类的抽象类):
会自动调用到
其中的
接下来再看
其实简单点来说就是返回该
static:: 静态延迟绑定
还有一点就是我的实际代码和他的有点不同,这里再贴一下实际的源码,顺道也再整理一下思路:
这里拿
vendor/laravel/framework/src/Illuminate/Support/Facades/App.php为例进行介绍:
<?php namespace Illuminate\Support\Facades; /** * 这里顺道记录一个小技巧,在函数前写这样的注释,会被PHPSrorm解析,表示该类所拥有的方法 * @method static string version() * @method static string basePath() * @method static string environment() * @method static bool isDownForMaintenance() * @method static void registerConfiguredProviders() * @method static \Illuminate\Support\ServiceProvider register(\Illuminate\Support\ServiceProvider|string $provider, array $options = [], bool $force = false) * @method static void registerDeferredProvider(string $provider, string $service = null) * @method static void boot() * @method static void booting(mixed $callback) * @method static void booted(mixed $callback) * @method static string getCachedServicesPath() * * @see \Illuminate\Foundation\Application */ class App extends Facade { /** * Get the registered name of the component. * * @return string */ protected static function getFacadeAccessor() { return 'app'; } }
当我们外部这样调用时:
use App; /App:make('app');
时,根据服务容器的自动依赖注入,(Facade类是App类的抽象类):
<?php namespace Illuminate\Support\Facades; use Mockery; use RuntimeException; use Mockery\MockInterface; abstract class Facade{ //先省略其中的代码 }
会自动调用到
App类,接着就是解释如何像调用静态方法一样调用
App类中的方法了,根据那位大哥的解释,当我们调用
getFacadeAccessor()方法时,在
Facades中并没有该静态方法,那么就会调用PHP的魔术方法:
__callStatic($method,$args),下面来看其源码:
public static function __callStatic($method, $args) { $instance = static::getFacadeRoot(); //先到这里,下面讲解 static::getFacadeRoot() 这个函数 if (! $instance) { throw new RuntimeException('A facade root has not been set.'); } return $instance->$method(...$args); }
其中的
getFacadeRoot方法如下:
public static function getFacadeRoot() { //注意,最开始时我们的 getFacadeAccessor() 的返回值是 "app" return static::resolveFacadeInstance(static::getFacadeAccessor()); }
接下来再看
resolveFacadeInstance
protected static function resolveFacadeInstance($name) { //如果传入的参数是对象的话,则返回该对象 if (is_object($name)) { return $name; } //如果该类是在项目加载完成后就自动装载的,则返回该类 if (isset(static::$resolvedInstance[$name])) { return static::$resolvedInstance[$name]; } //如果没有,就到服务容器中去找 return static::$resolvedInstance[$name] = static::$app[$name]; }
其实简单点来说就是返回该
$name的实例,接着回到最开始的
__callStatic函数的剩余部分:
//如果经过上面的`resolveFacadeInstance`函数没有办法获取该类实例的话,那么接下来肯定无法正常运行了,所以这里抛出异常 if (! $instance) { throw new RuntimeException('A facade root has not been set.'); } //就是在这里调用了该类下面的方法,...$args表示该方法可能存在输入参数,可能不存在 return $instance->$method(...$args);
相关文章推荐
- PHP重载以及Laravel门面Facade
- 门面(Facade)模式
- PureMVC学习系列-从源码深度剖析PureMVC(从PureMVC中看设计模式-Facade门面模式)
- 讲故事学设计模式-门面(Facade)模式
- 设计模式学习笔记(二):门面模式【Facade】(一) 问题的提出
- 设计模式C++学习笔记之六(Facade门面模式)
- 《Laravel5.2学习笔记---数据库操作之DB-facade》
- 门面模式(Facade)----结构笔记
- 结构型模式之门面模式(Facade)
- 您的设计模式——门面模式【Facade Pattern】
- 设计模式(七)门面模式(Facade)-结构型
- java设计模式-门面模式Facade
- 门面模式/Facade
- 设计模式学习笔记(二):门面模式【Facade】(二) 问题的改进
- PHP设计模式:结构型之门面(facade)
- Laravel - DB - facade实现CURD
- 门面模式(Facade)----结构笔记
- 门面模式(Facade Pattern)
- 门面模式(Facade Pattern)
- 设计模式C++学习笔记之六(Facade门面模式)