Laravel 8 beginner insights

Implementing An Array Extension Method in Laravel 8

Edwin Klesman
Apr 22 · 4 min read
Lean how to Extend the Laravel Collection class with custom functionality using macros in this article: Implementing An Array Extension Method In Laravel 8

This post is the second one in a series of articles titled Laravel 8 Beginner Insights that reflect what I’ve learned while using Laravel 8 for a side project for the first time:

  1. Populate your Laravel Project’s Database With Initial Data
  2. Implementing An Array Extension Method In Laravel 8
  3. Debug Your Laravel Project From Front to Back With Telescope

While working on my side-project, a Clubhouse profile editor named Clubprofile.xyz, I found myself needing functionality that could prefix/postfix the string values in an array.

Coming from a .Net background, I was looking for a way to create some kind of extension method for arrays. Also, I wanted to make the functionality available throughout my entire project.

As it turns out, Laravel 8 got this covered by providing something called Macros.

What is a Laravel Macro? 🤔

As Microsoft writes in their documentation about Extension methods:

Extension methods enable you to “add” methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. Extension methods are static methods, but they’re called as if they were instance methods on the extended type.

I mentioned earlier, Laravel has a mechanism that’s quite similar to Extension Methods, called Macros.

It is quite similar to extension methods, but unlike Extension Methods in C#, you can’t append functionality to every class.
As it appears, not all core Laravel classes have the Macroable trait. The following core classes are the most used core classes when it comes to expanding them with your functions:

  1. Request: Illuminate\Http\Request
  2. Response: Illuminate\Http\Response
  3. Collection: Illuminate\Support\Collection
  4. Str: Illuminate\Support\Str
  5. Router: Illuminate\Routing\Router
  6. UrlGenerator: Illuminate\Routing\UrlGenerator
  7. Cache: Illuminate\Cache\Repository
  8. Filesystem: Illuminate\Filesystem\Filesystem
  9. Arr: Illuminate\Support\Arr
  10. Rule: Illuminate\Validation\Rule

If you remember the title, you know my goal was to add functionality to arrays, and “arrays” are part of what is called Collections in the Laravel framework.

Adding a Macro to Arrays in Laravel ➕

The Collection class is a wrapper around an array ( a list of elements), and has functionality like counting the elements and writing & retrieving each value in the collection.

As you’ve seen in the previous part, Collection also has the Macroable trait, which makes it easier for us to expand with a macro function.

Let’s assume we want to create a function that converts all the characters in an array’s element value to UPPERCASE, and that we want to be able to use it everywhere.

When you follow the docs on extending Collection, you see that our example use case is quite easy to implement using the macro function:

use Illuminate\Support\Collection;
use Illuminate\Support\Str;

Collection::macro('toUpper', function () {
return $this->map(function ($value) {
return Str::upper($value);
});
});

$collection = collect(['first', 'second']);

$upper = $collection->toUpper();
// ['FIRST', 'SECOND']

Making YOUR Macro Available Throughout Your Project’s Code 💻

The right place to register services in your Laravel solution is the AppServiceProvider. This is a service provider class provided by the framework, in which you can register things like services, but also Macro definitions.

By defining your macro in the AppServiceProvider’s Boot() function, you make sure that the framework first loads any other service providers, and then appends the macro functions you defined onto the core functionality — in our case, the Collection class:

<?php 
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Collection;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
...
}

/**
* Bootstrap any application services.
* @return void
*/
public function boot()
{
//Collection Macros
Collection::macro('toUpper', function () {
return $this->map(function ($value) {
return Str::upper($value);
});
});
}
}

From this point on, you can call your toUpper function on any collection like so:

$uppercaseValues = myCollection->toUpper(); 

BONUS: Cleaner Code With Multiple Macros 🧹

Let’s assume that your project requires you to set up many macros to keep your coding logic cleaner.

You wouldn’t want to end up with 10+ macros “polluting” your AppServiceProvider class, right?

Let me show you how you can keep your AppServiceProvider nice and tidy in this bonus part.

Laravel provides a mechanism called Mixins; this allows you to code your macros in a separate class, that you can “mix into” your AppServiceProvider class (makes sense, huh?).

Your AppServiceProvider’s boot() function can be adjusted as following to add your mixin file:

...  /**
* Bootstrap any application services.
* @return void
*/
public function boot()
{
//replaced the macro definition with the mixin call
Collection::mixin(new CollectionMacros);
}
...

The CollectionMacros class with our macro in it would look like this:

class CollectionMacros
{
Collection::macro('toUpper', function () {
return $this->map(function ($value) {
return Str::upper($value);
});
});
}

This keeps your AppServiceProvider cleaner and lets you separate your mixins (perhaps per extended core class?).

To Conclude

I hope you enjoyed reading about how you can extend core functionality — like the collection wrapper used in Laravel — and how you can make it available throughout your entire Laravel project’s code.

The extensibility and thoughtfulness of the Laravel framework really is a beauty that I’ve discovered while working my way on finding my way towards implementing an array extension method in Laravel 8.

Code Hard, Ship Harder 🔥

Shipharder.com

Features mindshaping content on how to build viable…

Edwin Klesman

Written by

Team lead @Detacom | cross-platform | mobiledev | apps | Azure | Xamarin | Saas | ♥family+movies+food | created www.washem.app | Owner www.eekayonline.com

Shipharder.com

Features mindshaping content on how to build viable products

Edwin Klesman

Written by

Team lead @Detacom | cross-platform | mobiledev | apps | Azure | Xamarin | Saas | ♥family+movies+food | created www.washem.app | Owner www.eekayonline.com

Shipharder.com

Features mindshaping content on how to build viable products

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store