文章摘要
这篇文章介绍了PHP Laravel中门面(Facade)的实现原理。门面是应用服务容器中绑定的类提供的一种“静态”接口,允许直接通过静态方法调用绑定的类中的方法,无需实例化对象。文章详细解释了门面类继承自`IlluminateSupportFacadesFacade`父类,利用魔术方法`__callStatic`调用内部类的方法。通过`getFacadeAccessor`方法获取服务根名,`resolveFacadeInstance`方法从服务容器中获取对象,并将其缓存在`static::$resolvedInstance`中以避免重复实例化。文章强调了门面机制的便利性和效率,简化了对绑定类的调用流程。
目录环境原理
Laravel 5.4
在Laravel中,门面为应用服务容器中绑定的类提供了一个“静态”接口,使得我们可以不用new这些类出来,就可以直接通过静态接口调用这些类中的方法。
下面我们先看看一个门面类是怎么定义的:
<?php
namespace App\Facades;
use Illuminate\Support\Facades\Facade;
class Player extends Facade
{
protected static function getFacadeAccessor() {
return ‘player’;
}
}
门面类都继承自Illuminate\Support\Facades\Facade父类,这个父类中有一个魔术方法:
public static function __callStatic($method, $args)
{
$instance=static::getFacadeRoot();
if (! $instance) {
throw new RuntimeException(‘A facade root has not been set.’);
}
return $instance->$method(…$args);
}
当我们静态调用一个不存在的方法时,例如Player::playOneSong(),这个魔术方法就会被调用。它通过getFacadeRoot()方法创建出一个对象,然后在这个对象上真正执行我们的方法。
再看看getFacadeRoot()方法:
public static function getFacadeRoot()
{
return static::resolveFacadeInstance(static::getFacadeAccessor());
}
这里通过我们自定义门面类中的getFacadeAccessor方法,获取到一个service_id(暂且这么叫吧),然后传给resolveFacadeInstance方法。
再往下看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];
}
通过static::$app[$name]从服务容器中获取 key 为name的对象,服务容器会帮我们实例化出对应的对象(前提是已经绑定好)。
服务容器$app是一个对象,但它实现了ArrayAccess接口,所以可以用这种数组的方式访问。
获取到对象后,放入到static::$resolvedInstance静态变量中,这样下次再获取相同对象时,就不用重复实例化了。
到此这篇关于PHP Laravel门面的实现原理详解的文章就介绍到这了,更多相关PHP Laravel门面内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
您可能感兴趣的文章:PHP Laravel框架缓存操作介绍PHP Laravel软删除的实现方法介绍PHP Laravel框架异步执行的实现详解PHP laravel使用自定义邮件类实现发送邮件PHP发送邮件确认验证注册功能示例【修改别人邮件类】详解PHP发送邮件知识点PHP使用laravel邮件服务发送邮件