توسعه دهنده Back-End
با معجزه ماکروها در لاراول آشنا شوید
ابتدا به قطعه کد زیر نگاهی بندازیم که برای uppercase کردن محتویات یک کالکشن به کار می رود:
$uppercaseWords = collect(['code', 'ferengi'])->map(function($word) {
return strtoupper($word);
});
خب این کد مشکلی نداره ولی تصور کنید که بخواهیم تعداد زیادی کالکشن رو uppercase کنیم! تایپ کردن و تکرار این قطعه کد خیلی خسته کننده خواهد شد، اینطور نیست ؟
خب پس بیاید به کمک ماکروها که جزء ویژگی های جدید لاراول هستند کدمون رو بهبود بدهیم.
use Illuminate\Support\Collection;
Collection::macro('uppercase', function() {
return collect($this->items)->map(function($word) {
return strtoupper($word);
});
});
حالا که ماکروی خودمون رو تعریف کردیم، پس بیاید ازش استفاده کنیم:
$uppercaseWords = collect(['code', 'daily'])->uppercase();
$moreUppercaseWords = collect(['code', 'every', 'day'])->uppercase();
$evenMoreUppercaseWords = collect(['laravel', 'facade'])->uppercase();
خب شاید شما بگویید که " من می تونستم این کار رو یا یک فانکشن ساده هم انجام بدهم" حتما به این صورت:
function uppercase($collection) {
...
}
$uppercaseWords = uppercase(collect(['hello','Iran']));
بله می شود این کار رو کرد ولی توجه داشته باشید که شما با استفاده از ماکروها همچنان میتونید از فانکشن هاتون رو chain کنید و کد شما خوانایی بهتری خواهد داشت.
//lots of functions
function4(function3(function2(function1(collect(['Ali','Iran'])))));
//lots of macros
collect(['i', 'want', 'to', 'live', 'in','peace'])
->function1()
->function2()
->function3()
->function4();
یه مثال کاربردی تر دیگه روی کامپوننت Request لاراول بگیم، مثلا اگه بخواهیم، دامین اصلی رکوئست رو تشخیص بدهیم با استفاده از ماکرو ها به این صورت می تونیم:
Request::macro('isTld', function ($tld) {
return Str::is('*.' . $tld, $this->root());
});
اون نامگذاری متغیر tld$ برای مخفف کلمات Top Level Domainهست، مثل com. یا net.
حالا به راحتی می تونیم در رکوئست ها دامنه اصلی رو چک کنیم
Request::isTld('com') // returns true for app.com
Request::isTld('dev') // returns false for app.dev
یه ماکرو پیشرفته تر که بر اساس TLD یک where به مدل اضافه میکنه
Builder::macro('whenTldMatches', function($tld, $callback) {
if (Request::isTld($tld)) {
call_user_func($callback->bindTo($this));
}
return $this;
});
SomeModel::whenTldMatches('org', function () {
$this->where('id', '>', 5);
})->get();
// applies ->where() on app.org but not app.com
حالا شاید بپرسید کجا ماکروها رو تعریف کنم ؟
ء Service providers ها جای خوبی برای تعریف ماکرو ها هستند. مثلا App\Providers\AppServiceProvider
ولی پیشنهاد میکنم برای ماکروها یه سرویس پرووایدر ایجاد کنید مثلا App\Providers\MacrosServiceProvider
برای کدوم کامپوننت ها می تونیم ماکرو بنویسیم ؟
تقریبا برای همشون مثل فسادهایی مانند:
- Cache
- File
- Lang
- Request
- Response
- Route
- URL
یا کلاس هایی مثل:
- Illuminate\Database\Eloquent\Relation
- Illuminate\Support\Collection
- Illuminate\Routing\ResponseFactory
جالبه نه ؟ به relationship ها می تونید ماکرو اضافه کنید، مثلا :
HasMany::macro('toHasOne', function() {
return new HasOne(
$this->getQuery,
$this->getParent,
$this->foreignKey,
$this->localKey
);
});
که میاد و آخرین عنصر یک رابطه مشخص رو میگیره.
مطلبی دیگر از این انتشارات
کاربرد vue.js بیشتر برای چه کاریه
مطلبی دیگر از این انتشارات
OctoberCMS - اکتبر سی ام اس
مطلبی دیگر از این انتشارات
نسخه جاواسکریپتی لاراول!