[PHP] PHP Laravel门面的实现原理详解

2405 0
Honkers 2023-2-25 13:28:50 | 显示全部楼层 |阅读模式
目录

    环境原理


环境

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父类,这个父类中有一个魔术方法:
/**
     * Handle dynamic, static calls to the object.
     *
     * @param  string  $method
     * @param  array   $args
     * @return mixed
     *
     * @throws \RuntimeException
     */
    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()方法:
    /**
     * Get the root object behind the facade.
     *
     * @return mixed
     */
    public static function getFacadeRoot()
    {
        return static::resolveFacadeInstance(static::getFacadeAccessor());
    }
这里通过我们自定义门面类中的getFacadeAccessor方法,获取到一个service_id(暂且这么叫吧),然后传给resolveFacadeInstance方法。
再往下看resolveFacadeInstance方法:
    /**
     * Resolve the facade root instance from the container.
     *
     * @param  string|object  $name
     * @return mixed
     */
    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门面内容请搜索中国红客联盟以前的文章或继续浏览下面的相关文章希望大家以后多多支持中国红客联盟!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Honkers

荣誉红客

关注
  • 4004
    主题
  • 36
    粉丝
  • 0
    关注
这家伙很懒,什么都没留下!

中国红客联盟公众号

联系站长QQ:5520533

admin@chnhonker.com
Copyright © 2001-2025 Discuz Team. Powered by Discuz! X3.5 ( 粤ICP备13060014号 )|天天打卡 本站已运行