container-interop/service-provider
Experimental PSR draft to standardize PHP service providers (“bundles/modules”) for PSR-11 containers. Defines interfaces for registering factories and extensions so modules can share container definitions across frameworks. Not stable before 1.0; expect breaking changes.
Installation
composer require container-interop/service-provider
Add to composer.json under require (experimental, so ensure your team is aware).
First Use Case: Wrapping a Non-Laravel Container
DependencyInjection).ContainerInterface to a PSR-11 container for Laravel’s DI:
use ContainerInterop\ServiceProvider\ServiceProviderInterface;
use Symfony\Component\DependencyInjection\ContainerInterface as SymfonyContainer;
$symfonyContainer = new SymfonyContainer();
$provider = new \ContainerInterop\ServiceProvider\SymfonyServiceProvider($symfonyContainer);
$psr11Container = new \ContainerInterop\Container($provider);
Where to Look First
SymfonyServiceProvider and LaravelServiceProvider in the package’s src/ directory.Illuminate/Container for compatibility notes (e.g., binding methods).Bridging Containers
// In a Laravel service provider (e.g., AppServiceProvider)
public function register()
{
$symfonyContainer = new SymfonyContainer();
$provider = new \ContainerInterop\ServiceProvider\SymfonyServiceProvider($symfonyContainer);
$this->app->bind('container.interop', function () use ($provider) {
return new \ContainerInterop\Container($provider);
});
}
$app['container.interop']->get(MyService::class).Extending Laravel’s Container
Container.$laravelProvider = new \ContainerInterop\ServiceProvider\LaravelServiceProvider($this->app);
$psr11Container = new \ContainerInterop\Container($laravelProvider);
Service Provider Chaining
$container = new \ContainerInterop\Container();
$container->addProvider(new SymfonyServiceProvider($symfonyContainer));
$container->addProvider(new CustomServiceProvider());
ServiceProviderInterface for unit tests:
$mockProvider = $this->createMock(ServiceProviderInterface::class);
$mockProvider->method('getService')->willReturn(new MyService());
$container = new \ContainerInterop\Container($mockProvider);
Experimental Status
Laravel-Specific Quirks
when()/needs() bindings aren’t directly translatable to PSR-11.
LaravelServiceProvider with caution; prefer explicit bindings.LaravelServiceProvider.Circular Dependencies
Namespace Collisions
// Debug Laravel bindings
$this->app->bindings;
Psr\Container\ContainerInterface).ServiceProviderInterface for non-Symfony/Laravel containers:
class MyCustomProvider implements ServiceProviderInterface {
public function getService($id) {
return new $id(); // Simplified example
}
}
$container->get(Psr15MiddlewareDispatcher::class)->dispatch(
$request,
$response
);
$container->set(
Symfony\Contracts\EventDispatcher\EventDispatcherInterface::class,
$this->app->make(SymfonyEventDispatcher::class)
);
How can I help you explore Laravel packages today?