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

interface B {
    function bar();
}

trait AImpl {
    function foo() {
        return $this->a->foo();
    }
}

trait BImpl {
    function bar() {
        return $this->b->bar();
    }
}

class AB implements A, B {
    private $a;
    private $b;

    use AImpl;
    use BImpl;

    public function __construct(A $a, B $b) {
        $this->a = $a;
        $this->b = $b;
    }
}