الکوئنت: دگرسان
معرفی
هنگام بازیابی یا تنظیم مقادیر مشخصه 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
andJsonSerializable
را روی شی مقدار پیادهسازی کنید.
ریخته گری ورودی
گاهی اوقات، ممکن است نیاز داشته باشید که یک قالب سفارشی بنویسید که فقط
مقادیری را که روی مدل تنظیم میشوند، تبدیل میکند و هیچ عملیاتی را هنگام بازیابی ویژگیها از مدل انجام
نمیدهد.
یک نمونه کلاسیک از یک بازیگر فقط ورودی، یک بازیگر "هشینگ" است.
کستهای سفارشی فقط ورودی باید
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();