大家好,今天带来的内容是 Laravel 的 Facade 机制实现原理。
Facade的简单使用
数据库的使用:
$users = DB::connection(\'foo\')->select(...);
IOC容器
众所周知,IOC容器是 Laravel 框架的最最重要的部分。它提供了两个功能,IOC和容器。
- IOC(Inversion of Control),也叫控制反转。说白了,就是控制对象的生成,使开发者不用关心对象的如何生成,只需要关心它的使用即可。
- 而通过IOC机制生成的对象实例需要一个存放的位置,以便之后继续使用,便是它的容器功能。
这次不准备讲解IOC容器的具体实现,之后会有文章详细解读它。关于IOC容器,读者只需要记住两点即可:
- 根据配置生成对象实例;
- 保存对象实例,方便随时取用;
简化后 Facade 类
<?php
namespace facades;
abstract class Facade
{
protected static $app;
/**
* Set the application instance.
*
* @param \\Illuminate\\Contracts\\Foundation\\Application $app
* @return void
*/
public static function setFacadeApplication($app)
{
static::$app = $app;
}
/**
* Get the registered name of the component.
*
* @return string
*
* @throws \\RuntimeException
*/
protected static function getFacadeAccessor()
{
throw new RuntimeException(\'Facade does not implement getFacadeAccessor method.\');
}
/**
* Get the root behind the facade.
*
* @return mixed
*/
public static function getFacadeRoot()
{
return static::resolveFacadeInstance(static::getFacadeAccessor());
}
/**
* Resolve the facade root instance from the container.
*
* @param string| $name
* @return mixed
*/
protected static function resolveFacadeInstance($name)
{
return static::$app->instances[$name];
}
public static function __callStatic($method, $args)
{
$instance = static::getFacadeRoot();
if (! $instance) {
throw new RuntimeException(\'A facade root has not been set.\');
}
switch (count($args)) {
case 0:
return $instance->$method();
case 1:
return $instance->$method($args[0]);
case 2:
return $instance->$method($args[0], $args[1]);
case 3:
return $instance->$method($args[0], $args[1], $args[2]);
case 4:
return $instance->$method($args[0], $args[1], $args[2], $args[3]);
default:
return call_user_func_array([$instance, $method], $args);
}
}
}
代码说明:
- $app中存放的就是一个IOC容器实例,它是在框架初始化时,通过 setFacadeApplication() 这个静态方法设置的
- 它实现了 __callStatic 魔术方法
- getFacadeAccessor() 方法需要子类去继承,返回一个string的标识,通过这个标识,IOC容器便能返回它所绑定类(框架初始化或其它时刻绑定)的对象
- 通过 $instance 调用具体的方法
创建自己的Facade:
TEST1 的具体逻辑:
<?php
class Test1
{
public function hello()
{
print(\"hello world\");
}
}
TEST1 类的Facade:
<?php
namespace facades;
/**
* Class Test1
* @package facades
*
* @method static setOverRecommendInfo [设置播放完毕时的回调函数]
* @method static setHandlerP [明确指定下一首时的执行类]
*/
class Test1Facade extends Facade
{
protected static function getFacadeAccessor()
{
return \'test1\';
}
}
使用:
use facades\\Test1Facade;
Test1Facade::hello(); // 这是 Facade 调用
解释:
- facades\\Test1Facade 调用静态方法 hello() 时,由于没有定义此方法,会调用 __callStatic;
- 在 __callStatic 中,首先是获取对应的实例,即
return static::$app->instances[$name];。这其中的$name,即为facades\\Test1里的 test1 - $app, 即为 IOC 容器,类的实例化过程,就交由它来处理。
继续阅读与本文标签相同的文章
-
登榜!风采依旧表现“佳”
2026-05-18栏目: 教程
-
苹果新获专利详细介绍了Measure如何利用AR进行精确视觉测量
2026-05-18栏目: 教程
-
消费升级不是把原来的成熟产品卖得更高更贵
2026-05-18栏目: 教程
-
红旗首款纯电SUV登场!动力强续航足,这外观太漂亮!
2026-05-18栏目: 教程
-
互联网时代,挑战与机遇并存
2026-05-18栏目: 教程
