Accessors và Mutators trong Laravel 5.5
Bài đăng này đã không được cập nhật trong 3 năm
Xin chào tất cả mọi người. Hôm nay mình sẽ tìm hiểu về Accessors Mutators trong Laravel phiên bản 5.5
Giới thiệu
Accessors và Mutators đều cho phép chúng ta format lại các giá trị thuộc tính của Eloquent khi lấy ra hoặc thêm vào Model. Ngoài việc hỗ trợ tạo accessor và mutator, Eloquent cũng có thể tự động chuyển các trường date thành Carbon instance hoặc thậm chí chuyển trường text thành JSON.
Accessors và Mutators
Định nghĩa 1 accessors
Để định nghĩa 1 accessors, chúng ta hãy cũng tạo một hàm có tên getNameAttribute
trong model User
tại thư mục app
như sau:
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function getNameAttribute($value)
{
return $this->strtoupper($value);
}
}
Chưa biết nó ra sao, đến đây các bạn cũng có thể đoán được cái hàm bên trong function getNameAttribute
rồi phải không. Đây là hàm chuyển chữ thường sang chữ hoa trong PHP.
Tiếp theo ta vào mysql và thêm vào cơ sở dũ liệu của chúng ta các bản ghi. Ở đây do mình sẽ thêm 1 hàng bằng tay như sau:
Quay sang thư mục routes/web.php, ta tạo một route mới như sau:
Route::get('/accessors', function() {
$user = App\User::find(1);
return $upper_name = $user->name;
});
Mở trình duyệt theo đường dẫn localhost:8000/accessors lên. Kết quả là VIỆT NAM VÔ ĐỊCH.
Quay lại với model User
nào! Ở ví dụ này, các bạn hãy nhìn vào hàm getNameAttribute
. Hàm này được viết theo kiểu camelCase
để thực hiện việc lấy giá trị cho thuộc tính name
.
Có thể giải thích rằng nếu bạn muốn định nghĩa một accessors trong một model bất kỳ nào, thì trong function của bạn phải có tiền tố là get
và hậu tố là Attribute
.
Định nghĩa 1 mutators
Ngược lại với accessors, mutators có nghĩa là khi bạn muốn format lại các giá trị thuộc tính trước khi lưu vào cơ sở dữ liệu.
Ví dụ, để định nghĩa một Mutators
, mình sẽ định nghĩa một phương thức setPasswordAttribute
trong model User
public function setPasswordAttribute($password)
{
$this->attributes['password'] = bcrypt($password);
}
web.php
:
Route::get('/mutators', function() {
$user = App\User::find(1);
$user->password = 123456;
return $user->password;
});
Quay lại trình duyệt và gõ địa chỉ localhost:8000/accessors . Kết quả là một đoạn ký tự đã được mã hóa.
Ở ví dụ trên, hàm setPasswordAttribute
sẽ được gọi với $password
truyền vào là 123456.
Vậy nếu bạn muốn định nghĩa một Mutators trong một model, function của bạn phải có tiền tố là set
và hậu tố là Attribute
Không khó đúng không nào ^^!!
Date Mutators
Mặc định trong Laravel, Eloquent sẽ chuyển đổi hai trườngcreated_at
and updated_at
thành các instance của Carbon
, một thư viện cung cấp rất nhiều hàm hữu ích và mở rộng class DateTime của PHP.
Bạn có thể tuỳ chỉnh trường nào sẽ được tự động mutated, và thậm chí có thể disable việc mutation này bằng cách ghi đè lên thuộc tính $date
trên model của bạn.
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
protected $dates = [
'created_at',
'update_at',
'delete_at',
];
}
Khi một cột là kiểu date, bạn có thể đặt giá trị của nó là một UNIX timestamp, date string (Y-m-d), date-time string và là một instance của DateTime / Carbon, và giá trị của date sẽ tự động được lưu vào trong database:
$user = App\User::find(1);
$user->deleted_at = now();
$user->save();
Và một lưu ý, đó là khi các bạn lấy ra các giá trị nằm trong $date của bạn, chúng sẽ tự động được cast thành các Carbon instance và cho phép bạn sử dụng các method của Carbon trong các attribute.
$user = App\User::find(1);
return $user->deleted_at->getTimestamp();
Date Format
Mặc định, timestamp được format dưới dạng Y-m-d H:i:s
. Nếu bạn cần tùy chỉnh format cho timestamp, hãy đặt thuộc tính $dateFormat
trên model của bạn. Thuộc tính này sẽ quyết định giá trị date được lưu như thế nào trong database, giống như việc format chúng khi mà một model được serialized theo mảng hoặc JSON.
Ví dụ:
<?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';
}
Attribute Casting
Thuộc tính $casts
cung cấp một phương thức tiện lợi về việc chuyển đổi các các thuộc tính sang các kiểu dữ liệu bình thường. Thuộc tính $casts
nên là một mảng có key là tên của các attribute được cast và giá trị là kiểu dữ liệu bạn muốn cast. Các kiểu dữ liệu để cast được hỗ trợ bao gồm: integer
, real
, float
, double
, string
, boolean
, object
, array
, collection
, date
, datetime
, và timestamp
.
VD: cast thuộc tính is_admin từ kiểu integer sang boolean:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'is_admin' => 'boolean',
];
}
Giờ đây, thuộc tính is_admin
sẽ luôn luôn được cast thành kiểu boolean
khi bạn truy cập đến nó, thậm chí nếu giá trị của nó được lưu trong database là kiểu integer
:
$user = App\User::find(1);
if ($user->is_admin) {
//
}
Array & JSON Casting
Cast
kiểu array
đặc biệt hữu ích khi chúng ta làm việc với các column được lưu dưới dạng JSON. Giả sử database của bạn có 1 trường JSON
hoặc TEXT
có chứa serialized JSON, thêm vào array
cast
lên attribute sẽ tự động deserialize
các attribute
thành PHP array khi bạn truy cập trong Eloquent model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'options' => 'array',
];
}
Một khi cast
được định nghĩa, bạn có thể truy cập giá trị options
và nó sẽ tự động được deserialize từ JSON thành PHP array.
Khi bạn đặt giá trị options
, nó sẽ tự động được serialize trở lại thành JSON để lưu vào trong cơ sở dữ liệu:
$user = App\User::find(1);
$options = $user->options;
$options['key'] = 'value';
$user->options = $options;
$user->save();
Kết Luận
Thông thường thì mình thấy trong các project hay sử dụng Accessors và Mutators khá nhiều. Hi vọng các bạn có thể xem được những thông tin hữu ích từ bài viết này. Bài viết của mình xin dừng lại tại đây. Mong được sự theo dõi và ủng hộ của các bạn.
Tham khảo thêm về Accessors và Mutators tại : https://laravel.com/docs/5.5/eloquent-mutators
All rights reserved