在 Laravel 6.0 使用 Macros 巨集

前言

Laravel 提供一個 Macroable 特徵機制,用來擴展基礎類別。

Str 類別

Str 類別為例,新增 app/Mixins/StrMixin.php 檔:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
namespace App\Mixins;

class StrMixin
{
/**
* @return \Closure
*/
public static function uppercase()
{
return function ($value) {
return strtoupper($value);
};
}
}

app/Providers/AppServiceProvider.php 檔註冊:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
namespace App\Providers;

use App\Mixins\StrMixin;
use Illuminate\Support\Str;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}

/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Str::mixin(new StrMixin());
}
}

使用:

1
echo Str::uppercase('test');

結果:

1
TEST

Collection 類別

Collection 類別為例,新增 app/Mixins/CollectionMixin.php 檔:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
namespace App\Mixins;

class CollectionMixin
{
/**
* @return \Closure
*/
public function uppercase()
{
return function () {
return collect($this->items)->map(function ($item) {
return strtoupper($item);
});
};
}
}

app/Providers/AppServiceProvider.php 檔註冊:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
namespace App\Providers;

use App\Mixins\CollectionMixin;
use Illuminate\Support\Collection;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}

/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Collection::mixin(new CollectionMixin());
}
}

使用:

1
return collect(['test'])->uppercase()->toArray();

結果:

1
["TEST"]

ResponseFactory 類別

以 ResponseFactory 類別為例,新增 app/Mixins/ResponseMixin.php 檔:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
namespace App\Mixins;

class ResponseMixin
{
/**
* @return \Closure
*/
public function error()
{
return function ($error) {
return [
'error' => $error,
];
};
}
}

app/Providers/AppServiceProvider.php 檔註冊:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
namespace App\Providers;

use App\Mixins\ResponseMixin;
use Illuminate\Routing\ResponseFactory;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}

/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
ResponseFactory::mixin(new ResponseMixin());
}
}

使用:

1
return Response::error('test');

結果:

1
2
3
{
"error": "test"
}

服務提供者

新增一個 MixinServiceProvider 服務提供者來集中管理所有的 Mixin 類別。

1
php artisan make:provider MixinServiceProvider

修改 MixinServiceProvider 服務提供者。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
namespace App\Providers;

use App\Mixins\CollectionMixin;
use App\Mixins\ResponseMixin;
use App\Mixins\StrMixin;
use Illuminate\Routing\ResponseFactory;
use Illuminate\Support\Collection;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Str;

class MixinServiceProvider extends ServiceProvider
{
/**
* Register services.
*
* @return void
*/
public function register()
{
//
}

/**
* Bootstrap services.
*
* @return void
*/
public function boot()
{
Str::mixin(new StrMixin());
Collection::mixin(new CollectionMixin());
ResponseFactory::mixin(new ResponseMixin());
}
}

修改 config 資料夾的 app.php 檔,以註冊服務提供者:

1
2
3
4
5
6
'providers' => [

// ...
App\Providers\MixinServiceProvider::class,

],

補充

所有帶有巨集的類別有以下:

  • Illuminate\Auth\RequestGuard
  • Illuminate\Auth\SessionGuard
  • Illuminate\Cache\Repository
  • Illuminate\Console\Command
  • Illuminate\Console\Scheduling\Event
  • Illuminate\Cookie\CookieJar
  • Illuminate\Database\Eloquent\FactoryBuilder
  • Illuminate\Database\Eloquent\Relations\Relation
  • Illuminate\Database\Grammar
  • Illuminate\Database\Query\Builder
  • Illuminate\Database\Schema\Blueprint
  • Illuminate\Filesystem\Filesystem
  • Illuminate\Foundation\Testing\TestResponse
  • Illuminate\Http\JsonResponse
  • Illuminate\Http\RedirectResponse
  • Illuminate\Http\Request
  • Illuminate\Http\Response
  • Illuminate\Http\UploadedFile
  • Illuminate\Mail\Mailer
  • Illuminate\Routing\PendingResourceRegistration
  • Illuminate\Routing\Redirector
  • Illuminate\Routing\ResponseFactory
  • Illuminate\Routing\Route
  • Illuminate\Routing\Router
  • Illuminate\Routing\UrlGenerator
  • Illuminate\Support\Arr
  • Illuminate\Support\Collection
  • Illuminate\Support\LazyCollection
  • Illuminate\Support\Str
  • Illuminate\Support\Testing\Fakes\NotificationFake
  • Illuminate\Translation\Translator
  • Illuminate\Validation\Rule
  • Illuminate\View\Factory
  • Illuminate\View\View

參考資料