چگونه با استفاده از Macro کلاس های هسته ی لاراول را گسترش دهیم؟

حمید تیموری 555 بازدید 1399/01/21
چگونه با استفاده از Macro کلاس های هسته ی لاراول را گسترش دهیم؟

امروز قصد دارم Laravel Macros رو آموزش بدم. Macro یک ویژگی قدرتمند در لاراول است که به شما اجازه میدهد که توابع شخصی خودتان را به هسته ی لاراول اضافه کنید.

به عبارت ساده ، Laravel Macro راهی است برای اضافه کردن برخی قابلیت های از دست رفته به component داخلی Laravel با یک تکه کدی که در لاراول کلا وجود ندارد.
برای مثال کلاس Response را که در مسیر Illuminate\Http\Response است چک کنید و میبینید که از Macroable Trait استفاده میکند که به این معنی است که میتوانید به کلاس Response توابع خودتان را اضافه کنید.

همه کلاس های Macroable در لاراول
کلاس های لاراولی که از  Illuminate\Support\Traits\Macroable trait استفاده میکنند اجازه دارند Macro بسازند. کلاس های زیر از معمول ترین کلاس هایی هستند که Macro میسازند.

 

  • Request: Illuminate\Http\Request
  • Response: Illuminate\Http\Response
  • Collection: Illuminate\Support\Collection
  • Str: Illuminate\Support\Str
  • Router: Illuminate\Routing\Router
  • UrlGenerator: Illuminate\Routing\UrlGenerator
  • Cache: Illuminate\Cache\Repository
  • Filesystem: Illuminate\Filesystem\Filesystem
  • Arr: Illuminate\Support\Arr
  • Rule: Illuminate\Validation\Rule


باز هم کلاس و فسادهایی هستند که از Macroable Trait استفاده میکنند و شما میتوانید آنها را پیدا کنید


مثال:
قبل از اینکه یک Macro بسازید باید مطمئن شوید که کلاسی که قصد ساختن Macro برای آن را دارید از Macroable Trait استفاده میکند.
در این مقاله ما قصد داریم یک Macro برای Illuminate\Support\Str بسازیم که در آن طول رشته،  بررسی میشود و اسم آن isLenght است.
فایل AppServiceProvider  را باز کنید و در متد boot کد زیر را بنویسید

app/Providers/AppServiceProvider.php
namespace App\Providers;

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::macro('isLength', function ($str, $length) {

            return static::length($str) == $length;
        });
    }
}

طبق کد بالا ما در فایل AppServiceProvider در متد boot یک Macro نوشتیم که دو پارامتر قبول میکند و یک مقایسه ساده انجام میدهد. ماکرو ها میتوانند با توجه به نیاز شما پارامترهای متعددی قبول کنند.
نکته ی مهم این است که ما در Macro ای که نوشته ایم از static::lenght که یک ماکرو از پیش تعریف شده است، استفاده کرده ایم. بنابراین موقع تعریف Macro به متد و خواص دیگر آن کلاسی که ماکرو را برای آن نوشته اید نیز دسترسی دارید.

حالا برای استفاده از این Macro یک Route تعریف میکنیم:

use Illuminate\Support\Str;

Route::get('/', function(){

   dd(Str::isLength('This is a Laravel Macro', 23)); //true

});

مکانیسم داخلی Macroable Trait این امکان را به شما میدهد که هم به صورت statick و هم با instance سازی صدا زده شوند.


زمانی که ما تعدادی Macro به AppServiceProvider اضافه کنیم، کم کم خواهیم دید که این فایل نامرتب و شلوغ میشود. بنابراین میتوانیم یک کلاس بسازیم و Macro های خود را درآن قرار دهیم.
حالا یک کلاس به نام StrMixin در مسیر app/Mixins میسازیم و Macro های خود را در آن اضافه میکنیم:

namespace App\Mixins;

class StrMixin
{

    /**
     * @return \Closure
     */
    public function isLaraman()
    {
        return function ($str) {
            return strtolower($str) == 'laraman';
        };
    }

    /**
     * @return \Closure
     */
    public function isLength()
    {
        return function ($str, $length) {
            return static::length($str) == $length;
        };
    }

    /**
     * @return \Closure
     */
    public function appendTo()
    {
        return function ($str, $char) {
            return $char . $str;
        };
    }

}

حالا در فایل AppServiceProvider آن ماکرو که قبلا نوشتیم را پاک میکنیم و از متد mixin که از متدهای لاراول است استفاده میکنیم که Macro های جدید را به کلاس مورد نظر نسبت دهیم!

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);
    }
}

حالا اگر تست کنید خواهید دید که سه تابع isLaraman ، isLenght و appendTo برای کلاس Str قابل استفاده هستند!
امیدوارم این مطلب برای شما مفید باشد.

اگر سوالی داشتید از قسمت نظرات میتونید بپرسید...

دیگر مقالات
حمید تیموری 1631 بازدید 1397/05/14
حمید تیموری 1659 بازدید 1397/10/12
حمید تیموری 365 بازدید 1398/06/03
حمید تیموری 904 بازدید 1397/07/01
حمید تیموری 589 بازدید 1399/03/16


نظرات (0)
هنوز نظری ثبت نشده است
برای ثبت نظر ابتدا وارد سایت شوید