• 我们就从获取配置文件开始解析

    ThinkPHP门面源码解析-LMLPHP执行Config::get('facade.');会执行到文件thinkphp/library/think/facade/Config.php中。

    在这个文件中就是之前说的,如果存在getFacadeClass方法就会直接返回对应的别名。

    如果不存在的话就需要使用bind方法来进行门面绑定。

    这里如果不明白就需要去文档好好看看门面那一章节哈!

    ThinkPHP门面源码解析-LMLPHP在上边类中是不存在get方法的,所以就会直接调用thinkphp/library/think/Facade.php文件中的__callStatic方法。

    这个方法就是文章开头就直接说明的,访问不存在的静态的方法时则会调用此方法。

    ThinkPHP门面源码解析-LMLPHP接着就会执行本类中的createFacade这个方法

    在这个方法里边有一行代码是这个样子的$facadeClass = static::getFacadeClass();这段代码会在下文做详细的说明。

    因为在子类中也有同样的方法,在本类中也有同样的方法但是在本类中的方法是没有任何返回值的。

    这时你有没有一丝丝的困惑,这里使用的static到底会执行哪里的方法。或者这样想,为什么会执行子类的方法。

    保留这些疑问将会在下文给你细细的讲来,先来把门面类的源码看完。

    在这个方法中主要看我圈起来的几个地方。

    第一处就是从子类的getFacadeClass方法获取类的别名。

    第二处是当子类没有getFacadeClass方法时,从手动绑定的属性中获取。

    第三处就是之前文章提到的容器了,这里就不对这里做详细说明了,如果不会的点开主页去看之前的文章。

    五、static关键字

    在这里不得不说明一下static这个关键字。

    新学习的伙伴估计只能知道static是用来定义静态变量和静态方法的。

    当然这里不会去给大家说怎么定义静态方法和静态变量,而是说一个非常非常小的细节点。

    先看一个实例,这个实例也是在阅读门面源码时,咔咔根据门面源码改编过来的。

    咔咔这里新建了俩个文件,分别为test和test1。

    test继承test1文件,并且都有同样的方法getKaka。

    test的源码

    test1源码

    ThinkPHP门面源码解析-LMLPHP控制器进行调用

    ThinkPHP门面源码解析-LMLPHP打印结果ThinkPHP门面源码解析-LMLPHP这个时候有没有一点点疑惑,这里怎么打印出来的是147,而不是456呢!

    修改test1的代码,把static改为self

    ThinkPHP门面源码解析-LMLPHP打印结果

    ThinkPHP门面源码解析-LMLPHP使用self的代码相信大家都看的明白,那为什么使用static就出现了有可能不太明白的结果呢!

    此时就是文档开始起作用了,但是当你打开PHP文档会发现,在static这一篇中并没有对这类情况作出说明。

    经过咔咔多次测试和查阅资料,最终总结结果如下。

    static::$test 如果有被继承的话 默认调用子类 ,否则调用的是自身

    self::$test 如果有被继承的话,默认调用本类

    放在本实例中来说明就是,当test继承test1时。

    在test1中使用static调用方法getKaka时,默认调用的是test类中的getKaka,也就是子类的方法。

    在test1中使用self调用方法getKaka时,默认调用的是test1类中的getKaka,也就是本类的方法。

    这个小小的细节也是咔咔无意中发现的,如果有什么不对的地方可以提出来,咔咔作出修改。

    因为在继承这方面还有另外一种情况,咔咔私下会进行测试,在这里就不说明了。

    这里对这个static做出解释主要是为了解释thinkphp/library/think/Facade.php文件中这个行代码。

    因为这行代码调用的方法在子类和父类都存在,所以咔咔为了不让大家出现迷惑就写出来做一个简单的介绍。

    六、总结

    先来一份门面流程图,可以更清晰的看到门面类的具体执行流程。

    ThinkPHP门面源码解析-LMLPHP门面类的源码很是简单,除了几个不太常见的知识点,代码相信都看的明白。

    这里主要是对阅读完门面类后,做一个小总结。

    门面类主要是结合了容器来实现的一个功能,因为需要容器来返回对应的实例,关于容器的文章也已经完成了,如果对容器有不会的可以在文章的开头去看对应的文章即可。

    本文中给大家介绍了门面在容器中如何使用,并且给大家提供了最优的使用方式,这里的最优是咔咔个人见解,因为这种方式咔咔使用了接近俩年了。

    无论从代码的健壮性还是扩展性都是非常实用的。

    再就是关于static关键字,给大家做的一点点冷门知识得补充,当一个类继承一个类时,在父类实用static关键字时,默认调用的子类的方法。

    这里的总结只是针对于本文的实例。

    其实在这里咔咔还想给大家说明一个点就是return call_user_func_array([static::createFacade(), $method], $params);

    因为在以前的用法的哥参数就直接是方法,但是在这里碰到了数组形式,那么这个数组中的俩个值都代表的是什么呢!

    第一个值为实例,第二个值为实例中的方法。

    关于call_user_func_array这个方法的使用咔咔就不去做案例给大家看了,只需要知道它会去执行传入得方法即可。

    到这里关于门面的源码解析就结束了,最重要的还是理解容器,因为门面就是在容器的基础上实现的,这也就是咔咔先写容器在写门面的原因。

    还有就是关于门面的使用咔咔也给出了方案,如你有更好的方案可以在评论区给一个大概的思路。

    以上就是ThinkPHP门面源码解析的详细内容,更多请关注Work网其它相关文章!

    08-27 16:13