Класс Attribute
Класс Attribute предназначен для определения пользовательских атрибутов (аксессоров и мутаторов) в моделях Laravel. Он позволяет создавать вычисляемые поля, преобразовывать значения при получении или сохранении, а также добавлять кэширование для атрибутов. Класс находится в пространстве имён Illuminate\Database\Eloquent\Casts.
Основное преимущество использования Attribute - это декларативный подход к определению атрибутов через атрибуты PHP 8. Вместо создания отдельных методов getFooAttribute и setFooAttribute, вы определяете один метод с атрибутом Attribute, который возвращает объект этого класса.
Синтаксис
<?php
use Illuminate\Database\Eloquent\Casts\Attribute;
protected function name(): Attribute
{
return Attribute::make(
get: fn ($value) => $value,
set: fn ($value) => $value,
);
}
?>
Метод возвращает объект Attribute, созданный с помощью статического метода make. В параметрах передаются замыкания для получения (get) и установки (set) значения атрибута.
Пример
Создадим аксессор, который возвращает полное имя пользователя:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Casts\Attribute;
class User extends Model
{
protected function fullName(): Attribute
{
return Attribute::make(
get: fn ($value) => $this->first_name . ' ' . $this->last_name,
);
}
}
?>
Использование аксессора в коде:
<?php
use App\Models\User;
$user = User::find(1);
$res = $user->full_name;
echo $res;
?>
Результат выполнения кода:
"John Doe"
Обратите внимание, что имя атрибута определяется по имени метода в стиле snake_case.
Пример
Создадим мутатор для преобразования телефона к единому формату:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Casts\Attribute;
class User extends Model
{
protected function phone(): Attribute
{
return Attribute::make(
set: fn ($value) => preg_replace('/[^0-9]/', '', $value),
);
}
}
?>
Пример сохранения с мутатором:
<?php
use App\Models\User;
$user = User::find(1);
$user->phone = '+7 (999) 123-45-67';
$user->save();
echo $user->phone;
?>
Результат выполнения кода:
"79991234567"
В данном случае при сохранении из строки удаляются все символы, кроме цифр.
Пример
Создадим атрибут с кэшированием результата для избежания повторных вычислений:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Casts\Attribute;
class Article extends Model
{
protected function cachedWordsCount(): Attribute
{
return Attribute::make(
get: fn ($value) => str_word_count($this->text),
)->shouldCache();
}
}
?>
При использовании такого атрибута его значение вычисляется только один раз:
<?php
use App\Models\Article;
$article = Article::find(1);
$res = $article->cached_words_count;
echo $res;
?>
Результат выполнения кода:
234
Смотрите также
-
атрибут модели
casts,
который преобразует типы данных -
атрибут модели
appends,
который добавляет атрибуты в массив модели -
атрибут модели
hidden,
который скрывает атрибуты при преобразовании в массив -
метод
getAttribute,
который получает значение атрибута модели