elie29 / zend-phpdi-config
PSR-11 PHP-DI autowire container configurator for Laminas, Mezzio, ZF2, ZF3 and Zend Expressive applications
Installs: 227 570
Dependents: 9
Suggesters: 0
Security: 0
Stars: 19
Watchers: 3
Forks: 5
Open Issues: 0
pkg:composer/elie29/zend-phpdi-config
Requires
- php: ^8.2
- laminas/laminas-stdlib: ^3.12
- php-di/php-di: ^7.0
Requires (Dev)
- mikey179/vfsstream: ^1.6
- phpro/grumphp: ^2.0
- phpunit/phpunit: ^11.0
- dev-master
- v10.0.2
- v10.0.1
- v10.0.0
- v9.0.3
- v9.0.2
- v9.0.1
- v9.0.0
- v8.1.1
- v8.1.0
- v8.0.0
- 7.x-dev
- 6.x-dev
- v6.0.1
- v6.0.0
- 5.x-dev
- v5.0.0
- 4.x-dev
- v4.0.5
- v4.0.4
- v4.0.3
- v4.0.2
- v4.0.1
- 3.x-dev
- v3.0.12
- v3.0.11
- v3.0.10
- v3.0.9
- v3.0.8
- v3.0.7
- v3.0.6
- v3.0.5
- v3.0.4
- v3.0.3
- v3.0.2
- v3.0.1
- v3.0.0
- V2.0.2
- V2.0.1
- v2.0.0
- v1.0.5
- v1.0.4
- v1.0.3
- v1.0.2
- v1.0.1
- v1.0.0
This package is auto-updated.
Last update: 2026-01-03 14:49:45 UTC
README
๐ Quick Start
composer require elie29/zend-phpdi-config
<?php declare(strict_types=1); use Elie\PHPDI\Config\Config; use Elie\PHPDI\Config\ContainerFactory; $container = (new ContainerFactory())( new Config(require __DIR__ . '/config/config.php') );
โจ Features
- ๐งฉ PSR-11 compatible container configuration
- โก Autowiring support
- ๐ Service manager compatibility (Laminas/Mezzio)
- ๐ป CLI tool for autowire entry management
- ๐๏ธ Cache and proxy support
- ๐ Easy migration from other containers
๐ Introduction
zend-phpdi-config acts as a bridge to configure a PSR-11 compatible PHP-DI container using service manager configuration.
Requirements: PHP 8.2 or higher
It can be used with Laminas and Mezzio starting from v10.0.0
This library uses autowiring technique, cache compilation and cache definitions as defined in PHP-DI.
๐ ๏ธ Configuration
To get a configured PSR-11 PHP-DI container, do the following:
<?php declare(strict_types=1); use Elie\PHPDI\Config\Config; use Elie\PHPDI\Config\ContainerFactory; $factory = new ContainerFactory(); $container = $factory( new Config([ 'dependencies' => [ 'services' => [], 'invokables' => [], 'autowires' => [], // A new key added to support PHP-DI autowire technique 'factories' => [], 'aliases' => [], 'delegators' => [], ], // ... other configuration // Enable compilation Config::DI_CACHE_PATH => __DIR__, // Folder path // Write proxies to file: cf. https://php-di.org/doc/lazy-injection.html Config::DI_PROXY_PATH => __DIR__, // Folder path // Disable autowire (enabled by default) Config::USE_AUTOWIRE => false // Enable cache Config::ENABLE_CACHE_DEFINITION => false, // boolean, true if APCu is activated ]) );
Configuration Keys
The dependencies configuration array supports the following keys:
-
services: Maps a service name to a specific service instance, class name, or callable.- Values can be object instances, class names, or callables
- Used for registering pre-instantiated services or simple service definitions
- See ServicesTest.php for comprehensive examples
-
invokables: Maps service names to classes with no constructor dependencies.- Can be an associative array (alias => class name) or indexed array (class names)
- When alias differs from class name, the alias is created automatically
- Classes must have no required constructor parameters
- See InvokablesTest.php for comprehensive examples
-
autowires: Array of fully qualified class names to be autowired by PHP-DI.- PHP-DI automatically resolves constructor dependencies through type-hinting
- Works with or without constructor parameters
- Create aliases separately in the
aliasesconfiguration if needed
-
factories: Maps service names to factory classes or callables.- Factory classes must implement
__invoke(ContainerInterface $container) - Can reference other registered factories by name
- Factories must return the actual service instance (object, array, scalar, etc.), not service names
- Used when service instantiation requires custom or dynamic logic
- See FactoriesTest.php for comprehensive examples
- Factory classes must implement
-
aliases: Maps alias names to service names or other aliases.- Allows multiple names to resolve to the same service instance
- Can chain aliases (alias โ alias โ service)
- Only
invokablescreate aliases automatically
-
delegators: Maps service names to arrays of delegator factory classes.- Decorates or wraps services with additional functionality
- Delegators are applied in the order specified
- See Laminas delegators documentation for details
N.B.: All configuration except
dependenciesis merged into aconfigkey within the$container:$config = $container->get('config');
๐ป CLI Usage
The CLI command add-autowires-entry creates the configuration file if it doesn't exist, otherwise it adds the entry
to the autowires key.
Example of adding ConsoleHelper to a config.php:
./vendor/bin/add-autowires-entry config.php "Laminas\\Stdlib\\ConsoleHelper" [DONE] Changes written to config.php
You can also add this as a Composer script:
"scripts": { "add-autowire": "add-autowires-entry config.php \"My\\Service\\Class\"" }
๐งช Development & Testing
Running Tests
# Run tests (no coverage) composer test # Run with coverage (requires Xdebug) composer test-coverage # Run coverage + serve HTML report composer cover # Opens localhost:5001
Git Hooks with GrumPHP
This project uses GrumPHP to automatically run tests before each commit.
After running composer install, GrumPHP will:
- Install git hooks automatically
- Run
composer testbefore every commit - Block commits if tests fail
Bypass the hook (not recommended):
git commit --no-verify -m "Your message"
Configure GrumPHP: Edit grumphp.yml to customize tasks and behavior.
๐ Troubleshooting / FAQ
Q: My service is not autowired.
A: Ensure it is listed in the autowires array and all dependencies are available.
Q: The CLI tool fails with a permissions error. A: Make sure the config file directory is writable.
Q: How do I debug container errors? A: Check that all dependencies are correctly defined and that your factories do not throw exceptions.
Using with Mezzio (formerly Expressive)
Replace contents of config/container.php with the following:
<?php declare(strict_types=1); use Elie\PHPDI\Config\Config; use Elie\PHPDI\Config\ContainerFactory; // Protect variables from global scope return call_user_func(function () { $config = require __DIR__ . '/config.php'; $factory = new ContainerFactory(); // Container return $factory(new Config($config)); });
Example of a ConfigProvider class
<?php declare(strict_types=1); class ConfigProvider { /** * Returns the configuration array */ public function __invoke(): array { return [ 'dependencies' => $this->getDependencies() ]; } /** * Returns the container dependencies */ public function getDependencies(): array { return [ 'autowires' => [ UserManager::class ] ]; } }
Where UserManager depends on Mailer as follows:
<?php declare(strict_types=1); class UserManager { private $mailer; public function __construct(Mailer $mailer) { $this->mailer = $mailer; } public function register($email, $password) { $this->mailer->mail($email, 'Hello and welcome!'); } } class Mailer { public function mail($recipient, $content) { } }
Switching back to another container
To switch back to another container is straightforward:
- Create your factories with
__invokefunction - Replace
autowireskey in ConfigProvider byfactorieskey, then for each class name attach its correspondent factory.
PSR 11 and Interop\Container\ContainerInterface
V4.x supports as well Interop\Container\ContainerInterface
Migration guides
- Migration from 3.x to 4.0
- Migration from 4.x to 5.0: container-interop/container-interop was dropped in favor of PSR-11.
๐ค Contributing
See CONTRIBUTING.md for guidelines on how to contribute, run tests, and submit pull requests.
๐ License
This project is licensed under the MIT License. See LICENSE for details.