Don't use them
...unrestricted. But do use them when their use is restricted to a specific well-maintained role as doing so will ease software maintenance and avoid dependency-hiding.
First, some background.
In context of Zend Framework 2+ architecture, injecting any DiC into a Controller means using that DiC as Service Locator. (In Zend Framework, concrete implementation of Service Locator is called ServiceManager).
For pure use of DiC as DiC there is a Register Resolve Release (RRR) pattern, which creates the Controller for you and populates it with dependencies. You do not, as a rule, inject DiC itself into the controller, although you could if you so wanted to, thereby mixing DiC and Service Locator patterns.
This link is helpful in providing more details on the differences: https://github.com/aimfeld/ZendDiCompiler
Also, there has been some advice to avoid using DiC, because of slower PHP Reflection API and various maintenance issues down the road. DiC makes it easy to use complex dependencies resulting in complex dependency graphs that are created automatically without explicit manual code wiring. This makes it hard to debug them when things go wrong. If new dependencies are added over time, automatic rewiring is done for you without explicit wiring code being written. This potentially makes it harder to track dependencies manually when something goes wrong. Using Service Locator pattern is then recommended as it restricts you to Factory-based Di, giving you more explicit control of Di via explicit configuration.
For RAD, when Controllers ask for a lot of dependencies, when business logic is complex enough, instead of cluttering Controller constructor methods with 5+ dependencies, it is at times more convenient to pass the Service Locator / container as the dependency to the Controller and let code inside the Controller invoke various many objects via SL/DiC facilities.
For non-RAD, break up your controllers to where they do not have that many dependencies.
"Besides ZF2 controllers, I recommend not to inject ZendDiCompiler
directly anywhere. If you need a service in one of your classes, just
ask for it in the constructor"
However, I would not recommend injecting DiC into Controllers. Read below as to why.
Using Service Locator
Do not use Service Locator unrestricted. It has been deprecated in Zend for good reasons.
Use restricted version of Service Locator as for example how it is being used in Zend Framework version 3. It is restricted to being a Factory-based hardcoded-configuration Service Locator implemented via
ServiceManager class. It connects Routing to Controllers via instantiation of Controllers directly, or Factories (where Controllers receive their dependencies), Invokables, AbstractFactories. See More about ServiceManager here
Using Dependency-injection/Inversion of Control Containers
You can use DiC for ease of dependency management for Rapid Application Development (RAD), but expect more debugging and maintenance issues down the road if you don't subsequently refactor to inject your dependencies directly. To avoid greater pains, if you are going to use DiC, use the RRR pattern to create your Controllers and populate them with any dependencies.
PSR-11 Container Interface