نسخه:

الکوئنت: دگرسان

معرفی

هنگام بازیابی یا تنظیم مقادیر مشخصه Eloquent در نمونه‌های مدل، ابزارهای دسترسی و جهش‌دهنده‌ها به شما امکان می‌دهند که آن‌ها را قالب‌بندی کنید. به عنوان مثال، ممکن است بخواهید از رمزگذار لاراول برای رمزگذاری یک مقدار در زمانی که در پایگاه داده ذخیره می شود، استفاده کنید، و سپس زمانی که به آن در مدل Eloquent دسترسی پیدا می کنید، ویژگی را به طور خودکار رمزگشایی کنید.

علاوه بر دسترسی‌ها و جهش‌دهنده‌های سفارشی، Eloquent همچنین می‌تواند فیلدهای تاریخ را به‌طور خودکار به نمونه‌های Carbon ارسال کند یا حتی فیلدهای متنی را به JSON ارسال کند .

لوازم جانبی و جهش دهنده ها

تعریف اکسسوری

برای تعریف یک Accessor، getFooAttribute روشی را در مدل خود ایجاد کنید که در آن Foo نام ستونی که می‌خواهید به آن دسترسی داشته باشید، به صورت "مطالعه‌ای" باشد. در این مثال، یک Accessor برای ویژگی تعریف می کنیم first_name . هنگام تلاش برای بازیابی مقدار مشخصه، Accessor به طور خودکار توسط Eloquent فراخوانی می شود first_name :

<?php
 
namespace App;
 
use Illuminate\Database\Eloquent\Model;
 
class User extends Model
{
/**
* Get the user's first name.
*
* @param string $value
* @return string
*/
public function getFirstNameAttribute($value)
{
return ucfirst($value);
}
}

همانطور که می بینید، مقدار اصلی ستون به Accessor ارسال می شود و به شما امکان می دهد مقدار را دستکاری و برگردانید. برای دسترسی به مقدار Accessor، می توانید به first_name ویژگی در یک نمونه مدل دسترسی داشته باشید:

$user = App\User::find(1);
 
$firstName = $user->first_name;

همچنین می توانید از Accessor ها برای برگرداندن مقادیر جدید و محاسبه شده از ویژگی های موجود استفاده کنید:

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

اگر می خواهید این مقادیر محاسبه شده به آرایه / نمایش JSON مدل شما اضافه شود، باید آنها را اضافه کنید .

تعریف جهش دهنده

برای تعریف یک mutator، setFooAttribute روشی را در مدل خود تعریف کنید که در آن Foo نام ستونی که می خواهید به آن دسترسی داشته باشید، با حروف "مطالعه ای" باشد. بنابراین، دوباره، اجازه دهید یک mutator برای first_name ویژگی تعریف کنیم. زمانی که بخواهیم مقدار first_name ویژگی را در مدل تنظیم کنیم، این جهش‌دهنده به‌طور خودکار فراخوانی می‌شود:

<?php
 
namespace App;
 
use Illuminate\Database\Eloquent\Model;
 
class User extends Model
{
/**
* Set the user's first name.
*
* @param string $value
* @return void
*/
public function setFirstNameAttribute($value)
{
$this->attributes['first_name'] = strtolower($value);
}
}

جهش‌دهنده مقداری را که روی ویژگی تنظیم می‌شود، دریافت می‌کند و به شما امکان می‌دهد مقدار را دستکاری کنید و مقدار دستکاری شده را روی ویژگی داخلی مدل Eloquent تنظیم کنید $attributes . بنابراین، برای مثال، اگر بخواهیم first_name ویژگی را روی Sally :

$user = App\User::find(1);
 
$user->first_name = 'Sally';

در این مثال، setFirstNameAttribute تابع با مقدار فراخوانی می شود Sally . سپس mutator strtolower تابع را به نام اعمال می کند و مقدار حاصل از آن را در $attributes آرایه داخلی تنظیم می کند.

تغییر دهندگان تاریخ

created_at به طور پیش‌فرض، Eloquent ستون‌های و updated_at را به نمونه‌هایی از کربن تبدیل می‌کند که DateTime کلاس PHP را گسترش می‌دهد و مجموعه‌ای از روش‌های مفید را ارائه می‌دهد. می توانید با تنظیم $dates ویژگی مدل خود، ویژگی های تاریخ دیگری را اضافه کنید:

<?php
 
namespace App;
 
use Illuminate\Database\Eloquent\Model;
 
class User extends Model
{
/**
* The attributes that should be mutated to dates.
*
* @var array
*/
protected $dates = [
'seen_at',
];
}

می‌توانید با تنظیم ویژگی عمومی مدل خود، مهرهای پیش‌فرض created_at و زمانی را غیرفعال کنید . updated_at $timestamps false

هنگامی که یک ستون به عنوان تاریخ در نظر گرفته می شود، می توانید مقدار آن را روی مهر زمانی یونیکس، رشته تاریخ ( Y-m-d )، رشته تاریخ-زمان یا یک نمونه DateTime / تنظیم کنید Carbon . مقدار تاریخ به درستی تبدیل و در پایگاه داده شما ذخیره می شود:

$user = App\User::find(1);
 
$user->deleted_at = now();
 
$user->save();

همانطور که در بالا ذکر شد، هنگام بازیابی ویژگی‌هایی که در دارایی شما فهرست شده‌اند ، به طور خودکار به نمونه‌های کربن $dates فرستاده می‌شوند و به شما امکان می‌دهند از هر یک از روش‌های کربن در ویژگی‌های خود استفاده کنید:

$user = App\User::find(1);
 
return $user->deleted_at->getTimestamp();

فرمت های تاریخ

به طور پیش فرض، مُهرهای زمانی به صورت قالب بندی می شوند 'Y-m-d H:i:s' . اگر نیاز به سفارشی کردن قالب زمان دارید، $dateFormat ویژگی را روی مدل خود تنظیم کنید. این ویژگی تعیین می کند که چگونه ویژگی های تاریخ در پایگاه داده ذخیره می شوند:

<?php
 
namespace App;
 
use Illuminate\Database\Eloquent\Model;
 
class Flight extends Model
{
/**
* The storage format of the model's date columns.
*
* @var string
*/
protected $dateFormat = 'U';
}

ویژگی ریخته گری

ویژگی $casts موجود در مدل شما روش مناسبی برای تبدیل ویژگی ها به انواع داده های رایج ارائه می دهد. ویژگی $casts باید آرایه‌ای باشد که در آن کلید، نام مشخصه‌ای است که در حال فرستادن است و مقدار، نوعی است که می‌خواهید ستون را به آن ارسال کنید. انواع بازیگران پشتیبانی شده عبارتند از: integer , real , float , double , decimal:<digits> , string , boolean , object , array , collection , date , datetime , و timestamp . هنگام ارسال به decimal ، باید تعداد ارقام ( decimal:2 ) را مشخص کنید.

برای نشان دادن ریختن ویژگی، اجازه دهید is_admin ویژگی را که در پایگاه داده ما به عنوان یک عدد صحیح ( 0 یا 1 ) ذخیره می‌شود به یک مقدار بولی تبدیل کنیم:

<?php
 
namespace App;
 
use Illuminate\Database\Eloquent\Model;
 
class User extends Model
{
/**
* The attributes that should be cast.
*
* @var array
*/
protected $casts = [
'is_admin' => 'boolean',
];
}

اکنون is_admin مشخصه همیشه هنگام دسترسی به آن به یک Boolean فرستاده می شود، حتی اگر مقدار اساسی در پایگاه داده به عنوان یک عدد صحیح ذخیره شود:

$user = App\User::find(1);
 
if ($user->is_admin) {
//
}

ویژگی‌هایی که هستند null پخش نمی‌شوند. علاوه بر این، هرگز نباید یک بازیگر (یا یک ویژگی) که نام یک رابطه را دارد تعریف کنید.

بازیگران سفارشی

لاراول انواع مختلفی از بازیگران داخلی و مفید دارد. با این حال، ممکن است گاهی لازم باشد انواع بازیگران خود را تعریف کنید. شما می توانید این کار را با تعریف کلاسی که CastsAttributes رابط را پیاده سازی می کند انجام دهید.

کلاس هایی که این رابط را پیاده سازی می کنند باید a get و set متد را تعریف کنند. این get روش مسئول تبدیل یک مقدار خام از پایگاه داده به یک مقدار ریخته‌گری است، در حالی که set روش باید یک مقدار ریخته‌شده را به یک مقدار خام تبدیل کند که می‌تواند در پایگاه داده ذخیره شود. به عنوان مثال، نوع ریخته گری داخلی را json به عنوان یک نوع ریخته گری سفارشی دوباره پیاده سازی می کنیم:

<?php
 
namespace App\Casts;
 
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
 
class Json implements CastsAttributes
{
/**
* Cast the given value.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param string $key
* @param mixed $value
* @param array $attributes
* @return array
*/
public function get($model, $key, $value, $attributes)
{
return json_decode($value, true);
}
 
/**
* Prepare the given value for storage.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param string $key
* @param array $value
* @param array $attributes
* @return string
*/
public function set($model, $key, $value, $attributes)
{
return json_encode($value);
}
}

هنگامی که یک نوع Cast سفارشی را تعریف کردید، می توانید آن را با استفاده از نام کلاس آن به یک ویژگی مدل متصل کنید:

<?php
 
namespace App;
 
use App\Casts\Json;
use Illuminate\Database\Eloquent\Model;
 
class User extends Model
{
/**
* The attributes that should be cast.
*
* @var array
*/
protected $casts = [
'options' => Json::class,
];
}

ارسال ارزش شی

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

به عنوان مثال، ما یک کلاس cast سفارشی تعریف می کنیم که چندین مقدار مدل را به یک Address شی مقدار واحد می ریزد. فرض می کنیم Address مقدار دارای دو ویژگی عمومی است: lineOne و lineTwo :

<?php
 
namespace App\Casts;
 
use App\Address;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use InvalidArgumentException;
 
class Address implements CastsAttributes
{
/**
* Cast the given value.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param string $key
* @param mixed $value
* @param array $attributes
* @return \App\Address
*/
public function get($model, $key, $value, $attributes)
{
return new Address(
$attributes['address_line_one'],
$attributes['address_line_two']
);
}
 
/**
* Prepare the given value for storage.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param string $key
* @param \App\Address $value
* @param array $attributes
* @return array
*/
public function set($model, $key, $value, $attributes)
{
if (! $value instanceof Address) {
throw new InvalidArgumentException('The given value is not an Address instance.');
}
 
return [
'address_line_one' => $value->lineOne,
'address_line_two' => $value->lineTwo,
];
}
}

هنگام ارسال به اشیاء ارزشی، هر تغییری که در شیء مقدار ایجاد شده باشد، قبل از ذخیره مدل، به‌طور خودکار با مدل همگام‌سازی می‌شود:

$user = App\User::find(1);
 
$user->address->lineOne = 'Updated Address Value';
 
$user->save();

اگر قصد دارید مدل‌های Eloquent خود را که حاوی اشیاء ارزشی هستند به JSON یا آرایه‌ها سریال کنید، باید واسط‌های Illuminate\Contracts\Support\Arrayable and JsonSerializable را روی شی مقدار پیاده‌سازی کنید.

ریخته گری ورودی

گاهی اوقات، ممکن است نیاز داشته باشید که یک قالب سفارشی بنویسید که فقط مقادیری را که روی مدل تنظیم می‌شوند، تبدیل می‌کند و هیچ عملیاتی را هنگام بازیابی ویژگی‌ها از مدل انجام نمی‌دهد. یک نمونه کلاسیک از یک بازیگر فقط ورودی، یک بازیگر "هشینگ" است. کست‌های سفارشی فقط ورودی باید CastsInboundAttributes رابط را پیاده‌سازی کنند، که فقط به یک set روش نیاز دارد تا تعریف شود.

<?php
 
namespace App\Casts;
 
use Illuminate\Contracts\Database\Eloquent\CastsInboundAttributes;
 
class Hash implements CastsInboundAttributes
{
/**
* The hashing algorithm.
*
* @var string
*/
protected $algorithm;
 
/**
* Create a new cast class instance.
*
* @param string|null $algorithm
* @return void
*/
public function __construct($algorithm = null)
{
$this->algorithm = $algorithm;
}
 
/**
* Prepare the given value for storage.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param string $key
* @param array $value
* @param array $attributes
* @return string
*/
public function set($model, $key, $value, $attributes)
{
return is_null($this->algorithm)
? bcrypt($value)
: hash($this->algorithm, $value);
}
}

پارامترهای بازیگری

هنگام پیوست کردن یک Cast سفارشی به یک مدل، پارامترهای Cast ممکن است با جدا کردن آنها از نام کلاس با استفاده از یک : کاراکتر و تعیین چند پارامتر با کاما مشخص شوند. پارامترها به سازنده کلاس cast ارسال می شود:

/**
* The attributes that should be cast.
*
* @var array
*/
protected $casts = [
'secret' => Hash::class.':sha256',
];

ریخته گری

به جای پیوست کردن قالب سفارشی به مدل خود، می‌توانید کلاسی را که Illuminate\Contracts\Database\Eloquent\Castable رابط را پیاده‌سازی می‌کند، وصل کنید:

protected $casts = [
'address' => \App\Address::class,
];

اشیایی که Castable اینترفیس را پیاده سازی می کنند باید castUsing متدی را تعریف کنند که نام کلاس کلاس caster سفارشی که مسئول ارسال به کلاس و از Castable کلاس است را برمی گرداند:

<?php
 
namespace App;
 
use Illuminate\Contracts\Database\Eloquent\Castable;
use App\Casts\Address as AddressCast;
 
class Address implements Castable
{
/**
* Get the name of the caster class to use when casting from / to this cast target.
*
* @return string
*/
public static function castUsing()
{
return AddressCast::class;
}
}

هنگام استفاده از Castable کلاس‌ها، همچنان ممکن است آرگومان‌هایی در $casts تعریف ارائه کنید. آرگومان ها مستقیماً به کلاس caster ارسال می شوند:

protected $casts = [
'address' => \App\Address::class.':argument',
];

ارسال آرایه و JSON

نوع ریخته array گری به ویژه هنگام کار با ستون هایی که به صورت سریال JSON ذخیره می شوند مفید است. به عنوان مثال، اگر پایگاه داده شما دارای یک JSON یا TEXT نوع فیلد است که حاوی JSON سریالی است، افزودن array cast به آن ویژگی، هنگامی که در مدل Eloquent خود به آن دسترسی پیدا می‌کنید، به طور خودکار ویژگی را به یک آرایه PHP از فهرست خارج می‌کند:

<?php
 
namespace App;
 
use Illuminate\Database\Eloquent\Model;
 
class User extends Model
{
/**
* The attributes that should be cast.
*
* @var array
*/
protected $casts = [
'options' => 'array',
];
}

هنگامی که cast تعریف شد، می توانید به options ویژگی دسترسی داشته باشید و به طور خودکار از JSON به یک آرایه PHP تبدیل می شود. وقتی مقدار مشخصه را تنظیم می کنید options ، آرایه داده شده به طور خودکار برای ذخیره سازی به JSON تبدیل می شود:

$user = App\User::find(1);
 
$options = $user->options;
 
$options['key'] = 'value';
 
$user->options = $options;
 
$user->save();

ریخته گری تاریخ

هنگام استفاده از نوع date یا datetime cast، می توانید قالب تاریخ را مشخص کنید. این قالب زمانی استفاده خواهد شد که مدل به یک آرایه یا JSON سریال شود :

/**
* The attributes that should be cast.
*
* @var array
*/
protected $casts = [
'created_at' => 'datetime:Y-m-d',
];

ارسال زمان پرس و جو

گاهی اوقات ممکن است لازم باشد هنگام اجرای یک پرس و جو، از جمله زمانی که یک مقدار خام را از جدول انتخاب می کنید، Casts را اعمال کنید. به عنوان مثال، پرس و جو زیر را در نظر بگیرید:

use App\Post;
use App\User;
 
$users = User::select([
'users.*',
'last_posted_at' => Post::selectRaw('MAX(created_at)')
->whereColumn('user_id', 'users.id')
])->get();

ویژگی last_posted_at نتایج این پرس و جو یک رشته خام خواهد بود. اگر بتوانیم date هنگام اجرای پرس و جو، یک cast برای این ویژگی اعمال کنیم، راحت خواهد بود. برای انجام این کار، ممکن است از روش زیر استفاده کنیم withCasts :

$users = User::select([
'users.*',
'last_posted_at' => Post::selectRaw('MAX(created_at)')
->whereColumn('user_id', 'users.id')
])->withCasts([
'last_posted_at' => 'datetime'
])->get();