在一般编程中,我们要扩展一个基础类,我们需要进行继承才能扩充。然而Laravel利用PHP的特性,编写了一套叫做Macroable的Traits,这样,凡是使用Macroable的类,都是可以使用这个方法扩充的。

基本使用方法

我下面用Collection类来做示范。

要给Collection加一个扩充方法可以这样写:

Collection::macro("macro_name", function ($parameters) {

// Your macro

});

这样就很容易的就扩充了Collection的方法,而不需要进行复杂的继承。

我们再举个具体的例子,把所有Collection的字符数组全部变成大写。那么我们就这样写:

Collection::macro('uppercase', function () {

return collect($this->items)->map(function ($item) {

return strtoupper($item);

});

});

collect(["hello", "world"])->uppercase();

这个结果是: ["HELLO", "WORLD"]

关于macro内部的$this

Collection $this 在macro的作用域必须注意,$this不是指向你文件类的对象,而是指向你marco扩充的类。比如例子中的$this是指向Collection的。

这是因为在Marcoable的源代码中,是可以看到static::$macros[$method]->bindTo($this, static::class)这段代码。而bindTo是改变$this上下文指向的方法。

marco的代码应该放在哪里?

marco的代码应该放在哪里才能让整个项目都能使用, 这个问题其实困扰了我很久, 所以一直没有写这个教程。不过现在研究明白了。

要让marco扩充的类,保证整个项目都能使用, 需要创建一个ServiceProvider,并把扩充的方法,放入boot()的方法中

namespace App\Providers;

use Collection;

use Illuminate\Support\ServiceProvider;

class CollectionMacroServiceProvider extends ServiceProvider {

public function boot()

{

Collection::macro('uppercase', function () {

return collect($this->items)->map(function ($item) {

return strtoupper($item);

});

});

}

}

然后我们就可以在config/app.php中的providers中下面加App\ProvidersCollectionMacroServiceProvider::class即可

哪些类可以使用marco

Response

Request

Collection

HTML

Form

Filesystem

Cache

Str

Arr

Translator

等等,使用了Marcoable的Traits,如果是自己编写的类,使用了Marcoable,也可以这样扩充使用(写Laravel开源库的时候)

英文简版和参考

我把经验的部分写在了Stackoverflow的document中了,有兴趣可以支持一下:

http://stackoverflow.com/documentation/lar...

参考内容:

php macro,如何利用 macro 方法来扩展 Laravel 的基础类的功能相关推荐

  1. 【ABAP】创建局部Macro和全局Macro

    1. 局部Macro 在程序中重复使用的语句,最好定义成Macro 后使用.当在程序中使用时,先以 DEFINE~ END-OF-DEFINITION形式定义后用Macro名字和参数调用即可.如果PE ...

  2. 双线macd指标参数最佳设置_MT4双线MACD设置方法及扩展应用

    原标题:MT4双线MACD设置方法及扩展应用 在MT4交易软件上MACD虽然看起来是单线,其实它和我们在股票软件上看到的双线MACD并没有本质的区别. 将MT4软件上MACD的每一个柱的顶点连成线,其 ...

  3. 【Groovy】Groovy 扩展方法 ( Groovy 扩展方法引入 | 分析 Groovy 中 Thread 类的 start 扩展方法 )

    文章目录 一.Groovy 扩展方法引入 二. 分析 Groovy 中 Thread 类的 start 扩展方法 一.Groovy 扩展方法引入 Groovy 可以对 JDK 中的一些类进行 方法扩展 ...

  4. 【转】自然语言系列学习之表示学习与知识获取(五)融合文本和知识,利用cnn方法进行关系抽取

    本文重点放在怎么利用知识表示学习,辅助我们进行关系抽取,首先介绍如何利用分布式表示去融合知识和文本进行文本的抽取. 前文提到利用知识图谱学习了知识表示,就可以预测任意两个实体之间的关系,它是通过t-h ...

  5. python内置库绘制33角形_33 python format练习题 利用format方法生成一个星号三角形...

    第十五课 练习题 ''' 1. 编写一个Python程序,从控制台输入一个字符串(保存到变量s中), 然后通过while循环不断输入字符串(保存到变量subStr中), 并统计subStr在s中出现的 ...

  6. 利用ES6-Promise()方法封装原始jsonp实现跨域请求公用方法(告别使用JQuery封装好的jsonp)

    在项目中,经常需要用到jsonp实现跨域请求,假如使用JQuery封装好的jsonp方法,是很容易实现的,缺点:需要引入JQuery库. $.ajax({url : './package.json', ...

  7. 循环体内,字符串的连接方式,使用StringBuilder的append方法进行扩展

    循环体内,字符串的连接方式,使用StringBuilder的append方法进行扩展

  8. 第八节:语法总结(2)(匿名类、匿名方法、扩展方法)

    一. 匿名类 1. 传统的方式给类赋值,需要先建一个实体类→实例化→赋值,步骤很繁琐,在.Net 3.0时代,微软引入匿名类的概念,简化了代码编写,提高了开发效率.  匿名类的声明语法:  var o ...

  9. ES8新特性_ES8中对象方法的扩展---JavaScript_ECMAScript_ES6-ES11新特性工作笔记052

    然后我们来看es8中对对象方法的扩展., 首先看Object.values 我们声明一个对象,可以看到school,然后, 我们打印这个Ojbect.keys(school) 可以看到右边,获取到了, ...

最新文章

  1. try finally 中的return
  2. Centos(6、7) —— yum源的配置
  3. NOIP2018 退役记
  4. Linux php 中文乱码解决
  5. python求平均工资_python如何求列表平均值?
  6. 电脑遇到打印机脱机状态如何解决
  7. 中国高性能计算服务器排名,2007中国高性能计算100强出炉
  8. 自制QQ机器人插件笔记[nonebot2部署于ubuntu系统服务器]
  9. ROS中NodeHandle nh与NodeHandle nh(“~“)区别
  10. python中文乱码如何处理、如何处理跨域_解决Python发送Http请求时,中文乱码的问题...
  11. 怎么注册一个电子邮件账号?电子邮件地址怎么写?
  12. CHD搭建的环境中,解决用户权限的问题
  13. 医疗APP有哪些功能
  14. 使用selenium实现豆瓣电影信息的自动化搜索
  15. HTML怎么设置自动滚动的图片,转:HTML中让图片滚动的marquee标签的使用方法
  16. 2021最新最全前端面试题(包含HTML、CSS、JavaScript、Vue、React、浏览器、算法与数据结构等)
  17. 关于我学习线代的那些事
  18. 软件测试笔记(十六)- 缺陷轰炸和beta测试
  19. 1 invalid import format(s) Postman Collection Format v1 is no longer supported and can not be import
  20. linux 4TB硬盘 只识别2T,4TB移动硬盘电脑只能识别到2.2TB 是怎么回事?

热门文章

  1. MFC隐藏EditControl控件的光标
  2. opencv漫水填充算法
  3. Gym100923H Por Costel and the Match
  4. Leetcode-5063 Last Stone Weight(最后一块石头的重量)
  5. 【Luogu4921】情侣?给我烧了!(组合计数)
  6. [PHP]Phpexcel导入时间格式数据处理
  7. 学渣的心酸(求职篇)
  8. 1000个JQuery插件(转载)
  9. Java面试题-集合框架篇三
  10. 检测客户端是否安装 Silverlight 插件和判断IE是否安装或支持Silverlight(限IE)