laravel中使用macro方法实例举例

谢谢你啊

在一般编程中,我们要扩展一个基础类,我们需要进行继承才能扩充。然而Laravel利用PHP的特性,编写了一套叫做Macroable的Traits,这样,凡是使用Macroable的类,都是可以使用这个方法扩充的。

邮件发送动态设置

1
2
3
4
5
6
7
8
\Mail::macro('setConfig', function (string $key, string $domain) {

$transport = $this->getSwiftMailer()->getTransport();
$transport->setKey($key);
$transport->setDomain($domain);

return $this;
});

使用

1
2
3
4
5
6
7
8
9
10
11
public function build()
{

$to = 'lnmput@gmail.com';

$mailgunConfig = 'erp.template.'.$mailTplDir.'.mailgun.';

\Mail::setConfig(config($mailgunConfig.'secret'), config($mailgunConfig.'domain'));

return $this->to($to)->subject($subject)->from($mailFrom, $mailFromName)->view($view);
}

集合转小写

1
2
3
4
5
Collection::macro('uppercase', function () {
return collect($this->items)->map(function ($item) {
return strtoupper($item);
});
});

使用

1
collect(["hello", "world"])->uppercase();

自定义响应

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
\Response::macro('xml', function(array $vars, $status = 200, array $header = [], $xml = null)
{
if (is_null($xml)) {
$xml = new \SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><response/>');
}
foreach ($vars as $key => $value) {
if (is_array($value)) {
\Response::xml($value, $status, $header, $xml->addChild($key));
} else {
$xml->addChild($key, $value);
}
}
if (empty($header)) {
$header['Content-Type'] = 'application/xml';
}
return \Response::make($xml->asXML(), $status, $header);
});

使用

1
2
3
4
5
6
$data = ['status' => 'OK', 'data' => [
'name' => 'yangguoqi',
'age' => 27
]];

return Response::xml($data);

统计字符串中单词数量

1
2
3
4
5
6
use Illuminate\Support\Str;

Str::macro('countWords', function($value)
{
return str_word_count($value);
});

使用

1
$value = Str::countWords('This is test'); //3

字符串CSV转array

1
2
3
4
Str::macro('csvToArray', function ($string)
{
return array_filter(array_map('trim', str_getcsv($string)));
});

使用

1
2
3
$string = "some, crazy, , , , mixed, bag, of , comma-separated values, , ,";
$array = \Illuminate\Support\Str::csvToArray($string);
dd($array);

模型是否分页

1
2
3
4
5
6
7
Builder::macro('paginateIf', function($callback = true) {
if($callback) {
return $this->paginate();
}

return $this->get();
});

使用

1
$data = Model::oldest()->paginateIf($request->has('page'));

哪些类可以使用marco

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Illuminate\Database\Query\Builder
Illuminate\Database\Eloquent\Builder
Illuminate\Database\Eloquent\Relations\Relation
Illuminate\Http\Request
Illuminate\Http\RedirectResponse
Illuminate\Http\UploadedFile
Illuminate\Routing\Router
Illuminate\Routing\ResponseFactory
Illuminate\Routing\UrlGenerator
Illuminate\Support\Arr
Illuminate\Support\Str
Illuminate\Support\Collection
Illuminate\Cache\Repository
Illuminate\Console\Scheduling\Event
Illuminate\Filesystem\Filesystem
Illuminate\Foundation\Testing\TestResponse
Illuminate\Translation\Translator
Illuminate\Validation\Rule
Mail

等等,使用了Marcoable的Traits,如果是自己编写的类,使用了Marcoable,也可以这样扩充使用(写Laravel开源库的时候)

https://laravel-tricks.com/tricks/responsexml-macro