首页 > 其他分享 >laravel Macroable 类详解

laravel Macroable 类详解

时间:2023-07-04 13:47:29浏览次数:43  
标签:laravel return parameters macro Macroable param 详解 static method

<?php
namespace Illuminate\Support\Traits;

use BadMethodCallException;
use Closure;
use ReflectionClass;
use ReflectionMethod;

trait Macroable
{
    /**
     * 存放注册的宏方法数组
     */
    protected static $macros = [];

    /**
     * 注册的宏方法
     * @param  string  $name
     * @param  object|callable  $macro
     * @return void
     */
    public static function macro($name, $macro)
    {
        static::$macros[$name] = $macro;// 方法名 => 对象
    }

    /**
     * 混合其他对象到当前类.
     * @param  object  $mixin
     * @param  bool  $replace 是否替换已经存在的
     * @return void
     *
     * @throws \ReflectionException
     */
    public static function mixin($mixin, $replace = true)
    {
        // 通过反射得到 $mixin 对象所有 protected 和 public 方法
        $methods = (new ReflectionClass($mixin))->getMethods(
            ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PROTECTED
        );

        // 遍历所有方法,并把方法和对应的 添加到 static::macro 数组中
        foreach ($methods as $method) {
            if ($replace || ! static::hasMacro($method->name)) {
                static::macro($method->name, $method->invoke($mixin)); // 类似于 $mixin->$method(), 这里要求其他返回的是个一个函数对象
            }
        }
    }

    /**
     * 检测方法名是否已经注册过了
     * @param  string  $name
     * @return bool
     */
    public static function hasMacro($name)
    {
        return isset(static::$macros[$name]);
    }


    /**
     * 通过魔术方法,调用静态方法
     * @param  string  $method
     * @param  array  $parameters
     * @return mixed
     * @throws \BadMethodCallException
     */
    public static function __callStatic($method, $parameters)
    {
        // 如果方法名未注册,抛出异常
        if (! static::hasMacro($method)) {
            throw new BadMethodCallException(sprintf(
                'Method %s::%s does not exist.', static::class, $method
            ));
        }

        $macro = static::$macros[$method];

        // 如果可调用对象 $macro 是匿名函数,则通过 $macro->bindTo()方法,复制 $macro 这个闭包对象,绑定 static::class 对象和类作用域
        // 比如: $macro = function(){ $this->name }; $macro->bindTo($obj); $macro(); 返回的就是 $obj->name 属性
        if ($macro instanceof Closure) {
            $macro = $macro->bindTo(null, static::class);
        }

        // 最后调用并返回
        return $macro(...$parameters);
    }

    /**
     * __call 和 __callStatic 一模一样的代码
     * 为啥不写一句 static::__callStatic($method, $parameters) 呢?
     * @param  string  $method
     * @param  array  $parameters
     * @return mixed
     * @throws \BadMethodCallException
     */
    public function __call($method, $parameters)
    {
        if (! static::hasMacro($method)) {
            throw new BadMethodCallException(sprintf(
                'Method %s::%s does not exist.', static::class, $method
            ));
        }

        $macro = static::$macros[$method];

        if ($macro instanceof Closure) {
            $macro = $macro->bindTo($this, static::class);
        }

        return $macro(...$parameters);
    }
}

 

标签:laravel,return,parameters,macro,Macroable,param,详解,static,method
From: https://www.cnblogs.com/zbseoag/p/17525524.html

相关文章

  • 详解共识算法的Raft算法模拟数
    摘要:Raft算法是一种分布式共识算法,用于解决分布式系统中的一致性问题。本文分享自华为云社区《共识算法之Raft算法模拟数》,作者:TiAmoZhang。01、Leader选举存在A、B、C三个成员组成的Raft集群,刚启动时,每个成员都处于Follower状态,其中,成员A心跳超时为110ms,成员B心跳超时为150m......
  • 第20课 SPI协议详解及裸机程序开发分析
    第001节_SPI协议介绍市面上的开发板很少接有SPI设备,但是SPI协议在工作中经常用到。我们开发了SPI模块,上面有SPIFlash和SPIOLED。OLED就是一块显示器。我们裸板程序会涉及两部分:用GPIO模拟SPI用S3C2440的SPI控制器我们先介绍下SPI协议,硬件框架如下:SCK:提供时钟DO:作为数据输出DI:作......
  • 第017课 LCD原理详解及裸机程序分析
    第001节_LCD硬件原理先简单介绍下LCD的操作原理。如下图的LCD示意图,里面的每个点就是一个像素点。想象有一个电子枪,一边移动,一边发出各种颜色的光。这里有很多细节问题,我们一个一个的梳理。电子枪是如何移动的?答:有一条CLK时钟线与LCD相连,每发出一次CLK(高低电平),电子枪就移动......
  • 第014课 Jz2400_ARM异常与中断体系详解
    第001节_概念引入与处理流程取个场景解释中断。假设有个大房间里面有小房间,婴儿正在睡觉,他的妈妈在外面看书。问:这个母亲怎么才能知道这个小孩醒?过一会打开一次房门,看婴儿是否睡醒,让后接着看书一直等到婴儿发出声音以后再过去查看,期间都在读书第一种叫做查询方式:*优点:简单*缺......
  • Adidas EDI 需求详解
    Adidas(阿迪达斯)是一家知名的国际体育用品品牌,成立于1949年。作为全球领先的运动品牌之一,Adidas以设计和制造优质运动鞋、服装和配件而闻名。该公司的经营范围广泛,涵盖了多个运动领域,如足球、篮球、跑步和户外活动等。Adidas的使命是成为全球顶级运动品牌,通过为人们提供最先进的......
  • Java并发工具包详解
    针对并发编程,Java提供了很多并发工具类供我们使用,下面我们详细介绍一下。SemaphoreSemaphore,现在普遍翻译为“信号量”,以前也曾被翻译成“信号灯”,因为类似现实生活里的红绿灯,车辆能不能通行,要看是不是绿灯。同样,在编程世界里,线程能不能执行,也要看信号量是不是允许。信号量模型......
  • 语音房源码搭建技术分享之降噪功能详解
     噪音是指人们感觉到不愉快或干扰的声音,它通常是由于各种来源产生的不规则、杂乱的声音信号,噪音在我们生活中有很多的来源,像是环境噪音、社会噪音等,如果长时间暴露在噪音环境中可能导致许多健康问题,包括听力受损、睡眠障碍、心理压力增加、集中注意力困难等,而我今天要分享的知识......
  • WebSocket 协议详解
    一、WebSocket协议背景早期,在网站上推送消息给用户,只能通过轮询的方式或Comet技术。轮询就是浏览器每隔几秒钟向服务端发送HTTP请求,然后服务端返回消息给客户端。轮询技术一般在浏览器上就是使用setInerval或setTimeout这种方式的缺点:需要不断的向服务端发送HTTP......
  • IDEA常用快捷键大全(详解)
    前言IDEA中提供了很多快捷键,点击File-->Settings-->keymap便可进入看到IDEA提供的快捷键。我们也可以搜索和自定义所有快捷键,下面给出的是IDEA中默认的快捷键;一.Ctrl相关Ctrl+F在当前文件进行文本查找(必备)Ctrl+R在当前文件进行文本替换(必备)Ctrl+Z撤销(必备......
  • MySQL基础篇:逻辑架构图解和InnoDB存储引擎详解
    一、MySQL逻辑架构1、逻辑架构图基于下面的逻辑架构图,可以大致熟悉MySQL各个架构组件之间的协同工作关系。 很经典的C/S架构风格,即客户端/服务端模式。2、分层描述客户端连接通常会进行连接池管理,连接用户权限认证,安全管理等操作。可以通过如下命令查看连接配置信息:S......