Трейты (англ. traits) - это механизм обеспечения повторного использования кода в языках с поддержкой единого наследования. В php трейты внедрены с версии 5.4.0.
Они позволяют разработчику повторно использовать наборы методов и свойств в нескольких независимых классах.
Трейт похож на класс, но создать экземпляр трейта невозможно. Он предназначен для группирования функционала, который потом используется в разных классах.

Пример использования.
trait HelloWorld{    
    public function sayHello() {
        return 'Привет ';
    }
}
class NameMen{
    public $name = 'Вася';
}
class GetInfo extends NameMen{
    use HelloWorld;
    public function getPiple(){
            echo $this->sayHello() . $this->name;
    }
}
$obj = new GetInfo();
$obj->getPiple(); //Привет Вася
Тут создается трейт HelloWorld с публичным методом sayHello(). Все точно так же как в обычном классе. Далее создаем два класса. Класс GetInfo наследует класс NameMen для того, чтобы получить доступ к его методам и свойствам с помощью ключевого слова extends. Точно так же класс получает такой доступ к свойствам и методам трейтов с помощью директивы use, после которой указывается название трейта.

Нужные для использования в классе трейты можно указать через запятую:
use trait1, trait2, trait3;
    

Приоритет методов при работе с трейтами.

- члены из текущего класса переопределяют одноименные методы в трейте,
- члены из трейта переопределяют унаследованные классом методы. То есть трейт имеет преимущество перед классом который наследуем.

Конфликты трейтов.

Ошибки могут быть когда подключается несколько трейтов, содержащие одни и те же методы. Или когда класс наследует у другого класса с подключением трейта, который уже был подключен в родительском классе.
Для разрешения конфликтов необходимо использовать оператор insteadof при подключении трейтов для того, чтобы точно выбрать один из конфликтных методов.
trait Hello1{
    public function sayHello() {
        return 'Hello';
    }
}
trait Hello2{
    public function sayHello() {
        return 'Привет';
    }
}

class GetInfo{
    use Hello1,Hello2{
            Hello2::sayHello insteadof Hello1;
    }
    public function getPiple(){
            echo $this->sayHello();
    }
}

$obj = new GetInfo();
$obj->getPiple(); //Привет
Внутри тела «use» мы использовали ключевое слово insteadof, слева от которого указывается трейт, метод которого будем использовать и имя самого метода, которые разделяются двойным двоеточием. В правой части указывается имя трейта, метод которого должен быть заменён.

Если же второй одноименный метод (из другого трейта) нам тоже нужен, то можно применить псевдоним имени используя ключевое слово as:
use Hello1,Hello2{
        Hello2::sayHello insteadof Hello1;
        Hello1::sayHello as hel;
    }
public function getPiple(){
        echo $this->sayHello();
        echo $this->hel();
    }




Статические методы и свойства

Используются так же как и в классах:
trait HelloWorld{
    static $age = 'Вася';
    static function sayHello() {
        echo 'Привет ';
    }
}

class GetInfo{
    use HelloWorld;
    public function getPiple(){
            echo $this->sayHello();
    }
}

GetInfo::sayHello(); //Привет
echo GetInfo::$age; //Вася

Доступ к свойствам базового класса.

В трейтах для доступа к свойствам базового класса можно использовать псевдопеременную $this.


Изменения прав доступа к методам трейта.

Внутри трейта мы можем использовать любой модификатор доступа (public, private, protected) для методов. Но, кроме этого, есть возможность в классе менять этот модификатор на другой. Для этого в теле use после слова as можно указать новый модификатор.
use someTrait {
    someTrait::someMethod as private;
}

Константы связанные с трейтами.

__CLASS__

Имя класса. Это имя содержит название пространства имен, в котором класс был объявлен (например, Foo\Bar). Обратите внимание, что начиная с PHP5.4 __CLASS__ также работает в трейтах. При использовании в методах трейтов __CLASS__ является именем класса, в котором эти методы используется.

__TRAIT__

Имя трейта. Это имя содержит название пространства имен, в котором трейт был объявлен (например, Foo\Bar).

trait HelloWorld{
    static $name_trait = __TRAIT__;
}

class GetInfo{
    use HelloWorld;
}

echo GetInfo::$name_trait; //HelloWorld


Итоги:

  • Трейты используются, когда нужно набор методов вставить в разные классы, они чем-то похожи на команду include.
  • Трейты объявляются используя ключевое слово trait, в классе использование трейта прописывается ключевым словом use.
  • В одном классе можно использовать несколько трейтов.
  • Невозможно создать самостоятельный экземпляр трейта.
  • Трейты можно использовать совместно с интерфейсами.
  • Конфликты имён в трейтах устраняется при помощи ключевого слова insteadof, которое замещает метод.
  • Замещённому методу можно присвоить псевдоним при помощи ключевого слова as.
  • При помощи ключевого слова as также можно изменить область видимости метода трейта в классе.
  • В трейте можно использовать псевдопеременную $this для доступа с свойствам базового класса.
  • В трейтах можно задавать абстрактные классы, которые должны быть реализованы в классах, использующих эти трейты.
  • К методам трейта можно обратиться напрямую, используя оператор двойного двоеточия.