程序笔记   发布时间:2022-07-12  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了laravel facade源码学习大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
/**
     * The application instance being facaded.
     * 被封装的应用程序实例
     * @var IlluminateContractsFoundationApplication
     */
    protected static $app;

    /**
     * The resolved object instances.
     * 已解析的对象实例
     * @var array
     */
    protected static $resolvedInstance;

    /**
     * Run a Closure when the facade has been resolved.
     * 在解决facade时运行Closure
     * @param  Closure  $callBACk
     * @return void
     */
    public static function resolved(Closure $callBACk)
    {
        static::$app->afterResolving(static::getFacadeAccessor(), function ($service) use ($callBACk) {
            $callBACk($service);
        });
    }

这里的afterResolving,来自Container.php接口里的方法

/**
     * Register a new after resolving callBACk.
     * 解析回调后注册一个新的
     * @param  Closure|String  $abstract
     * @param  Closure|null  $callBACk
     * @return void
     */
    public function afterResolving($abstract, Closure $callBACk = null);

第一个参数static::getFacadeAccessor()方法如下

/**
     * Get the registered name of the component.
     * 获取组件的注册名称
     * @return String
     *
     * @throws RuntimeException
     */
    protected static function getFacadeAccessor()
    {
        throw new RuntimeException('Facade does not implement getFacadeAccessor method.');
    }

第二个参数是一个匿名函数方法作为回调。

下一个方法

/**
     * Convert the facadE into a mockery spy.
     * 把正面变成一个伪间谍(用翻译软件直接翻译结果如此)
     * @return mockerymockInterface
     */
    public static function spy()
    {
        if (! static::ismock()) {
            $class = static::getmockableClass();

            return tap($class ? mockery::spy($class) : mockery::spy(), function ($spy) {
                static::swap($spy);
            });
        }
    }

ismock方法返回一个布尔值

/**
     * Determines whether a mock is set as the instance of the facade.
     * 确定是否将模拟设置为facade的实例
     * @return bool
     */
    protected static function ismock()
    {
        $name = static::getFacadeAccessor();

        return isset(static::$resolvedInstance[$name]) &&
               static::$resolvedInstance[$name] instanceof mockInterface;
    }
mockInterface接口如下:
interface mockInterface extends LegacymockInterface
{
    /**
     * @param mixed $something  String method name or map of method => return
     * @return self|mockeryExpectationInterface|mockeryExpectation|mockeryHigherOrdermessage
     */
    public function allows($something = []);

    /**
     * @param mixed $something  String method name (optional)
     * @return mockeryExpectationInterface|mockeryExpectation|mockeryExpectsHigherOrdermessage
     */
    public function expects($something = null);
}

在ismock返回false后进入判断,首先获取实例类名getmockableClass,实现如下

/**
     * Get the mockable class for the bound instance.
     * 获取绑定实例的可模拟类
     * @return String|null
     */
    protected static function getmockableClass()
    {
        if ($root = static::getFacadeRoot()) {
            return get_class($root);
        }
    }

其中getFacadeRoot方法实现如下

/**
     * Get the root object behind the facade.
     * 获取facade背后的根对象
     * @return mixed
     */
    public static function getFacadeRoot()
    {
        return static::resolveFacadeInstance(static::getFacadeAccessor());
    }
里面的resolveFacadeInstancef方法如下
/**
     * Resolve the facade root instance from the container.
     * 从容器解析facade根实例
     * @param  object|String  $name
     * @return mixed
     */
    protected static function resolveFacadeInstance($name)
    {
        if (is_object($name)) {
            return $name;
        }

        if (isset(static::$resolvedInstance[$name])) {
            return static::$resolvedInstance[$name];
        }

        if (static::$app) {
            return static::$resolvedInstance[$name] = static::$app[$name];
        }
    }
resolveFacadeInstance根据传入的参数判断是否是对象,是对象直接返回该参数,不是则判断static::$resolvedInstance[$name]是否设置了这个key,有则返回static::$resolvedInstance[$name],没有再判断static::$app是否存在,存在赋值给static::$resolvedInstance[$name]并返回。回到getmockableClass,static::getFacadeRoot()赋值给$root,用get_class获取类名。回到spy,获取类名后,调用tap方法,该方法在Helpers.php里,实现如下
if (! function_exists('tap')) {
    /**
     * Call the given Closure with the given value then return the value.
     * 用给定的值调用给定的闭包,然后返回该值
     * @param  mixed  $value
     * @param  callable|null  $callBACk
     * @return mixed
     */
    function tap($value, $callBACk = null)
    {
        if (is_null($callBACk)) {
            return new HigherOrderTapProxy($value);
        }

        $callBACk($value);

        return $value;
    }
}
HigherOrderTapProxy类源码如下
class HigherOrderTapProxy
{
    /**
     * The target being tapped.
     *
     * @var mixed
     */
    public $target;

    /**
     * Create a new tap proxy instance.
     *
     * @param  mixed  $target
     * @return void
     */
    public function __construct($target)
    {
        $this->target = $target;
    }

    /**
     * Dynamically pass method calls to the target.
     *
     * @param  String  $method
     * @param  array  $parameters
     * @return mixed
     */
    public function __call($method, $parameters)
    {
        $this->target->{$method}(...$parameters);

        return $this->target;
    }
}
回到spy()里的tap,第一个参数
mockery::spy()实现在mockery里
/**
     * Static and semantic shortcut for getTing a mock from the container
     * and applying the spy's expected behavior into it.
     * 静态和语义快捷方式,用于从容器获取mock并将间谍的预期行为应用到其中
     * @param mixed ...$args
     *
     * @return mockerymockInterface|mockeryLegacymockInterface
     */
    public static function spy(...$args)
    {
        if (count($args) && $args[0] instanceof ClosurE) {
            $args[0] = new ClosureWrapper($args[0]);
        }

        return call_user_func_array(array(self::getContainer(), 'mock'), $args)->shouldIgnoreMissing();
    }
/**
     * Lazy loader and getter for
     * the container property.
     * 容器属性的惰性加载器和getter
     * @return mockeryContainer
     */
    public static function getContainer()
    {
        if (is_null(self::$_container)) {
            self::$_container = new mockeryContainer(self::getGenerator(), self::getLoader());
        }

        return self::$_container;
    }
/**
     * Lazy loader method and getter for
     * the $_loader property.
     * $_loader属性的惰性加载器方法和getter
     * @return Loader
     */
    public static function getLoader()
    {
        if (is_null(self::$_loader)) {
            self::$_loader = self::getDefaultLoader();
        }

        return self::$_loader;
    }
class ClosureWrapper
{
    private $closure;

    public function __construct(Closure $closure)
    {
        $this->closure = $closure;
    }

    public function __invoke()
    {
        return call_user_func_array($this->closure, func_get_args());
    }
}

 

/**
     * Hotswap the underlying instance behind the facade.
     * Hotswap facade背后的底层实例
     * @param  mixed  $instance
     * @return void
     */
    public static function swap($instance)
    {
        static::$resolvedInstance[static::getFacadeAccessor()] = $instance;

        if (isset(static::$app)) {
            static::$app->instance(static::getFacadeAccessor(), $instance);
        }
    }

 

 

 

大佬总结

以上是大佬教程为你收集整理的laravel facade源码学习全部内容,希望文章能够帮你解决laravel facade源码学习所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。