Is there a nice way in Symfony 2 or 3 to load all classes within a directory that implements a particular interface?
-
2Can we know why would you want to do that? It seems unnecessary since you have autoloading which means that every class will be loaded when needed for the first time.Jakub Matczak– Jakub Matczak2016-04-21 15:16:25 +00:00Commented Apr 21, 2016 at 15:16
-
I'm building my own framework on top of Symfony. I want to have each module in it's own self contained directory which all sit within a modules directory. I need to scan this directory for any classes which implement ModuleInterface. Then for each class implementing the interface I can call a register function which will allow me to inject dependencies and configure routes etc. Hope this clears up my need. Please let me know if you need any more info.nfplee– nfplee2016-04-21 15:28:18 +00:00Commented Apr 21, 2016 at 15:28
2 Answers
Since Symfony 3.3/3.4 it is possible by using configuration only (without a need to write custom CompilerPass):
# config/services.yaml
services:
# ...
_instanceof:
App\HandlerInterface:
tags: ['app.handler']
App\HandlerCollection:
# inject all services tagged with app.handler as first argument
arguments: [!tagged app.handler]
and if you need to restrict services to register from a single directory see importing with resource
references:
Comments
Short answer is: you can't.
You don't know, what is in a file until you load it.
Long answer (taking into account what you have wrote in the comment under the question):
The only thing you know before you load a file is its name. So one of solution is to name your modules' classes (and files) with a fixed pattern like UserModule, ProductModule and so on. That way you can load all modules by their names. But this is the solution that I wouldn't suggest.
I my opinion you should change the approach and inverse the workflow. Create a class in which you will define all modules that need to be loaded. In Symfony it's called by default AppKernel, in which you define bundles (modules) to be loaded and initialized.
This has a few advantages.
You can have multiple entry points to your application and configure each one with different modules.
You may have a few different environments (like production and development) with different modules loaded in both of them. (e.g. add some modules in development like profiler)
Also dependency managment is much easier, since you can load defined modules and add their dependencies also with autoloading.
In general I think that you should avoid manual loading any php files (except autoload.php or similar that contains autoloaders) at all.