Laravel Macros: Extend Core Classes with Your Own Magic Methods

Category : Laravel Advanced Tips Publish At : 21 Oct, 2025

Share On :

Introduction

Imagine you need to repeat a small logic across your Laravel project —like formatting phone numbers, cleaning strings, or sending standardized responses.

Sure, you could create a helper function or a service class.

But Laravel gives you something cleaner and framework-native — Macros. Macros let you extend built-in Laravel classes (like Str, Collection, Response, Request, etc.) with your own custom reusable methods.

Let’s see how to use them smartly in a real project.

What Are Laravel Macros?

A macro is simply a custom method you can “attach” to an existing Laravel class.

For example, you can make your own method like this:

Str::macro('maskEmail', function ($email) {
    $parts = explode('@', $email);
    return substr($parts[0], 0, 3) . '****@' . $parts[1];
});
echo Str::maskEmail('vivek@example.com');
// Output: viv****@example.com

Now you can use Str::maskEmail() anywhere — it behaves like a native Laravel helper.

Where to Register Macros

You can register your macros in the AppServiceProvider inside the boot() method, or even better, create a dedicated MacroServiceProvider.

namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Str;
use Illuminate\Support\Collection;
class MacroServiceProvider extends ServiceProvider
{
    public function boot()
   
{
        // Example 1: String Macro
        Str::macro('excerpt', function ($text, $limit = 100) {
            return strlen($text) > $limit ? substr($text, 0, $limit) . '...' : $text;
        });
        // Example 2: Collection Macro
        Collection::macro('toUpper', function () {
            return $this->map(fn($item) => strtoupper($item));
        });
    }
}

Real-World Use Cases

1. Custom JSON Response Macro

You can extend Laravel’s response builder for cleaner, standardized API responses:

use Illuminate\Support\Facades\Response;
Response::macro('success', function ($data = [], $message = 'Success', $status = 200) {
    return Response::json([
        'status' => true,
        'message' => $message,
        'data' => $data,
    ], $status);
});

Now in your controllers:

return response()->success($user, 'User fetched successfully!');

2.Request Macro: Sanitize Input

You can clean up inputs automatically before using them.

use Illuminate\Http\Request;
Request::macro('trimAll', function () {
    return collect($this->all())
        ->map(fn($value) => is_string($value) ? trim($value) : $value)
        ->toArray();
});

Usage in a controller:

$data = request()->trimAll();