Accessors و Mutators در لاراول

accessorها و mutatorها قابلیت سفارشی دارند، یعنی کاربر می‌تواند با تعریف آنها، خصیصه های Eloquent را تغییر دهد. accessorها زمانی که بخواهیم یک خصیصه را از دیتابیس بگیریم، عمل می‌کند در حالی که mutatorها زمانی فرمت انجام می‌دهند که بخواهیم بر روی دیتابیس ذخیره کنیم.

تعریف یک accessor

نحوه تعریف یک accessor به شکل ()getFooAttribute است به طوری که Foo با حرف بزرگ در اول آن، یک attribute است که می‌خواهیم به آن دسترسی داشته باشیم. اگر attribute شما first_name باشد، و شما با اطمینان بخواهید که هرگاه آن را واکشی کردید، حرف اول آن بزرگ باشد، باید یک accessor به صورت زیر بنویسید:


public function getFirstNameAttribute($value)
{
    return ucfirst($value);
}

مطمئنا این یک مثال خیلی عمومی برای مطالعه و درک درست مفهوم accessor است اما می‌توان از آن برای فرمت تاریخ‌ها، قیمت‌ها و غیره استفاده کرد.

بگذارید فرض کنیم شما یک مدل Member با فیلدهای زیر دارید:

  • first_name
  • last_name
  • email
  • password
  • last_visit
  • settings
  • created_at
  • updated_at

ما چند فیلد داریم که می‌توانیم برای اونها از مزیت accessorها استفاده کنیم. برای مثال، کاربران اکثرا بی‌دقتی به خرج می‌دهند و شما می‌خواهید اطمینان داشته باشید که نام کوچک و بزرگ هر شخص با حروف بزرگ شروع شود.

برای ایجاد یک Member از کدی شبیه به این باید استفاده کنید و البته که شما این اطلاعات را از کاربر دریافت خواهید کرد:


$user = App\Member::create([
    'first_name'  => 'mirza',
    'last_name'   => 'pasic',
    'email'       => 'mirza.pasic@bosnadev.com',
    'password'    => '!supersecretpassword!',
    'last_login'  => Carbon\Carbon::now(),
    'settings'    => ['two_factor_aut' => false, 'session_time' => 1200],
    'created_at'  => Carbon\Carbon::now(),
    'updated_at'  => Carbon\Carbon::now()
]);

ممکن است من یک یوزر بی‌توجه باشم و دقتی به اینکه باید نامم را با حروف بزرگ بنویسم، نداشته باشم، اما شما همچنان می‌خواهید که نام من به درستی در سایت نمایش داده شود، درسته؟ اینجاست که accessorها به کار می‌آیند:


use Illuminate\Database\Eloquent\Model;

/**
 * Class Member
 * @package App
 */
class Member extends Model
{
    /**
     * Make sure that first name is always capitalized when retrieved from the database
     * 
     * @param $value
     * @return string
     */
    public function getFirstNameAttribute($value)
    {
        return ucfirst($value);
    }

    /**
     * Make sure that last name is always capitalized when retrieved from the database
     * 
     * @param $value
     * @return string
     */
    public function getLastNameAttribute($value)
    {
        return ucfirst($value);
    }
}

همچنین شما می‌توانید با استفاده از accessorها دو attribute واقعی را برای ساخت یک attribute جدید استفاده کنیم. در این مثال، به سادگی می‌بینید که من یک attribute به نام full name ساخته‌ام. شما می‌توانید accessor را به صورت زیر بسازید:


    /**
     * Get members full name
     * 
     * @return string
     */
    public function getFullNameAttribute()
    {
        return ucfirst($this->first_name) . ' ' . ucfirst($this->last_name);
    }

سپس شما به روش زیر می‌توانید از آن استفاده کنید:


$member = App\Member::find(1);

echo $member->full_name;

شما می‌توانید آن را برای date نیز استفاده کنید. با accessorها شما می‌توانید تعیین کنید که یک date با چه فرمتی نمایش داده شود. در اکثر کشورهای اروپایی نمایش تاریخ متفاوت از کشور آمریکاست. شما می‌توانید با استفاده از accessor این فرمت را نزدیک به کاربران خود نمایش دهید. برای مثال:


    /**
     * Custom format for the last login date
     * 
     * @param $value
     * @return string
     */
    public function getLastLoginAttribute($value)
    {
        return \Carbon\Carbon::parse($value)->format('d.m.Y.');
    }

وقتی شما last_login را فراخوانی می‌کنید، خروجی زیر را مشاهده خواهید کرد:


$member = App\Member::find(1);
echo $member->last_login;

// 15.12.2015.

تعریف یک mutator

نحوه تعریف یک Mutator به صورت ()setFooAttribute است که Foo فیلدی است که می‌خواهید به آن دسترسی داشته باشید. بنابراین، بزارید فیلدهای first_name و last_name را پیش از ذخیره شدن در دیتابیس طبق آنچه پیشتر گفتیم، اصلاح کنیم:


    /**
     * Make sure that first name is capitalized BEFORE saving it to the database
     * 
     * @param $value
     * @return string
     */
    public function setFirstNameAttribute($value)
    {
        $this->attributes['first_name'] = ucfirst($value);
    }

    /**
     * Make sure that last name is capitalized BEFORE saving it to the database
     * 
     * @param $value
     * @return string
     */
    public function setLastNameAttribute($value)
    {
        $this->attributes['last_name'] = ucfirst($value);
    }

شما ممکن است دقت کرده باشید که ما در اینجا چیزی برنمی‌گردانیم. ما مستقیما به attribute دسترسی داشته و آنرا تنظیم می‌کنیم. با این عملکرد، می‌توانیم مطمئن باشیم که نام و نام خانوادگی کاربران همواره با حروف بزرگ شروع شود.

مثال های بیشتر

من به شما مثال های خیلی ساده از متودهای accessor و mutator نشان خواهم داد. اما شما می‌توانید بیشتر تست کرده و من شرایط مختلف را هم برای استفاده به شما خواهم گفت.

هش کردن پسوردها

مطمئنا شما پیش از اینکه رمز عبور را در دیتابیس ثبت کنید، می‌خواهید آنها را هش کنید. Mutatorها یک راه مطمئن برای دست‌یابی به این موضوع هستند.


public function setPasswordAttribute($value) {
    $this->attributes['password'] = Hash::make($value);
}

با این روش، شما مطمئنید که رمز عبور همیشه قبل از اینکه در دیتابیس ذخیره شود، هش می‌گردد. من اینجا از فساد Hash در لاراول برای ایجاد رمز عبور هش شده استفاده کردم، اما شما می‌توانید از متود کمکی ()bcrypt نیز استفاده نمایید.

JSON ENCODING

اگر یک بار دیگر به مدل Member ما در ابتدای آموزش توجه کنید، می‌بینید که خصیصه settings برای ذخیره‌سازی اطلاعات شخصی کاربران و امکاناتی که در برنامه شما لحاظ گشته، ایجاد شده است. طبیعتا ممکن است که شما برای مدیریت این امکانات از آرایه استفاده کنید و یکی از بهترین راه‌ها برای ذخیره کردن یک آرایه encode کردن به یک رشته JSON است.

برای خصیصه  settings شما به یک accessor برای decode رشته JSON به آرایه و یک mutator برای encode آرایه به رشته JSON نیاز دارید.


/**
 * Make sure that we get an array from JSON string 
 *
 * @param $value
 * @return array
 */
public function getSettingsAttribute($value) {
    return json_decode($value, true);
}


/**
 * Encode an array to a JSON string
 * 
 * @param $value
 */
public function setSettingsAttribute($value)
{
    $this->attributes['settings'] = json_encode($value);
}

مثال کامل

و در آخر، من یک مدل کامل از Member که در این مقاله استفاده کردم، در اینجا آورده ام:


first_name) . ' ' . ucfirst($this->last_name);
    }

    /**
     * Custom format for the last login date
     *
     * @param $value
     * @return string
     */
    public function getLastLoginAttribute($value)
    {
        return \Carbon\Carbon::parse($value)->format('d.m.Y.');
    }

    /**
     * Make sure that first name is capitalized BEFORE saving it to the database
     *
     * @param $value
     * @return string
     */
    public function setFirstNameAttribute($value)
    {
        $this->attributes['first_name'] = ucfirst($value);
    }

    /**
     * Make sure that last name is capitalized BEFORE saving it to the database
     *
     * @param $value
     * @return string
     */
    public function setLastNameAttribute($value)
    {
        $this->attributes['last_name'] = ucfirst($value);
    }

    /**
     * Make sure that password is encrypted
     *
     * @param $value
     */
    public function setPasswordAttribute($value) {
        $this->attributes['password'] = Hash::make($value);
    }

    /**
     * Make sure that we get an array from JSON string
     *
     * @param $value
     * @return array
     */
    public function getSettingsAttribute($value) {
        return json_decode($value, true);
    }


    /**
     * Encode an array to a JSON string
     *
     * @param $value
     */
    public function setSettingsAttribute($value)
    {
        $this->attributes['settings'] = json_encode($value);
    }

و چگونگی استفاده از آن نیز اینگونه است:


Route::get('members', function() {
    $user = App\Member::create([
        'first_name'  => 'mirza',
        'last_name'   => 'pasic',
        'email'       => 'mirza.pasic@bosnadev.com',
        'password'    => '!supersecretpassword!',
        'last_login'  => Carbon\Carbon::now(),
        'settings'    => ['two_factor_aut' => true, 'session_time' => 1200],
        'created_at'  => Carbon\Carbon::now(),
        'updated_at'  => Carbon\Carbon::now()
    ]);
    
    $member = App\Member::find(1);
    echo $member->last_login . '
'; echo $member->full_name . '
'; });

واقعا من امیدوارم که تونسته باشم مفهوم mutator و accessor را به شما توضیح بدم و امیدوارم اگر تا پیش از این نمی‌دونستید چه کاربردهایی دارند، حالا برای استفاده از آنها در پروژه هایتان، استفاده کنید.

کامنت ها (0)

ارسال نظر