Laravel 宏指令(Macro)动态添加自定义方法到Laravel的核心组件中

Laravel 宏指令(Macro)

在Laravel中,宏指令(Macro)是一种灵活的方式,允许您动态添加自定义方法到Laravel的核心组件中,如模型、查询构建器、集合等,以便在不改变核心代码的情况下扩展框架的功能。通过宏指令,您可以向Laravel内置的类添加自定义方法,实现更高级的功能和逻辑。

福利彩蛋:没有好玩的 API 接口?上百款免费接口等你来,免费 API,免费 API 大全

模型中定义宏指令使用示例

1. 在模型中定义宏指令

您可以在模型中定义宏指令,让模型具备额外的功能。以下是一个示例,展示如何向模型添加一个自定义的宏指令:

use Illuminate\Database\Eloquent\Model;Model::macro('customMethod', function() {// 定义自定义方法逻辑return 'This is a custom method.';
});

2. 在查询构建器中定义宏指令

您也可以在查询构建器中定义宏指令,以便在查询数据时使用自定义的方法。以下是一个示例,展示如何向查询构建器添加一个自定义的宏指令:

use Illuminate\Database\Query\Builder;Builder::macro('whereActive', function () {return $this->where('active', '=', 1);
});

3. 使用宏指令

在定义宏指令后,您可以通过具体的对象来调用宏指令定义的方法。例如,在模型中调用上面定义的 customMethod 宏指令:

$user = User::find(1);
echo $user->customMethod(); // 输出:This is a custom method.

或者在查询构建器中使用上面定义的 whereActive 宏指令:

$activeUsers = DB::table('users')->whereActive()->get();

使用宏指令可以方便地为Laravel项目添加自定义方法,提高代码复用性和扩展性。同时,宏指令的灵活性使您可以根据具体需求动态地为不同的类添加自定义方法,扩展框架功能,提升开发效率。

高级使用

一、前置准备:

安装 tutorigo/laravel-ide-macros


composer require tutorigo/laravel-ide-macrosphp artisan vendor:publish --provider="Tutorigo\LaravelMacroHelper\IdeMacrosServiceProvider"php artisan ide-helper:macros

二、开始使用

1、新建MacrosServiceProvider或根据业务扩展需求创建RouteMacrosServiceProvider等等
2、config/app.php中添加MacrosServiceProvider注册
3、在MacrosServiceProvider boot中完成宏指令编写

1、Route macro 来定义 Route 的新方法permission

通过宏指令绑定自定义方法到路由实例
路由定义时候通过宏指令自定义的方法将响应的参数存储到路由action参数下,该参数在路由缓存的时候回一并缓存

/*** 扩展路由方法*/
Route::macro('permission', function (array $value): self {$this->action['permission'] = $value;return $this;
});Route::macro('getPermission', function (): array {return $this->action['permission'] ?? [];
});/**
* 路由定义
*/
Route::post('report', 'ProductController@apiReport')->permission(['value' => 'productPayReport', 'name' => '付费数据统计', 'label' => '付费API统计']);/**
* 权限中间件或其他地方使用
*/
$permission = request()->getPermission()

2、Route macro 来定义 Route 的新方法full

通过新增的方法可以简洁的定义两个路由

Route::macro('full',function ($prefix, $controller){Route::delete($prefix.'/destroy-selection', $controller.'@destroySelection')->name($prefix.'destroy-selection');Route::apiResource($prefix, $controller);
});/**
* 路由定义:一次完成两个路由定义
*/
Route::full('prefix','UserController')

3、扩展数据查询builder新方法

输出完整的sql语句

// 查询构造器builder
// use Illuminate\Database\Query\Builder as QBuilder;
QBuilder::macro('toRawSql', function () {return array_reduce($this->getBindings(), function ($sql, $binding) {return preg_replace('/\?/', is_numeric($binding) ? $binding : "'" . $binding . "'", $sql, 1);}, $this->toSql());});// 数据库模型builder      
// use Illuminate\Database\Eloquent\Builder as EBuilder;
EBuilder::macro('toRawSql', function () {return ($this->getQuery()->toRawSql());
});// 使用,输出查询语句:
var_dump(SomeModel::where('id',1)->toRawSql())// 自定义一个tld条件查询:当前主域名符合查询要求时候主动添加一个where条件
Builder::macro('whenTldMatches', function($tld, $callback) {if (Request::tldIs($tld)) {call_user_func($callback->bindTo($this));}return $this;
});// 使用自定义方法
SomeModel::whenTldMatches('org', function () {$this->where('id', '>', 5);
})->get();

3、Request 宏指令用于检测当前的 TLD(顶级域:.com,.net,.org,.etc…)

use Illuminate\Support\Facades\Request;// 定义
Request::macro('tldIs', function ($tld) {return Str::is('*.' . $tld, $this->root());
});// 使用
Request::tldIs('com') // returns true for app.com
Request::tldIs('dev') // returns false for app.com

4、Response响应宏

use Illuminate\Support\Facades\Response;
// 注册成功响应宏
Response::macro('success', function ($data = [], $message = 'success') {return new JsonResponse(['code' => 0,'data' => $data,'message' => $message], 200);
});// 调用
return response()->success($userRepository->all(), 'success');

福利彩蛋:没有好玩的 API 接口?上百款免费接口等你来,免费 API,免费 API 大全

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/41611.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

电脑硬盘分区的基本步骤(2个实用的硬盘分区方法)

在现代计算机中,硬盘分区是非常重要的一步。无论是新硬盘的初始化,还是重新组织现有硬盘,分区都是必不可少的操作。本文将详细介绍电脑硬盘分区的基本步骤,帮助您更好地管理和利用硬盘空间。 文章开始,我们先简单说一…

【C++】 解决 C++ 语言报错:Invalid Conversion from ‘const char*’ to ‘char*’

文章目录 引言 在 C 编程中,类型转换错误(Invalid Conversion)是常见的编译错误之一。特别是当程序试图将一个常量字符指针(const char*)转换为非常量字符指针(char*)时,会导致编译…

Vmware环境下ESXi主机 配置上行链路、虚拟交换机、端口组、VMkernel网卡

一、适用场景 1、使用专业服务器跑多种不同的业务,每种业务可能所需运行的server环境不同,有的需要Linux server CentOS7/8、kali、unbuntu……有的需要windows server2008、2003、2016、2019、2022…… 2、本例采用的是VMware ESXi6.7 update 3版本&am…

力扣习题--找不同

目录 前言 题目和解析 1、找不同 2、 思路和解析 总结 前言 本系列的所有习题均来自于力扣网站LeetBook - 力扣(LeetCode)全球极客挚爱的技术成长平台 题目和解析 1、找不同 给定两个字符串 s 和 t ,它们只包含小写字母。 字符串 t…

Java Maven中自动代码检查插件详细介绍

文章目录 Checkstyle主要特点使用场景配置与使用checkstyle.xmlsuppressions.xml 验证打包时验证执行命令验证 Spotless配置文件内容Java配置部分POM 配置部分Markdown 配置部分Up to Date Checking执行部分 验证打包时验证在插件中执行命令验证 Checkstyle Spotless 结合chec…

ABAP中BAPI_CURRENCY_CONV_TO_INTERNAL 函数的使用方法

在ABAP中,BAPI_CURRENCY_CONV_TO_INTERNAL 函数模块主要用于将外部金额转换为内部存储格式。这对于确保金额数据在SAP系统中的一致性和准确性至关重要。以下是关于该函数模块使用方法的详细解释: 函数模块参数 调用 BAPI_CURRENCY_CONV_TO_INTERNAL 时…

redis学习(005 java客户端 RedisTemplate学习)

黑马程序员Redis入门到实战教程,深度透析redis底层原理redis分布式锁企业解决方案黑马点评实战项目 总时长 42:48:00 共175P 此文章包含第16p-第p23的内容 文章目录 java客户端jedisSpringDataRedis项目实现hash哈希操作 java客户端 jedis 测试 ps:如果连接不上&…

vs2019 无法打开项目文件

vs2019 无法打开项目文件,无法找到 .NET SDK。请检查确保已安装此项且 global.json 中指定的版本(如有)与所安装的版本相匹配 原因:缺少组件 解决方案:选择需要的组件进行安装完成

C#静态类与非静态类

1、静态类 静态类有几个重要的特点: 1)无法实例化:由于静态类不能被实例化,因此它不会占用对象内存。 2)静态成员:静态类只能包含静态成员(静态方法、静态属性、静态事件等)。 3&am…

步进电机改伺服电机

步进电机: 42:轴径5mm 57:轴径8mm 86:轴径14mm 【86CME120闭环】// 12牛米 伺服电机: 40: 60: 80: 86: ECMA——C 1 0910 R S 4.25A 轴径…

评价ChatGPT与强人工智能的未来

在人工智能领域,ChatGPT的出现无疑是一个里程碑事件。它不仅展示了自然语言处理技术的巨大进步,也引发了人们对于强人工智能(AGI)的无限遐想。本文将从多个角度评价ChatGPT,并探讨强人工智能距离我们还有多远。 ChatGP…

虚拟地址和物理地址

到底什么是虚拟地址呢?它和物理地址的区别又在哪呢? 一. 虚拟地址的作用 1. 使代码的移植性更好,在不同平台进行编译以后,就可以直接运行,因为到别的系统,会将你的虚拟地址转换为物理地址,而使…

无人机运营合格证及无人机驾驶员合格证(AOPA)技术详解

无人机运营合格证及无人机驾驶员合格证(AOPA)技术详解如下: 一、无人机运营合格证 无人机运营合格证是无人机运营企业或个人必须获得的证书,以确保无人机在运营过程中符合相关法规和标准。对于无人机运营合格证的具体要求和申请…

无人机人员搜救

人员搜救-水域救援 水域搜救:快速水面搜查 物资抛投:救生物资抛投 绳索牵引:牵引救援绳索 领航船艇:水面侦察领航 人员搜救 昼夜搜救,精准定位 水域搜救 经纬 M300 RTK 搭载禅思 H20T 能够满足全天候作业需求&a…

【区分vue2和vue3下的element UI Dialog 对话框组件,分别详细介绍属性,事件,方法如何使用,并举例】

在 Vue 2 和 Vue 3 中,Element UI(针对 Vue 2)和 Element Plus(针对 Vue 3)提供了 Dialog 对话框组件,用于在页面中显示模态对话框。这两个库中的 Dialog 组件在属性、事件和方法的使用上有所相似&#xff…

新手教学系列——Git Stash踩坑

在之前的文章《如何彻底避免Git代码相互覆盖问题》中,我曾介绍过通过规范分支合并和使用git stash来避免代码覆盖问题。今天,我要深入探讨一下git stash的使用,并分享一些使用过程中遇到的坑,希望能帮你避免类似问题。 脚本mg.sh简介 为了更好地管理代码合并,我编写了一…

gcc: 自身编译: opt;有个变量怎么找不到?

文章目录 makefile/configure中间awk的转换举例,options.h里的内容:解开疑问makefile/configure lang_opt_files=@lang_opt_files@ $(srcdir)/c-family/c.opt $(srcdir)/common.opt# All option source files ALL_OPT_FILES=$(lang_opt_files) $(extra_opt_files

linux之管道重定向

管道与重定向 一、重定向 将原输出结果存储到其他位置的过程 标准输入、标准正确输出、标准错误输出 ​ 进程在运行的过程中根据需要会打开多个文件,每打开一个文件会有一个数字标识。这个标识叫文件描述符。 进程使用文件描述符来管理打开的文件(FD--…

windows USB 设备驱动开发-控制传输的数据包

每次在主机控制器和 USB 设备之间移动数据时,都会发生传输。 通常,USB 传输可大致分为控制传输和数据传输。 所有 USB 设备都必须支持控制传输,并且可以支持用于数据传输的端点。 每种类型的传输都与设备缓冲区USB 端点 的类型相关联。 控制传…

泛微开发修炼之旅--32ecology对接海康威视综合安防管理系统,人脸识别机器数据同步代码方案及源码

文章链接:32ecology对接海康威视综合安防管理系统,人脸识别机器数据同步代码方案及源码