PHP Laravel门面的实现原理详解
作者:自由de单车 时间:2023-05-25 06:42:36
环境
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静态变量中,这样下次再获取相同对象时,就不用重复实例化了。
来源:https://blog.csdn.net/ljfrocky/article/details/128944416
标签:Laravel,门面
0
投稿
猜你喜欢
MSSQL差异备份取系统权限的相关软件下载
2024-01-21 16:08:46
python3 scrapy框架的执行流程
2022-04-12 08:53:35
python+mysql实现简单的web程序
2024-01-15 12:31:58
pytorch教程resnet.py的实现文件源码分析
2023-11-07 21:18:47
js截取字符串的方法
2008-04-20 17:06:00
基于Python log 的正确打开方式
2021-05-29 21:42:59
Pycharm创建Django项目示例实践
2021-06-20 05:28:08
再谈“字符串拼接”的效率
2009-04-30 12:48:00
解压版MYSQL中文乱码问题解决方案
2024-01-21 12:40:12
python连接字符串的方法小结
2023-12-29 16:24:49
MySQL数据库JDBC编程详解流程
2024-01-15 09:39:55
WEB手绘稿常用元素 之 箭头
2009-05-08 12:33:00
Express实现Session身份认证的示例代码
2024-05-08 09:38:21
python算法学习之基数排序实例
2023-01-07 05:24:52
python之pkl文件的用法及说明
2021-02-21 21:44:57
Python Matplotlib绘制多子图详解
2021-01-11 11:27:05
Asp中通过简单的例子理解下ByVal和ByRef的用法
2011-02-20 10:57:00
asp操作Excel类源码
2009-12-25 19:01:00
Pycharm学习教程(3) 代码运行调试
2023-04-11 00:01:18
Python Socket TCP双端聊天功能实现过程详解
2022-03-13 02:25:44