Small but powerful dependency injection container

Overview

Container (Dependency Injection)

Author Latest Version Software License Build Status Coverage Status Quality Score Total Downloads

This package is compliant with PSR-1, PSR-2, PSR-4 and PSR-11. If you notice compliance oversights, please send a patch via pull request.

Install

Via Composer

$ composer require league/container

Requirements

The following versions of PHP are supported by this version.

  • PHP 7.0
  • PHP 7.1
  • PHP 7.2
  • PHP 7.3
  • PHP 7.4
  • PHP 8.0

Documentation

Container has full documentation, powered by Jekyll.

Contribute to this documentation in the docs/ sub-directory.

Testing

$ composer test

Contributing

Please see CONTRIBUTING for details.

Security

If you discover any security related issues, please email [email protected] instead of using the issue tracker.

Credits

License

The MIT License (MIT). Please see License File for more information.

Comments
  • Introduce Service Provider Functionality

    Introduce Service Provider Functionality

    This PR provides functionality for Service Providers and addresses #12.

    Usage

    Simplest use case would be to build a service provider and register an instance of that.

    <?php
    
    namespace Acme\ServiceProvider;
    
    use League\Container\ServiceProvider;
    
    class SomeServiceProvider extends ServiceProvider
    {
        protected $provides = ['some.service'];
    
        public function register()
        {
            $this->getContainer()->add('some.service', 'SomeService');
        }
    }
    
    $container->add(new Acme\ServiceProvider\SomeServiceProvider);
    
    // resolve the service provider by the name registered
    $container->get('some.service');
    

    Lazy Loading

    You can register a service provider by string reference to the fully qualified namespace of the service provider. The addServiceProvider expects you to provide a name/alias as the first argument.

    $container->addServiceProvider('Acme\ServiceProvider\SomeServiceProvider');
    
    $container->get('some.service');
    
    opened by philipobenito 67
  • Merge v2 Development

    Merge v2 Development

    This PR aims to be a discussion platform for version 2 of the container over the coming 2 weeks before a release is tagged on Friday 28th August 2015.

    It is incomplete and will be added to over the coming days with a completed test suite and any missing functionality.

    The main talking points I'd like to discuss are as follows:

    • Should "auto-wiring" be removed? I see three options
      1. Remove reflection completely (my preferred option).
      2. Attempt reflection as the last step of object resolution (turned off by default).
      3. Attempt reflection as the last step of object resolution (turned on by default).
    • The question of config. I've had several conversations with people requesting a better way to interact with the container via array type configs. This is something I've decided to include, but, should it be via new methods or by refactoring the current methods so that they can be invoked with different types of arguments then a simple array_map can pass the config to them as a callable?

    There will be more discussion over the coming days, but these two issues are my main concern as they are blockers to finishing the functionality.

    Please don't provide any edits to the code as of yet without discussion around it but if there is something you'd like to get involved with then please bring it up here so that it can be properly assigned and attributed.

    opened by philipobenito 27
  • Inflector Factory Closures

    Inflector Factory Closures

    Hi,

    It would be great to allow a way to have the inflector use a factory closure to create classes that implement an interface or extend a base class x.

    For instance:

    use My\ClassInterface;
    
    $container->inflector(ClassInterface::class, function ($container, $concrete) {
        return ClassFactory::create($concrete);
    });
    

    What is your thought on that?

    opened by gabrielbull 22
  • Enhancement: Allow to protect the container

    Enhancement: Allow to protect the container

    This PR

    • [x] allows to protect a container to prevent adding services, service providers, and inflectors

    :information_desk_person: It's still possible to override services, though, by creating a new container, defining services there, and delegating to the original container. Not sure, should delegating to a locked container be prevented, maybe?

    opened by localheinz 17
  • Wrong type-hint on ContainerAwareTrait::$container

    Wrong type-hint on ContainerAwareTrait::$container

    The $container field is type-hinted as \Psr\Container\ContainerInterface, which means you can't have a legal ServiceProvider implementation that does this:

    class FooServiceProvider extends AbstractServiceProvider {
        protected $provides = [
            ValidatorInterface::class,
        ];
    
        public function register()
        {
            $this->container->share(ValidatorInterface::class, Validator::class);
        }
    }
    

    Both phpstan and PhpStorm complains that there is no method named share() on $this->container. I'm not sure if the correct fix is to change just the member variable's type-hint or the setContainer() and getContainer() methods too.

    It doesn't seem to make sense to swap out the League\Container for some other PSR compatible container in a service provider specifically designed for this package, so maybe the whole ContainerAwareInterface needs some changes?

    opened by Jalle19 16
  • How to use ContainerAwareInterface

    How to use ContainerAwareInterface

    Hi there

    Is there any tutorial on how to use ContainerAwareInterface ?

    I try to pass the container object to my Controller class.

    I cant find any tutorial on that..Please advice

    Here what i tried:

    Controller class:

    <?php namespace App\Core;
    
    use League\Container\ContainerAwareTrait;
    use League\Container\ContainerAwareInterface;
    
    class AppController implements ContainerAwareInterface
    {
        use ContainerAwareTrait;
    
        public function __get( $name ) {
    
            var_dump($this->container);
            exit;
    
            if ( $this->container->has( $name ) ) {
                return $this->container->get( $name );
            }
        }
    }
    

    Bootstrap script:

    
    $container = new Container();
    
    #Auto-wiring based on constructor typehints.
    #http://container.thephpleague.com/auto-wiring
    $container->delegate( new ReflectionContainer() );
    
    $container->inflector( 'ContainerAwareInterface' )
        ->invokeMethod( 'setContainer', [ $container ] );
    

    I got the following when i try dump the container object

    /var/www/html/foo/src/App/Core/AppController.php:12:null

    opened by nmsobri 16
  • Can't seem to add values from a service provider

    Can't seem to add values from a service provider

    Hi, not quite sure if it's just me being stupid or this just not being possible:

    use League\Container\Container;
    use League\Container\ServiceProvider;
    
    
    class MyServiceProvider extends ServiceProvider
    {
        public function register()
        {
            $this->getContainer()['key'] = 'value';
        }
    }
    
    $container = new Container();
    $container->add(new MyServiceProvider);
    var_dump($container->get('key'));
    

    It throws:

    Fatal error: Uncaught exception 'League\Container\Exception\ReflectionException' with message 'Unable to reflect on the class [key], does the class exist and is it properly autoloaded?' in /Volumes/Data HD/Dropbox/Projects/snap/vendor/league/container/src/Container.php on line 401
    

    I've used Pimple in the past and this seems to work just fine :confused:

    opened by hassankhan 15
  • Using an alias does not properly look into the Service Providers

    Using an alias does not properly look into the Service Providers

    The commented line throws an error: Argument 1 passed to App\Users\UserMapper::__construct() must be an instance of Spot\Locator, none given. And the second line works properly, but defeats the purpose of lazy loading.

    // $container->add('App\Authentication\UserMapperInterface', 'App\Users\UserMapper');
    $container->add('App\Authentication\UserMapperInterface', $container->get('App\Users\UserMapper'));
    

    The problem seems to be with Spot\Locator being registered in a service provider. Using the commented line, the container does not look into the providers to find the service, like it does when using the get method

    opened by nebulousGirl 13
  • Inconsistent Behavior

    Inconsistent Behavior

    Environment:

    • Windows 10 x64
    • PHP 8.0.1
    • Package Version 3.3.4

    So far in most cases where I'm using the Container, it seems to work pretty well. But I'm starting to get instances where the reflection just stops working altogether.

    In many cases simply binding a concrete class to an abstract interface, or just sharing a concrete class on its own, just works. But it's behaving very inconsistently with some new structures I'm adding to my application.

    For instance, I'm now having to explicitly set constructor arguments. In other places in my code, this does not have to be done.

    $adapterDefinition = $container
    	->share(ExceptionResponseAdapter::class)
    	->addArguments([
    		ResponseFactoryInterface::class,
    		StreamFactoryInterface::class
    	]);
    

    I can retrieve and dump instances of those requirements before creating this definition and the container resolves them without issue, so I know it's not a matter of those dependencies failing to resolve. However, not explicitly setting the arguments here results in a 'too few arguments' error.

    Likewise, it doesn't attempt to resolve dependencies with addMethodCall being given a class name, and instead passes said class name directly to the method, which obviously fails with a type error.

    $adapterDefinition->addMethodCall('pipe', [$strategy]);
    

    I have again confirmed that it's able to successfully resolve the $strategy independent of this, so I know the dependency isn't failing, and the container is simply refusing to follow instructions.

    opened by alanondra 12
  • invokable with custom arguments

    invokable with custom arguments

    I assumed nobody used this:

    $container->invokable('closure', function ($arg1, $arg2) {
       ...
    });
    
    $container->call('closure', ['value1', 'value2']);
    

    But this is backwards compatible:

    $container->add('item', function ($arg) {
       return $arg;
    })->withArguments('default_value');
    
    echo $container->get('item');
    // 'default_value'
    
    echo $container->get('item', ['override']);
    // 'override'
    

    Fixes #32.

    opened by hannesvdvreken 12
  • Question: where to define inflectors?

    Question: where to define inflectors?

    I had an issue where I had put

    $this->container->inflector(ContainerAwareInterface::class)
                ->inflect('setContainer', [ContainerInterface::class]);
    

    inside the register method of a ServiceProvider. The register method wasn't called because the resolved object wasn't referenced in the container as a ContainerAwareInterface implementation object.

    opened by hannesvdvreken 11
  • Auto wiring a shared dependency

    Auto wiring a shared dependency

    I tried using ReflectionDelegate to achieve auto-wiring and it works mostly great. The issue occurs when I register some services as shared – then they won’t be autowired any more.

    See the following simplified example:

    <?php
    
    require __DIR__ . '/vendor/autoload.php';
    
    class Logger {
        public function __construct(string $name) { }
    }
    
    class Authentication {
        public function __construct(Logger $logger) { }
    }
    
    class AboutController {
        public function __construct(Authentication $authentication) { }
    }
    
    $container = new League\Container\Container();
    
    // Register the reflection container as a delegate to enable auto wiring.
    $container->delegate(new League\Container\ReflectionContainer(true));
    
    $container
        ->add(Authentication::class)
        ->setShared()
    ;
    
    $container
        ->add(Logger::class)
        ->addArgument('selfoss')
        ->setShared()
    ;
    
    var_dump($container->get(AboutController::class));
    
    Fatal error: Uncaught ArgumentCountError: Too few arguments to function Authentication::__construct(), 0 passed and exactly 1 expected in test.php:10
    Stack trace:
    #0 [internal function]: Authentication->__construct()
    #1 src/Definition/Definition.php(212): ReflectionClass->newInstanceArgs(Array)
    #2 src/Definition/Definition.php(175): League\Container\Definition\Definition->resolveClass('Authentication')
    #3 src/Definition/Definition.php(154): League\Container\Definition\Definition->resolveNew()
    #4 src/Definition/DefinitionAggregate.php(79): League\Container\Definition\Definition->resolve()
    #5 src/Container.php(175): League\Container\Definition\DefinitionAggregate->resolve('Authentication')
    #6 src/Container.php(118): League\Container\Container->resolve('Authentication')
    #7 src/Argument/ArgumentResolverTrait.php(45): League\Container\Container->get('Authentication')
    #8 src/Argument/ArgumentResolverTrait.php(107): League\Container\ReflectionContainer->resolveArguments(Array)
    #9 src/ReflectionContainer.php(58): League\Container\ReflectionContainer->reflectArguments(Object(ReflectionMethod), Array)
    #10 src/Container.php(203): League\Container\ReflectionContainer->get('AboutController')
    #11 src/Container.php(118): League\Container\Container->resolve('AboutController')
    #12 test.php(33): League\Container\Container->get('AboutController')
    #13 {main}
      thrown in test.php on line 10
    

    I could addArguments the dependencies explicitly but doing it for all of the shared services would be annoying.

    opened by jtojnar 0
  • Replace deprecated getClass function with getType

    Replace deprecated getClass function with getType

    This change removes the deprecated warning for ReflectionParameter::getClass in PHP 8 and adds support for nullable arguments.

    This change was taken from the 3.x branch.

    opened by MaximVanhove 1
  • Extends causing an infinite loop

    Extends causing an infinite loop

    It seems that #220 fixed #219 in the 3.x branch but the bug still exists in the 4.x branch.

    https://github.com/thephpleague/container/blob/388e992884ab75632d93dbaf4d29ec024d64b964/src/ServiceProvider/ServiceProviderAggregate.php#L72-L75

    opened by kraftner 1
  • Handle preceeding slash in class name handling

    Handle preceeding slash in class name handling

    Resolves https://github.com/thephpleague/container/issues/237

    To summarise that issue:

    • PHP class names may be valid in both the format Foo\Bar and also as \Foo\Bar when used as a string
    • Using Foo::class returns Foo\Bar but legitimate user code may handle as \Foo\Bar and this would work for class_exists or new $var cases
    • Because of this, a concrete class may be set with one form of slash, and got with the other. This means the set definition is not used.
    • This fix adds test for both ways round that this issue could occur, and implements the class name normalizing in each appropriate place

    This aims to be backwards compatible and causes no test failures.

    opened by M1ke 0
Releases(4.2.0)
  • 4.2.0(Nov 16, 2021)

  • 4.1.2(Jul 26, 2021)

  • 4.1.1(Jul 9, 2021)

  • 4.1.0(Jul 9, 2021)

  • 4.0.0(Jul 9, 2021)

    Added

    • New definition interface that extends psr/container
    • Literal and resolvable argument wrappers for better explicitness in definitions

    Changed

    • PHP requirement now >=7.2
    • Updated psr/container to ^2.0.0
    • Container::shared convenience method is now explicit Container::addShared method
    • Removed third argument $shared from Container::add, use Container::addShared
    • ServiceProviderInterface now defines return types
    • Service providers now require implementation of a provides method rather than relying on a class property.
    Source code(tar.gz)
    Source code(zip)
  • 3.4.1(Jul 9, 2021)

  • 3.4.0(Jul 9, 2021)

  • 3.3.4(Feb 22, 2021)

  • 3.3.3(Sep 28, 2020)

  • 3.3.2(Sep 26, 2020)

  • 3.3.1(May 18, 2020)

  • 3.3.0(Jun 30, 2019)

    3.3.0

    Added

    • Support for PHP 7.3
    • {set,get}LeagueContainer methods added to ContainerAwareTrait as a temporary measure until next major release when this can be properly addressed, less hinting of Psr\Container\ContainerInterface

    Changed

    • Various internal code improvements

    Fixed

    • Fix for setConcrete not re-resolving class on when overriding (@jleeothon)
    • Fix stack overflow error incase a service provider lies about providing a specific service (@azjezz)
    • Fix issue where providers may be aggregated multiple times (@bwg)
    • Various documentation fixes
    Source code(tar.gz)
    Source code(zip)
  • 3.2.2(Sep 28, 2018)

  • 3.2.1(Sep 21, 2018)

  • 3.2.0(Aug 13, 2018)

    3.2.0

    Added

    • Added ability to add definition as not shared when container is set to default to shared.
    • Added {set|get}Concrete to definitions to allow for better use of extend.

    (Thanks to @jenssegers for these)

    Source code(tar.gz)
    Source code(zip)
  • 3.1.0(Aug 12, 2018)

    3.1.0

    Added

    • Re-added the share proxy method that was mistakenly removed in previous major release.
    • Added ability to set Conatiner to "share" by default using defaultToShared method.
    • Added ability for ReflectionContainer to cache resolutions and pull from cache for following calls.
    Source code(tar.gz)
    Source code(zip)
  • 3.0.1(Jul 25, 2018)

  • 3.0.0(Jul 23, 2018)

    3.0.0

    Added

    • Service providers can now be pulled from the container if they are registered.
    • Definition logic now handled by aggregate for better separation.
    • Now able to add tags to a definition to return an array of items containing that tag.

    Changed

    • Updated minimum PHP requirements to 7.0.
    • Now depend directly on PSR-11 interfaces, including providing PSR-11 exceptions.
    • Refactored inflector logic to accept type on construction and use generator to iterate.
    • Refactored service provider logic with better separation and performance.
    • Merged service provider signature logic in to one interface and abstract.
    • Heavily simplified definition logic providing more control to user.
    Source code(tar.gz)
    Source code(zip)
  • 2.4.1(May 10, 2017)

  • 2.4.0(Mar 6, 2017)

    Changed

    • Can now wrap shared objects as RawArgument.
    • Ability to override shared items.

    Fixed

    • Booleans now recognised as accepted values.
    • Various docblock fixes.
    • Unused imports removed.
    • Unreachable arguments no longer passed.
    Source code(tar.gz)
    Source code(zip)
  • 2.3.0(Mar 6, 2017)

  • 2.2.0(Mar 17, 2016)

  • 2.1.0(Mar 15, 2016)

  • 2.0.3(Sep 7, 2015)

    Fixed

    • Bug where delegating container was not passed to delegate when needed.
    • Bug where Container::extend would not return a shared definition to extend.
    Source code(tar.gz)
    Source code(zip)
  • 2.0.2(Sep 3, 2015)

  • 2.0.1(Sep 2, 2015)

  • 2.0.0(Sep 2, 2015)

    Added

    • Now implementation of the container-interop project.
    • BootableServiceProviderInterface for eagerly loaded service providers.
    • Delegate container functionality.
    • RawArgument to ensure scalars are not resolved from the container but seen as an argument.

    Altered

    • Refactor of definition functionality.
    • Container::share replaces singleton functionality to improve understanding.
    • Auto wiring is now disabled by default.
    • Auto wiring abstracted to be a delegate container ReflectionContainer handling all reflection based functionality.
    • Inflection functionality abstracted to an aggregate.
    • Service provider functionality abstracted to an aggregate.
    • Much bloat removed.
    • Container::call now proxies to ReflectionContainer::call and handles argument resolution in a much more efficient way.

    Removed

    • Ability to register invokables, this functionality added a layer of complexity too large for the problem it solved.
    • Container no longer accepts a configuration array, this functionality will now be provided by an external service provider package.
    Source code(tar.gz)
    Source code(zip)
  • 1.3.1(Feb 21, 2015)

  • 1.3.0(Feb 9, 2015)

    1.3.0 - 2015-02-09

    Added

    • Added ServiceProvider functionality to allow cleaner resolving of complex dependencies.
    • Added Inflector functionality to allow for manipulation of resolved objects of a specific type.
    • Improvements to DRY throughout the package.

    Fixed

    • Setter in ContainerAwareTrait now returns self ($this).
    Source code(tar.gz)
    Source code(zip)
  • 1.2.1(Jan 29, 2015)

    1.2.1 - 2015-01-29

    Added

    • Nothing

    Deprecated

    • Nothing

    Fixed

    • Allow arbitrary values to be registered via container config.

    Removed

    • Nothing

    Security

    • Nothing
    Source code(tar.gz)
    Source code(zip)
Owner
The League of Extraordinary Packages
A group of developers who have banded together to build solid, well tested PHP packages using modern coding standards.
The League of Extraordinary Packages
The dependency injection container for humans

layout home PHP-DI is a dependency injection container meant to be practical, powerful, and framework-agnostic. Read more on the website: php-di.org G

null 2.4k Jan 4, 2023
πŸ’Ž Flexible, compiled and full-featured Dependency Injection Container with perfectly usable autowiring and support for all new PHP 7 features.

Nette Dependency Injection (DI) Introduction Purpose of the Dependecy Injection (DI) is to free classes from the responsibility for obtaining objects

Nette Foundation 781 Dec 15, 2022
PSR-11 compatible Dependency Injection Container for PHP.

bitexpert/disco This package provides a PSR-11 compatible, annotation-based dependency injection container. Have a look at the disco-demos project to

bitExpert AG 137 Sep 29, 2022
πŸš€ PHP Service Container with fast and cachable dependency injection.

ClanCats Container A PHP Service Container featuring a simple meta-language with fast and compilable dependency injection. Requires PHP >= 7.0 Pros: M

ClanCats 28 Apr 13, 2022
Twittee is the smallest, and still useful, Dependency Injection Container in PHP

What is Twittee? Twittee is the smallest, and still useful, Dependency Injection Container in PHP; it is also probably one of the first public softwar

null 133 Dec 5, 2022
Dependency Injection System

Aura.Di A serializable dependency injection container with constructor and setter injection, interface and trait awareness, configuration inheritance,

Aura for PHP 342 Dec 1, 2022
Yii Dependency Injection PSR-11 compatible

Yii Dependency Injection PSR-11 compatible dependency injection container that is able to instantiate and configure classes resolving dependencies. Fe

Yii Software 161 Nov 10, 2022
IoC Dependency Injector

auryn auryn is a recursive dependency injector. Use auryn to bootstrap and wire together S.O.L.I.D., object-oriented PHP applications. How It Works Am

Daniel Lowrey 725 Nov 23, 2022
IoC Dependency Injector

auryn auryn is a recursive dependency injector. Use auryn to bootstrap and wire together S.O.L.I.D., object-oriented PHP applications. How It Works Am

Daniel Lowrey 710 Apr 15, 2021
Dependency Manager for PHP

Composer - Dependency Management for PHP Composer helps you declare, manage, and install dependencies of PHP projects. See https://getcomposer.org/ fo

Composer 27.2k Dec 31, 2022
DI Container (PSR-11)

My DI Container It's my own implementation PSR-11 Container Interface. Installation composer require scruwi/container Init $container = new Container(

null 4 Mar 15, 2022
This repository holds all interfaces related to PSR-11 (Container Interface).

Container interface This repository holds all interfaces related to PSR-11 (Container Interface). Note that this is not a Container implementation of

PHP-FIG 9.6k Jan 4, 2023
Extensible DI container for Symfony2

This package contains an implementation of the Symfony 2 DI container that can be extended using other DI containers (from other frameworks).

TheCodingMachine 1 Apr 2, 2014
A small PHP dependency injection container

Pimple Caution! Pimple is now closed for changes. No new features will be added and no cosmetic changes will be accepted either. The only accepted cha

Silex 2.6k Dec 29, 2022
The dependency injection container for humans

layout home PHP-DI is a dependency injection container meant to be practical, powerful, and framework-agnostic. Read more on the website: php-di.org G

null 2.4k Jan 4, 2023
πŸ’Ž Flexible, compiled and full-featured Dependency Injection Container with perfectly usable autowiring and support for all new PHP 7 features.

Nette Dependency Injection (DI) Introduction Purpose of the Dependecy Injection (DI) is to free classes from the responsibility for obtaining objects

Nette Foundation 781 Dec 15, 2022
PSR-11 compatible Dependency Injection Container for PHP.

bitexpert/disco This package provides a PSR-11 compatible, annotation-based dependency injection container. Have a look at the disco-demos project to

bitExpert AG 137 Sep 29, 2022
πŸš€ PHP Service Container with fast and cachable dependency injection.

ClanCats Container A PHP Service Container featuring a simple meta-language with fast and compilable dependency injection. Requires PHP >= 7.0 Pros: M

ClanCats 28 Apr 13, 2022
Twittee is the smallest, and still useful, Dependency Injection Container in PHP

What is Twittee? Twittee is the smallest, and still useful, Dependency Injection Container in PHP; it is also probably one of the first public softwar

null 133 Dec 5, 2022
Dependency Injection System

Aura.Di A serializable dependency injection container with constructor and setter injection, interface and trait awareness, configuration inheritance,

Aura for PHP 342 Dec 1, 2022