Laravel Macroを使ってみる

# 環境
Laravel10(sail)
https://readouble.com/laravel/10.x/ja/installation.html
↑↑この通りにやればサクッと環境が作れる

Mac
Apple M1 Max
sonoma 14.2.1


# Macroとは？

> A “macro” in Laravel refers to the ability to add additional methods or features to various classes or framework components without altering the original source code.
>
> Laravel’s macro feature enables developers to enhance the capabilities of fundamental Laravel classes such as Eloquent models, collections, query builders, and others.

Laravel の「マクロ」とは、元のソース コードを変更せずに、さまざまなクラスやフレームワーク コンポーネントに追加のメソッドや機能を追加する機能を指します。

Laravel のマクロ機能を使用すると、開発者はEloquent モデル、コレクション、クエリ ビルダーなどの基本的な Laravel クラスの機能を強化できます。

参考: https://medium.com/@online-web-tutor/laravel-10-how-to-create-macro-with-examples-tutorial-d17359dcdf6d#:~:text=A%20%E2%80%9Cmacro%E2%80%9D%20in%20Laravel%20refers,altering%20the%20original%20source%20code.

# 利用手順
1.　マクロの作成
1.　サービスプロバイダに登録

# 簡単なマクロを登録してみる
マクロの作成をサービスプロバイダでやれば一気にできます。
AuthServiceProviderに作成してみる。
### マクロ作成と登録
bootメソッドに記載して、
Illuminate\Support\Strクラスを拡張して、`isLength`を使えるようにする。

文字列と数値を与えて、文字列の文字数と数値が等しいか判定するメソッドです。

```php:app/Providers/AppServiceProvider.php
<?php

namespace App\Providers;

use Illuminate\Support\Str;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     */
    public function register(): void
    {
        //
    }

    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        // 以下を記載
        Str::macro('isLength', function (string $string, int $length) {
            return static::length($string) === $length;
        });
    }
}
```

これでisLengthというのがStr::isLengthというのが使える。

tinkerを使って試す。

```console
sail@6e3e743493e6:/var/www/html$ php artisan tinker
Psy Shell v0.11.18 (PHP 8.2.6 — cli) by Justin Hileman
> Str::isLength('Laravel', 7);
= true

> Str::isLength('Laravel', 4);
= false
```

ちなみにマクロの登録をする前は↓↓
```console
sail@6e3e743493e6:/var/www/html$ php artisan tinker
Psy Shell v0.11.18 (PHP 8.2.6 — cli) by Justin Hileman
> Str::isLength('Laravel', 4);

   BadMethodCallException  Method Illuminate\Support\Str::isLength does not exist.
```

# 複数のマクロを登録
実務上では単一のマクロ登録でなく、複数使うことが多いかと思います。
そういう複数登録する場合も便利な方法が提供されています。Laravelさんありがとう。

### 追加したいメソッドの定義
app/Mixinsというディレクトリを作成し、そこに追加したいメソッドを記載する。

```php:app/Mixins/StrMixin.php
<?php

namespace App\Mixins;

class StrMixin
{
    public function isLength()
    {
        return function ($string, $length) {
            return static::length($string) === $length;
        };
    }

    public function appendTo()
    {
        return function ($string, $char) {
            return $string.$char;
        };
    }
}
```

### メソッドの登録
```php:AuthServiceProvider.php
    public function boot(): void
    {
        Str::Mixin(new StrMixin());
        // 先ほどのはコメントアウトしておく
        // Str::macro('isLength', function (string $string, int $length) {
        //     return static::length($string) === $length;
        // });
    }
```

### 動作確認
```console
sail@6e3e743493e6:/var/www/html$ php artisan tinker
Psy Shell v0.11.18 (PHP 8.2.6 — cli) by Justin Hileman
> Str::isLength('dd', 2)
= true

> Str::isLength('dd', 3)
= false

> Str::appendTo('laravel', '@');
= "laravel@"
```