All Notable changes to League\Container will be documented in this file
- Container compilation - compile a bootstrapped container into a standalone PHP class implementing PSR-11
ContainerInterface, eliminating reflection and definition resolution at runtime (#279)Compilerentry point withcompile()andisStale()methodsDefinitionAnalyserfor inspecting definitions, classifying types, resolving autowiring, and building the dependency graphCodeGeneratorfor producing compiled PHP source via string templating (zero new dependencies)ArgumentCompilerfor converting argument descriptors to PHP code expressionsDependencyGraphwith cycle detection (DFS with visited/in-stack colouring) and topological ordering- Value objects:
CompiledDefinition,CompilationConfig,CompilationResult,AnalysisResult,ConcreteTypeenum CompilationExceptionwith structured errors (service ID, error type, message, suggested fix)ContainerFactoryfor switching between compiled and dynamic containers based on environmentbin/container-compileCLI binary with--input,--output,--class,--namespace,--check,--dry-runoptionsServiceProviderAggregateInterface::registerAll()for force-registering all lazy providers before compilation- Pre-flight validation collecting all errors before failing, with actionable suggested fixes
- SHA-256 source hash for staleness detection based on normalised definition state
- Contextual binding - bind different implementations of an interface depending on the consuming class
DefinitionInterface::addContextualArgument(string $abstract, string|object $concrete)for per-definition contextual resolutionDefinitionInterface::getContextualArguments()to retrieve stored bindings- Runtime resolution via
Definition::resolveClass()with constructor reflection - Full compilation support: contextual arguments resolved at compile time into direct service references
- Improved error messages with runtime circular dependency detection
NotFoundException::forAlias()with Levenshtein-based "did you mean?" suggestions for mistyped service IDs- Runtime circular dependency detection via resolution stack in
Container::resolve()with descriptive chain messages - Resolution chain context in nested dependency failure messages
- Service provider class identification in "service provider lied" errors
- Container introspection for debugging
Container::getDefinitionIds()returns all registered service IDsContainer::getServiceProviderIds()returns all IDs claimed by providers (lazy or registered)ServiceProviderInterface::getProvidedIds()for providers to declare their full service list--dumpflag onbin/container-compilefor service summary output
#[Shared]attribute - class-level attribute declaring singleton intent for auto-wired classes viaReflectionContainer, with compilation support- PHP 8.5 support (first-class CI target)
- Typed class constants throughout (
ReflectionContainer,LiteralArgument,DependencyGraph) #[\Override]attribute on all interface implementations and trait methodsreadonly classdeclarations for compiler value objects (CompilationConfig,CompilationResult,CompiledDefinition)- Pest v4 arch tests enforcing strict types, final compiler classes, and exception hierarchy
- Granular Composer scripts:
test:unit,test:types,test:style
- PHP minimum version raised from
^8.1to^8.3 - Testing framework migrated from PHPUnit to Pest v4
- Test mocking framework migrated from PHPUnit mocks to Mockery, with explicit stub/expectation separation (
allowsvsshouldReceive) - Coding standard migrated from PHP CodeSniffer (PSR-12) to PHP CS Fixer (PER-CS 2.0)
- PHPStan analysis level raised from 6 to 8 with all blanket suppressions removed
ContainerAwareInterface::setContainer()now returnsstaticinstead ofContainerAwareInterfaceContainer::get()andReflectionContainer::get()now declare: mixedreturn type (PSR-11 v2 alignment)LiteralArgumentnow throws with actionable error messages including expected and actual typesget_class()calls replaced with::classsyntax throughoutcall_user_func_arraycalls replaced with spread syntaxpsr/container-implementationprovide version corrected from^1.0to^2.0
- Removed
ContainerAwareTraittest that was incompatible with#[\Override]enforcement in PHP 8.3+ - Test mocking of
DefinitionInterfaceand Reflection classes now explicitly stubs all called methods, preventing silent pass-through on unmocked interactions
- Inflector subsystem (
Inflector,InflectorAggregate,InflectorAggregateInterface,InflectorInterface) - useContainer::afterResolve()or the event system instead Container::inflector()method (deprecated in 5.2)inflector()fromDefinitionContainerInterfaceDefinition::$recursiveCheck(dead code, written but never read)- Scrutinizer CI integration (
.scrutinizer.yml,scrutinizer/ocular) orno/direplace directive fromcomposer.json- Unused dev dependencies:
nette/php-generator,nikic/php-parser - Stale branch aliases for 1.x through 4.x
- Event system for hooking into the container lifecycle
- Four event types:
OnDefineEvent,BeforeResolveEvent,DefinitionResolvedEvent,ServiceResolvedEvent - Fluent filtering API:
forType(),forTag(),forId(),where() Container::listen()for registering filtered event listenersContainer::afterResolve()convenience method as a drop-in replacement forinflector()- Lazy event dispatch: events are only created when listeners are registered for that event type
EventDispatcher::hasListenersFor()to check whether listeners exist for a given event typeDefinitionInterface::getTags()for retrieving tags from definitions- Docs: https://container.thephpleague.com/5.x/events/
- Four event types:
Container::getDelegate(string $class)to retrieve a registered delegate container by type
- Interface-to-concrete definitions now correctly resolve through the concrete's own registered definition instead of bypassing it via direct reflection (#275, #278)
Definition::resolveClass()now throwsContainerExceptionwith actionable guidance when a class has unsatisfied constructor dependencies, instead of a rawArgumentCountError
Container::inflector()- useContainer::afterResolve()or the event system instead. Will be removed in v6.0.
DefinitionContainerInterfaceno longer extendsEventAwareContainerInterface(removed)- Shared definitions now receive a
'shared'tag automatically viaaddTag('shared')
EventAwareContainerInterface- the event system is provided byEventAwareTraiton the concreteContainerclass, not as an interface contract
- Attribute based resolution for dependencies using
#[Inject]and#[Resolve]attributes. - Support for PHPUnit 12 (@ADmad)
- Explicit non-support for auto-wiring union types.
- Small internal changes for stricter static analysis and type safety. (@ADmad)
- Fixed a small unreachable code bug
- Ability to overwrite a definition within the container, disabled by default
- PHP requirement now
>=8.1 - General language modernisation
- General prep for future updates and container compilation
- Now properly handle string based fully qualified class names in with preceding slashes. (@M1ke)
- Warnings for PHP 8.4 implicit nullable types (@andypost)
- Remove an unnecessary conditional in ServiceProviderAggregate. (@SubhanSh)
- Fixed an infinite loop in resolving definitions. (@arai-ta)
- Support for psr/container 1.1.0.
- Fix bug that was causing an error on inflection due to introduced type hint.
- Move files autoload directive to dev (@ADmad)
- Way to handle non-public controllers safely (@beryllium)
- New definition interface that extends psr/container
- Literal and resolvable argument wrappers for better explicitness in definitions
- PHP requirement now
>=7.2 - Updated
psr/containerto ^2.0.0 Container::sharedconvenience method is now explicitContainer::addSharedmethod- Removed third argument
$sharedfromContainer::add, useContainer::addShared ServiceProviderInterfacenow defines return types- Service providers now require implementation of a
providesmethod rather than relying on a class property.
- Way to handle non-public controllers safely (@beryllium)
- PHPUnit ^7.0 for PHP versions that support it (@beryllium)
- Support for
psr/container^2.0.0 as the interface cannot be reconciled between versions
- Support for
psr/container^2.0.0
- Fixed an issue that caused a recursive
registercall. @pcoutinho - Fixed a return type declaration. @orbex
- Fixed bug relating to
ReflectionContainer::callon arrow functions.
- Experimental support for PHP 8.
- Fix issue when preventing reflection from using default value for arguments.
- Respect
$newargument when getting tagged definitions.
- Support for PHP 7.3
{set,get}LeagueContainermethods added to ContainerAwareTrait as a temporary measure until next major release when this can be properly addressed, less hinting ofPsr\Container\ContainerInterface
- Various internal code improvements
- Fix for
setConcretenot 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
- Fixed issue that prevented service providers from registering if a previous one in the aggregate was already registered.
- Fixed issue where all service providers were registered regardless of whether they need to be.
- Added ability to add definition as not shared when container is set to default to shared.
- Added
{set|get}Concreteto definitions to allow for better use ofextend.
- Re-added the
shareproxy method that was mistakenly removed in previous major release. - Added ability to set Container to "share" by default using
defaultToSharedmethod. - Added ability for
ReflectionContainerto cache resolutions and pull from cache for following calls.
- Allow definition aggregates to be built outside of container.
- 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.
- 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.
- Ensures
ReflectionContainerconverts class name in array callable to object.
- Can now wrap shared objects as
RawArgument. - Ability to override shared items.
- Booleans now recognised as accepted values.
- Various docblock fixes.
- Unused imports removed.
- Unreachable arguments no longer passed.
- Now implementation of the PSR-11.
- Service providers can now be added multiple times by giving them a signature.
- Allow resolving of
RawArgumentobjects as first class dependencies.
- Unnecessary recursion removed from
Container::get.
- Bug where delegating container was not passed to delegate when needed.
- Bug where
Container::extendwould not return a shared definition to extend.
- Bug introduced in 2.0.1 where shared definitions registered via a service provider would never be returned as shared.
- Bug where shared definitions were not stored as shared.
- Now implementation of the container-interop project.
BootableServiceProviderInterfacefor eagerly loaded service providers.- Delegate container functionality.
RawArgumentto ensure scalars are not resolved from the container but seen as an argument.
- Refactor of definition functionality.
Container::sharereplacessingletonfunctionality to improve understanding.- Auto wiring is now disabled by default.
- Auto wiring abstracted to be a delegate container
ReflectionContainerhandling all reflection based functionality. - Inflection functionality abstracted to an aggregate.
- Service provider functionality abstracted to an aggregate.
- Much bloat removed.
Container::callnow proxies toReflectionContainer::calland handles argument resolution in a much more efficient way.
- 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.
- Added
isRegisteredCallablemethod to public API. - Invoking
callnow accepts named arguments at runtime.
- Container now stores instantiated Service Providers after first instantiation.
- Extending a definition now looks in Service Providers as well as just Definitions.
- Fixed bug where arbitrary values were attempted to be resolved as classes.
- Added
ServiceProviderfunctionality to allow cleaner resolving of complex dependencies. - Added
Inflectorfunctionality to allow for manipulation of resolved objects of a specific type. - Improvements to DRY throughout the package.
- Setter in
ContainerAwareTraitnow returns self ($this).
- Allow arbitrary values to be registered via container config.
- Improvements to
Container::callfunctionality.
- General code tidy.
- Improvements to test suite.
- Allow singleton to be passed as method argument.
- Addition of
ContainerAwareTraitto provide functionality fromContainerAwareInterface.
- Migrated from Orno\Di.