idrinth / quickly
A fast dependency injection container featuring build time resolution.
Requires
- php: ^8.4
- psr/container: ^2.0.2
Requires (Dev)
- phpunit/phpunit: ^12.3.7
This package is auto-updated.
Last update: 2025-09-07 02:06:24 UTC
README
A fast dependency injection container for PHP featuring build-time resolution and PSR-11 compliance.
Features
- ✅ PSR-11 Compliant - Fully compatible with PSR-11 Container Interface
- ⚡ Build-time Resolution - Pre-compile dependency graphs for maximum performance
- 🔧 Autowiring - Automatic dependency resolution using reflection
- 🌍 Environment Injection - Direct injection of environment variables
- 🏭 Factory Pattern Support - Flexible object creation with custom factories
- 💤 Lazy Initialization - Defer object creation until needed
- 🔄 Circular Dependency Detection - Prevents infinite dependency loops
- 📋 Validation Tools - Command-line tools for configuration validation
Requirements
- PHP 8.4 or higher
- PSR Container 2.0.2+
Installation
composer require idrinth/quickly
Quick Start
Basic Usage
use Idrinth\Quickly\EnvironmentFactory; // Create container factory $factory = new EnvironmentFactory(); $container = $factory->createContainer(); // Get services $myService = $container->get(MyService::class);
With Reflection (Development Mode)
Set the DI_USE_REFLECTION=true
environment variable to enable automatic dependency resolution:
// Your environment $_ENV['DI_USE_REFLECTION'] = 'true'; // Container will automatically resolve dependencies $container = $factory->createContainer(); $service = $container->get(SomeService::class);
Dependency Injection Attributes
Environment Variable Injection
use Idrinth\Quickly\DependencyInjection\EnvironmentInject; class DatabaseService { public function __construct( #[EnvironmentInject('DATABASE_URL')] private string $databaseUrl, #[EnvironmentInject('DB_TIMEOUT')] private int $timeout = 30 ) {} }
Factory-based Resolution
use Idrinth\Quickly\DependencyInjection\ResolveWithFactory; use Idrinth\Quickly\DependencyInjection\Factory; class MyFactory implements Factory { public function pickImplementation(string $parameter, string $key, string $forClass): string { return ConcreteImplementation::class; } } class ServiceConsumer { public function __construct( #[ResolveWithFactory(MyFactory::class, 'implementation-key')] private SomeInterface $service ) {} }
Lazy Initialization
use Idrinth\Quickly\DependencyInjection\LazyInitialization; #[LazyInitialization] class ExpensiveService { }
Command Line Tools (ALL WIP)
Quickly provides several CLI commands accessible via vendor/bin/quickly
:
Build Configuration
vendor/bin/quickly build [filepath]
Creates an optimized production configuration file for maximum performance.
Validate Configuration
vendor/bin/quickly validate [filepath]
Validates your dependency injection configuration for errors.
Help
vendor/bin/quickly help
Shows available commands and usage information.
Configuration
Manual Configuration
use Idrinth\Quickly\DependencyInjection\Container; use Idrinth\Quickly\DependencyInjection\Definitions\ClassObject; use Idrinth\Quickly\DependencyInjection\Definitions\Environment; $container = new Container( environments: $_ENV, constructors: [ MyService::class => [ new ClassObject(Dependency::class), new Environment('CONFIG_VALUE') ] ], classAliases: [ 'MyInterface' => 'ConcreteImplementation' ] );
Generated Configuration
For production use, generate optimized configuration:
// .quickly/generated.php (example) return [ 'constructors' => [ // Pre-resolved constructor dependencies ], 'factories' => [ // Factory mappings ], 'classAliases' => [ // Interface to implementation mappings ] ];
Environment Variable Mapping
Environment variables are automatically converted to camelCase for injection:
DATABASE_URL
→databaseUrl
API_KEY
→apiKey
REDIS_HOST
→redisHost
Error Handling
Quickly provides specific exceptions for different error scenarios:
DependencyNotFound
- Service not registeredDependencyUnbuildable
- Cannot construct serviceCircularDependency
- Circular dependency detectedInvalidClassName
- Invalid class name providedNoImplementationFound
- Factory cannot resolve implementation
Advanced Features
Circular Dependency Detection
// This will throw CircularDependency exception class ServiceA { public function __construct(ServiceB $serviceB) {} } class ServiceB { public function __construct(ServiceA $serviceA) {} }
Singleton Behavior
All services are automatically singletons - the same instance is returned for subsequent requests:
$service1 = $container->get(MyService::class); $service2 = $container->get(MyService::class); // $service1 === $service2
Testing
Run the test suite:
composer test
Or with PHPUnit directly:
vendor/bin/phpunit
Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add some amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Author
Björn 'Idrinth' Büttner
Built with ❤️ for high-performance PHP applications.