Документация - https://www.php.net/manual/ru/language.oop5.traits.php
Как гласит документация, Трейты реализуют метод для повторного использования кода.
Проще говоря, это набор методов/свойств, которые можно собрать в одном месте и подключать в нужном классе для использования.
Добавлять можно сколько угодно трейтов.
Синтаксис
<?php
namespace App\Models\Traits;
use Illuminate\Support\Carbon;
trait HasDates
{
public function getCreatedAtAttribute($value)
{
$date = Carbon::parse($value);
return $date->format('Y-m-d H:i:s');
}
public function getUpdatedAtAttribute($value)
{
$date = Carbon::parse($value);
return $date->format('Y-m-d H:i:s');
}
}
Пример трейта с laravel. Как видно, в трейте можно объявить namespace, подключить другие классы и объявить методы.
Подключение трейтов
<?php
use App\Models\Traits\HasDates;
class User extends Model {
use HasDates;
/* ... */
}
Приоритет
При совпадении имен методов в трейте и классах, одни будут заменены другими.
Порядок: Метод в классе -> Метод в трейте -> Унаследованный метод.
То есть самый главный метод будет в классе, потом в трейте и самый последний - унаследованный.
Разрешение конфликтов
При подключении нескольких трейтов, если в них совпадают имена методов то будет выдана фатальная ошибка, если конфликты имен не разрешены явно.
Есть несколько основных способов разрешения конфликтов:
- Оператор
insteadof
; - Оператор
as
.
<?php
trait A {
public function smallTalk() {
echo 'a';
}
public function bigTalk() {
echo 'A';
}
}
trait B {
public function smallTalk() {
echo 'b';
}
public function bigTalk() {
echo 'B';
}
}
class Talker {
use A, B {
B::smallTalk insteadof A;
A::bigTalk insteadof B;
}
}
class Aliased_Talker {
use A, B {
B::smallTalk insteadof A;
A::bigTalk insteadof B;
B::bigTalk as talk;
}
}