Они нужны для избавления от дублирования кода, ну или например для множественного наследования.
Грубый пример:
У вас есть много классов, которые что-то записывают в лог, из класса в класс, это один и тот же участок кода, к примеру Logger::write(str), вот этот участок кода можно вынести в трейт LoggerTrait c методом logWrite, и потом во всех классах использовать $this->logWrite(str).
Потом удобно будет эту функцию переопределить в каком-то конкретном файле, если скажем там нужна какая-то специфичная запись в лог.
При таком подходе вы всегда класс логгера можете заменить, просто отредактировав всего один файл трейта, а не 100500 классов.
Еще пример:
В трейт можно вынести функцию isAjaxPost, для проверки, что запрос в контроллер пришел ajax post, и подключать в нужные контроллеры.
Да вообщем море примеров привести можно, где это удобно применять, для избавления от дублирование в коде, от однотипных операций и т.д.