php高级之框架源码、宏扩展原理与开发
在使用框架的时候我们经常会看到如下代码
类的方法不会显示地声明在代码里面,而是通过扩展的形式后续加进去,这么做的好处是可以降低代码的耦合度、保证源码的完整性、团队开发的时候可以分别写自己的服务去扩展类,减少代码冲突等等。我自己看着框架源码实现了这个功能。
以下是结果:
base代码
index.php
<?php
require_once "macroable.php";
require_once "base.php";
$a = new phpmacro\Base();
$a::macro("first",function (){$this->query .="I had be macro";return $this->query;
});
$a->first();
var_dump($a->query);
base.php
<?php
namespace phpmacro;/*** @method first()*/
class Base
{use Macroable;public $query = "init-query";function __construct(){// code...echo "base-contruct";}
}
Macroable.php
<?phpnamespace phpmacro;use BadMethodCallException;
use Closure;
use ReflectionClass;
use ReflectionMethod;trait Macroable
{/*** The registered string macros.** @var array*/protected static $macros = [];/*** Register a custom macro.** @param string $name* @param object|callable $macro* @return void*/public static function macro($name, $macro){static::$macros[$name] = $macro;}/*** Mix another object into the class.** @param object $mixin* @param bool $replace* @return void** @throws \ReflectionException*/public static function mixin($mixin, $replace = true){$methods = (new ReflectionClass($mixin))->getMethods(ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PROTECTED);foreach ($methods as $method) {if ($replace || ! static::hasMacro($method->name)) {static::macro($method->name, $method->invoke($mixin));}}}/*** Checks if macro is registered.** @param string $name* @return bool*/public static function hasMacro($name){return isset(static::$macros[$name]);}/*** Flush the existing macros.** @return void*/public static function flushMacros(){static::$macros = [];}/*** Dynamically handle calls to the class.** @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];if ($macro instanceof Closure) {$macro = $macro->bindTo(null, static::class);}return $macro(...$parameters);}/*** Dynamically handle calls to the class.** @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);}
}
其实原理就是利用了静态调用的魔术方法与匿名函数的bindTo方法实现了类与方法解藕的效果
以下是test.php,可以清晰的看明白匿名函数bindTo跟bind是怎么用的
<?php
/** * 复制一个闭包,绑定指定的$this对象和类作用域。 * * @author 疯狂老司机 */
class Animal {private static $cat = "cat";private $dog = "dog";public $pig = "pig";
}/* * 获取Animal类静态私有成员属性*/
$cat = static function() {return Animal::$cat;
};/* * 获取Animal实例私有成员属性*/
$dog = function() {return $this->dog;
};/* * 获取Animal实例公有成员属性*/
$pig = function() {return $this->pig;
};$bindCat = Closure::bind($cat, null, new Animal());// 给闭包绑定了Animal实例的作用域,但未给闭包绑定$this对象
$bindDog = Closure::bind($dog, new Animal(), 'Animal');// 给闭包绑定了Animal类的作用域,同时将Animal实例对象作为$this对象绑定给闭包
$bindPig = Closure::bind($pig, new Animal());// 将Animal实例对象作为$this对象绑定给闭包,保留闭包原有作用域
$animal = new Animal();
$pigBindto = $pig->bindTo($animal);
echo $pigBindto()."\r\n";
echo $bindCat()."\r\n";// 根据绑定规则,允许闭包通过作用域限定操作符获取Animal类静态私有成员属性
echo $bindDog()."\r\n";// 根据绑定规则,允许闭包通过绑定的$this对象(Animal实例对象)获取Animal实例私有成员属性
echo $bindPig()."\r\n";// 根据绑定规则,允许闭包通过绑定的$this对象获取Animal实例公有成员属性
输出结果
相关文章:
php高级之框架源码、宏扩展原理与开发
在使用框架的时候我们经常会看到如下代码 类的方法不会显示地声明在代码里面,而是通过扩展的形式后续加进去,这么做的好处是可以降低代码的耦合度、保证源码的完整性、团队开发的时候可以分别写自己的服务去扩展类,减少代码冲突等等。我自己…...
(2024,示例记忆,模型记忆,遗忘,差分评估,概率评估)深度学习中的记忆:综述
Memorization in deep learning: A survey 公和众和号:EDPJ(进 Q 交流群:922230617 或加 VX:CV_EDPJ 进 V 交流群) 目录 0 摘要 1 引言 0 摘要 深度神经网络(DNNs)驱动的深度学习ÿ…...
硬件产品经理
边端协调管理平台 主页一:模型管理1.1 边侧模型管理 二:配置管理2.1 终端软件配置管理 三:设备管理3.1 区域位置管理3.2 工控机管理(其实就是围绕授权)3.3 生产设备管理3.4 设备运行管理 四:数据服务4.1 实…...
AES加密、解密工具类
1、AES加密、解密工具类 这篇文章,主要记录一下AES加密、解密的工具类代码,在需要使用的时候,直接复制黏贴即可。 package com.gitcode.pms.common.util;import org.slf4j.Logger; import org.slf4j.LoggerFactory;import javax.crypto.Cipher; import javax.crypto.spec.…...
普通人想要自学ai,该如何入手,看完这篇你就懂了,零基础教程!
学会了AIGC之后,我只想说:无敌是多么寂寞? 之前我整理一篇会议记录起码要2小时。现在交给AI ,5分钟搞定; 之前整理账目总是出错,现在利用AI财务整合器,轻松解决统计难题; 之前写个…...
Less的简单总结
Less 是一个开源的 CSS 预处理器,它扩展了 CSS 语言,增加了变量、嵌套规则、运算符、函数等特性,使编写 CSS 更加高效、灵活且易于维护。下面是对 "Less" 的一个总结文档: 简介 名称:Less(通常表…...
Android:UI:Drawable:View/ImageView与Drawable
文章目录 在View/ImageVIew中显示DrawableDrawable对View的更新操作在View/ImageVIew中显示Drawable API View.setBackground(Drawable) ImageView.setImagDrawable(Drawable) 源码分析 View.mBackground在View.draw(Canvas)中绘制,调用Drawable.draw(Canvas) ImageView.m…...
网络安全实验BUAA-全套实验报告打包
下面是部分BUAA网络安全实验✅的实验内容 : 认识路由器、交换机。掌握路由器配置的基本指令。掌握正确配置路由器的方法,使网络正常工作。 本博客包括网络安全课程所有的实验报告:内容详细,一次下载打包 实验1-路由器配置实验2-AP…...
监控易监测对象及指标之:全面监控SQL Server 2008
随着企业信息化建设的不断深入,数据库作为存储和管理关键业务数据的核心,其稳定性和性能至关重要。SQL Server 2008作为一款广泛使用的关系型数据库管理系统,承载着众多企业的核心业务数据。 为了确保SQL Server 2008数据库的稳定运行和高效性…...
【学习记录】6.11 阅读记录
SpringBoot多环境配置详解(application-dev.yml、application-test.yml、application-prod.yml) springboot集成mybatis【使用generatorConfig.xml配置自动生成代码】 怎么快速查看自己mysql的安装位置 解决 http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd 报错...
100TOPS算力!16GB内存顶配NVIDIA Jetson Orin NX 16GB 开箱
观前提醒:你以为我斥资6600买了一个NX玩?我其实买了三个NX NVIDIA Jetson Orin NX 简介: NVIDIA Jetson Orin NX是NVIDIA推出的一款高性能边缘计算平台,其设计目标是提供卓越的计算能力以支持各种复杂的人工智能(AI&am…...
OCP学习笔记-007 SQL语言之一:DQL
1. DQL - Data Query Language 命令行提示符修改 SQL> set time on 10:33:58 SQL> define DEFINE _DATE = "11-DEC-22" (CHAR) DEFINE _CONNECT_IDENTIFIER = "orcl" (CHAR) DEFINE _USER = "SYS" (CHAR) DEFINE _P…...
Git之解决重复输入用户名和密码(三十九)
简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒…...
Python 机器学习 基础 之 【实战案例】轮船人员获救预测实战
Python 机器学习 基础 之 【实战案例】轮船人员获救预测实战 目录 Python 机器学习 基础 之 【实战案例】轮船人员获救预测实战 一、简单介绍 二、轮船人员获救预测实战 三、数据处理 1、导入数据 2、对缺失数据的列进行填充 3、属性转换,把某些列的字符串值转换为数字…...
安全相关的一些基础知识(持续更新)
目录 1. TRNG真随机数生成 2. 对称加密和非对称加密及其区别 3. Hash算法(摘要算法) 4. HTTPS、TLS、SSL、HTTP区别和关系 HTTPS的基本原理 5. PSS 1. TRNG真随机数生成 True Random Number Generator 在真随机数的生成里,把随机数的生…...
使用TensorFlow和Keras对以ResNet50模型进行微调
以下是使用ResNet50进行微调以识别特定的新东西的代码演示。将使用TensorFlow和Keras进行这个任务。 数据集下载地址,解压到工程里面去: https://www.kaggle.com/datasets/marquis03/cats-and-dogs原始代码: from keras.applications…...
Shell脚本要点和难点以及具体应用和优缺点介绍
Shell 脚本是一种用于自动化任务和简化常见系统命令的脚本语言,通常运行在 Unix 或 Unix-like 的系统上,如 Linux 和 macOS。Shell 脚本可以直接在命令行中执行,也可以保存为文件并通过 bash、sh、zsh 等 shell 解释器来执行。 以下是一个简单的 Shell 脚本示例,它演示了如…...
移动端浏览器的扫描二维码实现(vue-qrcode-reader与jsQR方式)
1. 实现功能 类似扫一扫的功能,自动识别到画面中的二维码并进行识别,也可以选择从相册中上传。 2. 涉及到的一些插件介绍 vue-qrcode-reader 一组用于检测和解码二维码的Vue.js组件 jsQR 一个纯粹的javascript二维码阅读库,该库接收原始…...
android中调用onnxruntime框架
创建空白项目 安装Android Studio及创建空白项目参考:【安卓Java原生开发学习记录】一、安卓开发环境的搭建与HelloWorld(详细图文解释)_安卓原生开发-CSDN博客 切记:build configuration language 一定选择Groovy!官…...
【机器学习】与【数据挖掘】技术下【C++】驱动的【嵌入式】智能系统优化
目录 一、嵌入式系统简介 二、C在嵌入式系统中的优势 三、机器学习在嵌入式系统中的挑战 四、C实现机器学习模型的基本步骤 五、实例分析:使用C在嵌入式系统中实现手写数字识别 1. 数据准备 2. 模型训练与压缩 3. 模型部署 六、优化与分析 1. 模型优化 模…...
Apollo9.0 PNC源码学习之Control模块(二)
前面文章:Apollo9.0 PNC源码学习之Control模块(一) 本文将对具体控制器以及原理做一个剖析 1 PID控制器 1.1 PID理论基础 如下图所示,PID各参数(Kp,Ki,Kd)的作用: 任何闭环控制系统的首要任务是要稳、准、快的响…...
直线度测量仪发展历程!
直线度测量仪的发展历程可以概括为以下几个关键阶段: 拉钢丝法: 早期直线度测量的简单直观方法,利用钢丝受重力自然下垂的原理来测量直线度误差。 随着机械设备的大型化和测量精度要求的提高,该方法逐渐无法满足要求,正…...
09-spring的bean创建流程(一)
文章目录 spring中bean的创建流程finishBeanFactoryInitialization(beanFactory)beanFactory.preInstantiateSingletons();getMergedLocalBeanDefinition(beanName);流程实现FactoryBean接口,里面的对象实例化过程 spring中bean的创建流程 finishBeanFactoryInitialization(be…...
spring中基于setting和构造器的注入方式
Spring中可以通过setting和构造器两种方式进行依赖注入。 1.基于setting的注入方式(Setter Injection): 实现方式:在类中添加对应的属性以及对应的setter方法,在配置文件中使用<property>元素进行注入。 示例代码…...
爬虫基本原理?介绍|实现|问题解决
爬虫基本原理: 模拟用户行为: 网络爬虫(Web Crawler)是一种自动化的程序,它模拟人类用户访问网站的方式,通过发送HTTP/HTTPS请求到服务器以获取网页内容。 请求与响应: 爬虫首先构建并发送带有…...
DevOps的原理及应用详解(六)
本系列文章简介: 在当今快速变化的商业环境中,企业对于软件交付的速度、质量和安全性要求日益提高。传统的软件开发和运维模式已经难以满足这些需求,因此,DevOps(Development和Operations的组合)应运而生&a…...
手撸 串口交互命令行 及 AT应用层协议解析框架
在嵌入式系统开发中,命令行接口(CLI)和AT命令解析是常见的需求。CLI提供了方便的调试接口,而AT命令则常用于模块间的通信控制。本文将介绍如何手动实现一个串口交互的命令行及AT应用层协议解析框架,适用于FreeRTOS系统…...
Redis几种部署模式介绍
Redis 提供了几种不同的部署模式,以满足不同的使用场景和可用性需求。这些模式包括单机模式、主从复制、哨兵模式和集群模式。下面我将简要介绍每种模式的特点和用途: 单机模式: 描述:单个 Redis 服务器实例运行在一台机器上&…...
【STM32HAL库学习】定时器功能、时钟以及各种模式理解
一、文章目的 记录自己从学习了定时器理论->代码实现使用定时->查询数据手册,加深了对定时器的理解以及该过程遇到了的一些不清楚的知识。 上图为参考手册里通用定时器框图,关于定时器各种情况的工作都在上面了,在理论学习和实际应用后…...
3588麒麟系统硬解码实战
目录 安装rockchip-mpp deb 查找头文件 .pro文件添加 检查库是否已安装 error: stdlib.h: No such file or directory ffmpeg 查找ffmpeg路径: 查找FFmpeg库和头文件的位置 使用pkg-config工具查找FFmpeg路径 ok的ffmpeg配置: ffmpeg查看是否支持libx264 ffmpeg …...
如何快速学成网站开发/中国关键词官网
Input 表的时候 hadoop Command 使用中中文的时候, chop查询下,默认采用UTF8 同时修改属性 使用命令导入 转载于:https://www.cnblogs.com/junjiany/p/6340834.html...
做网站实习日志/青岛百度推广优化
SQL 目录:https://blog.csdn.net/dkbnull/article/details/87932858 1、打开Workbench如下图,点击红色框后登录 2、输入密码后进入用户界面 3、点击 1 所示按钮创建数据库,出现 2 所示界面,输入数据库名,点击 3 所示…...
wordpress最大文件/网站增加外链的方法有哪些
《CⅡ》参考答案 (№ A03Ⅱa)第 PAGE 2 页 共 NUMPAGES 2 页计算机学院《CⅡ》参考答案一、1.(每小题1分,共10 分)(1) 私有成员函数;求两个整数的最大公因子。(2) 私有成员函数;分数约简。(3) 私有成员函数;小数转换为…...
用美国服务器做钓鱼网站/微商引流推广
ab命令原理 Apache的ab命令模拟多线程并发请求,测试服务器负载压力,也可以测试nginx、lighthttp、IIS等其它Web服务器的压力。 ab命令对发出负载的计算机要求很低,既不会占用很多CPU,也不会占用太多的内存,但却会给目…...
杭州建设职业技术学院招聘信息网站/代运营是什么意思
JVM 中对象咋创建啊,又怎么访问啊 虚拟机遇到 new 指令,会根据指令参数去常量池找对应类的符号引用,如果没找到会进行类加载,此时会执行类构造器指令。类加载完成之后,初始化之前,开始进行对象内存分配&…...
国家电力安全网站两学一做/微信小程序平台官网
一、数据仓库分为几层?负责什么职责?为什么要分层?1、数据仓库分为4层: ODS层 (原始数据层) DWD层 (明细数据层) DWS层 (服务数据层)ADS层 (数据应…...