Laravel/eloquent mutators
مقدمة
تمكّنك المعدّلات والموصّلات من تنسيق قيم خاصيّات Eloquent عند استردادها أو تعيينها على كائنات النماذج. مثلًا، يمكنك استخدام مشفّر Laravel لتشفير قيمة ما أثناء تخزينها بقاعدة لًا، ومن ثمّ فك تشفيرها تلقائيًّا عند استردادها من نموذج Eloquent.
إضافةً إلى المعدلات والموصلات الافتراضية، يمكّنك Eloquent من التحويل التلقائي للخاصيات الزمنية إلى كائنات من الصنف Carbon أو حتى تحويل الخاصيات النصية إلى كائنات JSON.
المعدلات والموصلات
تعريف الموصل
لتعريف موصل ما، عرف التابع getFooAttribute
على صنف نموذجك حيث Foo
هو اسم الحقل المراد الوصول إليه (بعد تحويل صيغة الاسم إلى PascalCase). في هذا المثال، سنعرف موصل للحقل first_name
. سيُستدعى الموصل تلقائيًّا من قبل Eloquent عند استرداد قيمة الحقل first_name
:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* قراءة الاسم الأول للمستخدم..
*
* @param string $value
* @return string
*/
public function getFirstNameAttribute($value)
{
return ucfirst($value);
}
}
كما نرى، تُمرّر القيمة الافتراضية للحقل إلى تابع الموصل، مما يتيح لك تعديل هذه القيمة. للوصول إلى القيمة المعدلة من قبل الموصل، قم بالوصول إلى الخاصية first_name
على نموذجك:
$user = App\User::find(1);
$firstName = $user->first_name;
وبالطبع، يمكنك استخدام الموصلات لإنشاء قيم جديدة ومحسوبة تلقائيًّا من القيم الموجودة مسبقًا:
/**
* قراءة الاسم الكامل للمستخدم..
*
* @return string
*/
public function getFullNameAttribute()
{
return "{$this->first_name} {$this->last_name}";
}
تعريف المعدل
لتعريف معدل ما، عرف التابع setFooAttribute
على صنف نموذجك حيث Foo
هو اسم الحقل المراد التعديل عليه (بعد تحويل صيغة الاسم إلى PascalCase). لذلك مجددًا، سنعرف معدل للحقل first_name
. سيُستدعى المعدل تلقائيًّا من قبل Eloquent عند تعيين قيمة الحقل first_name
:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* تعيين الاسم الأول للمستخدم.
*
* @param string $value
* @return void
*/
public function setFirstNameAttribute($value)
{
$this->attributes['first_name'] = strtolower($value);
}
}
يتلقى المعدل القيمة المراد تعيينها على الخاصية، مما يتيح لك تعديل هذه القيمة وتعيينها على الخاصية attributes
الداخلية لنماذج Eloquent. مثلاً، إذا أردنا تعيين الاسم الأول ليصبح Sally
:
$user = App\User::find(1);
$user->first_name = 'Sally';
في هذا المثال، سيُستدعى التابع setFirstNameAttribute
وتُمرّر القيمة Sally
له. سيطبّق المعدل بعد ذلك التابع strtolower
للاسم ويعيّنه للحقل.
المعدلات الزمنية
يحوّل Eloquent افتراضيًّا الحقلين created_at
و updated_at
لكائنات من النوع Carbon، الذي يرث من الصنف الداخلي DateTime
الخاص بـ PHP لتزويد مجموعة من التوابع المساعدة. يمكنك تخصيص الحقول الزمنية التي تُعدّل، أو إلغاء التعديل بأكمله، عن طريق إعادة تعيين الخاصية dates
على نموذجك:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* الخاصيات التي يجب تحويلها إلى كائنات زمنية.
*
* @var array
*/
protected $dates = [
'created_at',
'updated_at',
'deleted_at'
];
}
عند اعتبار حقل ما زمنيًّا، يمكنك تعيين قيمته إلى طابع زمني UNIX، أو نص تاريخ (Y-m-d
)، أو كائن من النوع DateTime
أو Carbon
؛ وستُخزّن القيمة الزمنية تلقائيًّا وبشكل صحيح في قاعدة البيانات:
$user = App\User::find(1);
$user->deleted_at = now();
$user->save();
كما ذُكر آنفًا، عند استرداد القيم الموجودة في مصفوفة dates
، ستُحوّل تلقائيًّا إلى كائن من نوع Carbon، مما يتيح لك استخدام أي من توابع Carbon على هذه الحقول:
$user = App\User::find(1);
return $user->deleted_at->getTimestamp();
تنسيق الحقول الزمنية
تُنسّق الحقول الزمنية افتراضيًّا بالنمط 'Y-m-d H:i:s
'. إذا أردت تخصيص هذا النمط، عيّن الخاصية dateFormat
على نموذجك. تحدد هذه الخاصية كيفية تخزين القيم الزمنية في قاعدة بياناتك، وكيفية تنسيق هذه القيم عند سلسلتها إلى مصفوفة أو كائن JSON:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model
{
/**
* نمط تخزين الحقول الزمنية.
*
* @var string
*/
protected $dateFormat = 'U';
}
تحويل الحقول
تزوّد الخاصية casts
في نموذجك بتابع مساعد لتحويل الحقول إلى أنواع بيانات معروفة. يجب أن تكون الخاصية casts
مصفوفة، تكون المفاتيح فيها أسماء الحقول التي ستُحوّل، والقيم أنواع البيانات التي تُحوّل إليها. إن التحويلات المتاحة هي: integer
, real
, float
, double
, string
, boolean
, object
, array
, collection
, date
, datetime
, و timestamp
.
لنحوّل على سبيل المثال الحقل is_admin
، الذي يُخزن في قاعدة البيانات كقيمة صحيحة (0 أو 1)، إلى قيمة منطقية boolean
:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* الحقول التي يجب تحويلها.
*
* @var array
*/
protected $casts = [
'is_admin' => 'boolean',
];
}
الآن، سيُحوّل الحقل is_admin
تلقائيًّا إلى قيمة منطقية عند الوصول إليها، حتى ولو كان نمط تخزينها في قاعدة البيانات قيمة صحيحة:
$user = App\User::find(1);
if ($user->is_admin) {
//
}
تحويلات المصفوفات وكائنات JSON
يساعد نمط التحويل array
بشكل خاص عند العمل مع الحقول التي تُخزّن القيم المسلسلة كـ JSON فيها. مثلاً، إذا احتوت قاعدة بياناتك على حقل من النوع JSON
أو TEXT
يحتوي على كائن JSON مسلسل، عند إضافة التحويل array
إلى ذلك الحقل، ستُفكّ السلسلة تلقائيًّا إلى مصفوفة PHP عند الوصول إلى هذا الحقل على نموذج Eloquent:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* الحقول التي يجب تحويلها.
*
* @var array
*/
protected $casts = [
'options' => 'array',
];
}
بعد تعريف التحويل، يمكنك الوصول إلى الحقل options
وستُفكّ السلسلة تلقائيًّا من JSON إلى مصفوفة PHP. عند تعيين قيم الحقل options
، ستُحوّل المصفوفة المعطاة تلقائيًّا إلى كائن JSON مسلسل وذلك للتخزين:
$user = App\User::find(1);
$options = $user->options;
$options['key'] = 'value';
$user->options = $options;
$user->save();
تحويلات الأزمان
عند استخدام نمط التحويل date
أو datetime
، يمكنك تعيين النمط الزمني. سيُستخدم هذا النمط عند سلسلة السجل إلى مصفوفة أو كائن JSON:
/**
* الحقول التي يجب تحويلها.
*
* @var array
*/
protected $casts = [
'created_at' => 'datetime:Y-m-d',
];