Interfaces are used to provide an interface to communicate with, as well as a blueprint for classes to use to implement methods.
Abstract classes are used to provide partial implementation, as well as a base type which facilitate communication and extendibility.
Traits are used for code re-use. It can't be used for type hinting.
If you're doing dependency injection, you'd want to use interfaces to be able to replace the implementation in the future if you choose to. If you have multiple sub-types, you might want to have a base type to share implementation between these (A good example is having a Request type from which you extend for the various HTTP verbs). Traits then allow you to group functionality which might not only apply to that inheritance tree.