大佬教程收集整理的这篇文章主要介绍了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,请注明来意。