简体   繁体   中英

How do inject array of implementations into constructor in PHP

How do inject array of implementations into class through constructor. I am sharing the link which is c#. I want to achieve the same in php.

How to achieve same in php.

public interface IFoo { }
public class FooA : IFoo {}
public class FooB : IFoo {}

public class Bar
{
    //array injected will contain [ FooA, FooB ] 
    public Bar(IFoo[] foos) { }
}

public class MyModule : NinjectModule
{
    public override void Load()
    {
        Bind<IFoo>().To<FooA>();
        Bind<IFoo>().To<FooB>();
        //etc..
    }
}

https://stackoverflow.com/a/13383476/1844634

Thanks in advance.

PHP does not support generics duo to run-time performance difficulty. So there are no way to explain that you expect all interfaces via definition of contractor. So you have to configure DI container manually. To explicitly tell that your class needs all classes that support some kind of interface.

Laravel for configuration use ServiceProvider to do all kind of configuration: In the class \\App\\Providers\\AppServiceProvider you can configure creation of your class.


    public function register(): void
    {
        // to configure implementation for an interface or abstract class
        // you can only configure one implementation for interface
        $this->app->bind(\App\IFoo::class, \App\FooA::class);

        // or 'tag' several implementation for one string tag.
        $this->app->tag([\App\FooA::class, \App\FooB::class], \App\IFoo::class);

        $this->app->bind(\App\Bar::class, function(\Illuminate\Contracts\Foundation\Application $container){
            // get all tagged implementations
            $foos = $container->tagged(\App\IFoo::class);

            return new \App\Bar($foos);
        });
    }

You may need to use Tagging . For example, perhaps you are building a report aggregator that receives an array of many different Report interface implementations. After registering the Report implementations, you can assign them a tag using the tag method:

$this->app->bind('App\Reports\MemoryReportInterface', 'App\Reports\MemoryReportImplementation');       
$this->app->bind('App\Reports\SpeedReportInterface', 'App\Reports\SpeedReportImplementation');  

$this->app->tag(['App\Reports\MemoryReportInterface', 'App\Reports\MemoryReportInterface'], 'reports'); 

Once the services have been tagged, you may easily resolve them all via the tagged method:

$this->app->bind('ReportAggregator', function ($app) {
    return new ReportAggregator($app->tagged('reports'));
});

Usage

<?php 

namespace ...;

/**
 * 
 */
class ReportAggregator
{
    private $reports;

    function __construct($reports)
    {
        $this->reports = $reports;
    }

    public function getReports() {
        return $this->reports;
    }
    //...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM