Fork me on GitHub

如何利用macro方法来扩展Laravel的基础类的功能


你只见到这么多人说他不好时,却看到他有出来说別人一句吗?

Laravel 5.2 provides some nice additions to the framework. One handy feature that I don’t see listed in the release notes is that Collection now is macroable. Using it’s macro function you can easily extend Illuminate\Support\Collection with your own custom functions.

Take a look at this piece of code to uppercase every string in a collection.

1
2
3
$uppercaseWords = collect(['code', 'ferengi'])->map(function($word) {
return strtoupper($word);
});

That’s good code, but image you need to uppercase a lot of collections. Typing the same closure will get very tiresome. Let’s improve this with a macro.

1
2
3
4
5
6
7
8
9
use Illuminate\Support\Collection;
Collection::macro('uppercase', function() {
return collect($this->items)->map(function($word) {
return strtoupper($word);
});
});

You could create a service provider to load up these macro’s. Now that the macro is defined let’s uppercase collections like there’s no tomorrow:

1
2
3
$uppercaseWords = collect(['code', 'ferengi'])->uppercase();
$moreUppercaseWords = collect(['love', 'the', 'facade'])->uppercase();
$evenMoreUppercaseWords = collect(['activerecord', 'forever'])->uppercase();

You could be thinking “Why should I use a macro? I can easily to this with a regular function.”. Consider this piece of code.

1
2
3
4
5
function uppercase($collection) {
...
}
$uppercaseWords = uppercase(collect(['halo','five']));

It works, but you have to encapsulate the collection with your function. The last executed function is put first, which is confusing. With macro’s you can still chain functions and greatly improve readability.

1
2
3
4
5
6
7
8
9
//lots of functions
function4(function3(function2(function1(collect(['jack','cheats'])))));
//lots of macros
collect(['i', 'want', 'to', 'live', 'in', 'a', 'desert'])
->function1()
->function2()
->function3()
->function4();

Sure, the examples use in this post were a bit contrived, but I hope you see that collection macro’s can be very handy.

https://murze.be/using-collection-macros-in-laravel