Php: How to Get a List of Classes That Implement Certain Interface

PHP: how to get a list of classes that implement certain interface?

You can use PHP's ReflectionClass::implementsInterface and get_declared_classes functions to accomplish this:

$classes = get_declared_classes();
$implementsIModule = array();
foreach($classes as $klass) {
$reflect = new ReflectionClass($klass);
if($reflect->implementsInterface('IModule'))
$implementsIModule[] = $klass;
}

Call all classes that implement an interface

The best way is to implement CompilerPass. Here is an example .
So, create a registry class (TransportChain class in that example), interface, and all classes that implements that interface, define them as services and give them tag name.
After that, you can call that registry service in your action, and call your desired method by each service.

Basic example:

interface

interface SomeInterface {
public function doSomething();
}

Service 1:

class First implement SomeInterface {
public function doSomething() {
// do smth
}
}

Service 2:

class Second implement SomeInterface {
public function doSomething() {
// do smth
}
}

Registry class:

class MyRegistry
{
private $services = [];

public function addMyService($service)
{
$this->services[] = $service;
}

public function all()
{
return $this->services;
}
}

CompilerPass:

   ...

$myServices = $container->findTaggedServiceIds('my_tag');

if (empty($myServices)) {
return;
}

$registry = $container->getDefinition('my_registry');

foreach ($myServices as $key => $myService) {
$registry->addMethodCall('add', [new Reference($key)]);
}

...

After clearign the cache, you can call them in your action:

...

foreach ($this->get('my_registry')->all() as $myService) {
$myService->doSomething();
}

...

The whole other stuff, like declaring services, give them tag name, registering your compiler pass has been written here.

Symfony 2/3 Get Classes in Directory that Implement an Interface

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.

Checking if an instance's class implements an interface?

interface IInterface
{
}

class TheClass implements IInterface
{
}

$cls = new TheClass();
if ($cls instanceof IInterface) {
echo "yes";
}

You can use the "instanceof" operator. To use it, the left operand is a class instance and the right operand is an interface. It returns true if the object implements a particular interface.

Can PHP classes return object of type interface that they are implementing?

You never return an interface or a class, you return an object that implements the class of your choice which in turn will implement an interface.

An interface or class is the declaration and definition portion of the object that you create while the object is variable that contains the properties. Any call you do to an object resolves to a class and the body of that function is executed, but the properties you access (the non-static ones) return to the object itself.

When instanciating an object of a certain class, the object is OF that class. It cannot be of the type of an interface because an interface cannot be instanciated. On the other hand, you can use "instanceof" in PHP to determine if an object implements a certain interface or uses a specific class. Instanceof validates all interfaces implemented in all classes of the object, even the parent ones.

So using:

interface i {}
interface i2 {}
class a implements i {}
class b extends a {}
class c extends b implements i2 {}
$o = new b();

In this very case, $o is an "i", "a" and "b". All calls to instanceof with these class names will return true... But because $o is ob class b naturally, instanceof will never return true for the C class or the i2 interface.



Related Topics



Leave a reply



Submit