diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8925195 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.idea +vendor +composer.lock \ No newline at end of file diff --git a/README.md b/README.md index 2ca25a9..b63f9e1 100644 --- a/README.md +++ b/README.md @@ -1 +1,60 @@ -# Zend-Expressive-Bridge \ No newline at end of file +# Zend-Expressive-Bridge + +The easiest way to use PHP-DI with Zend Expressive, seems to: + + - use the Dependency Injection Container Builder provided by this library using some default definition files + - add your own Dependency Definitions to the Container Builder + - use the Dependency Injection Container to fetch the Zend Expressive Application + - run the Application + - for example using the PHP internal WebServer: `php -S 0.0.0.0:8080 -t public/` + +## In your `./public/index.php` + +```php + +get(\Zend\Expressive\Application::class); +$app->run(); + +``` +## In your `./config/container.php` + + +```php +registerXYZRouter(); //Choose your preferred Router +$containerBuilder->registerXYZRenderer(); //Choose your preferred template Renderer +$containerBuilder->writeProxiesToFile($inProduction, __DIR__ . '/../data/cache'); //You probably want to use caching in production + +/** + * Add your own, application-specific, Dependency Definitions to the Container Builder + * @link https://zend-expressive.readthedocs.io/en/latest/features/modular-applications/ + */ +$pathToDependencyDefinitions = __DIR__ . '/../config/dependencies/{{,*.}global,{,*.}local}.php'; +$phpFileProvider = new \Zend\ConfigAggregator\PhpFileProvider($pathToDependencyDefinitions); +$dependencyDefinitions = $phpFileProvider(); +foreach ($dependencyDefinitions as $definitions) { + $containerBuilder->addDefinitions($definitions); +} + +$container = $containerBuilder->build(); + +//Assign configuration to container +$config = require __DIR__ . '/../config.php'; +$container->set('config', $config); + +return $container; +``` diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..b619ef1 --- /dev/null +++ b/composer.json @@ -0,0 +1,28 @@ +{ + "name": "php-di/zend-expressive-bridge", + "description": "PHP-DI integration in Zend Expressive", + "license": "MIT", + "type": "library", + "require": { + "php": "^7.1", + "php-di/php-di": "^6.0", + "zendframework/zend-expressive": "^2.0", + "zendframework/zend-expressive-helpers": "^4.0", + "http-interop/http-server-middleware": "^1.0", + "http-interop/http-middleware": "^0.5.0" + }, + "autoload": { + "psr-4": { + "DI\\": "src/DI" + } + }, + "suggest": { + "zendframework/zend-config-aggregator": "To easily add application specific Dependency Definitions to the ContainerBuilder", + "zendframework/zend-expressive-aurarouter": "To route requests using Aura.Router", + "zendframework/zend-expressive-fastroute": "To route requests using FastRoute", + "zendframework/zend-expressive-zendrouter": "To route requests using zend-mvc Router", + "zendframework/zend-expressive-platesrenderer": "To use Plates as templating engine", + "zendframework/zend-expressive-twigrenderer": "To use Twig as templating engine", + "zendframework/zend-expressive-zendviewrenderer": "To use zend-view PhpRenderer as templating engine" + } +} diff --git a/src/DI/ExpressiveContainerBuilder.php b/src/DI/ExpressiveContainerBuilder.php new file mode 100644 index 0000000..c747ca4 --- /dev/null +++ b/src/DI/ExpressiveContainerBuilder.php @@ -0,0 +1,101 @@ +registerDependencies(); + $this->registerErrorHandler($inProduction); + $this->registerMiddlewarePipeline(); + } + + private function registerDependencies(): void + { + $this->addDefinitions([ + \Interop\Container\ContainerInterface::class => function (\Interop\Container\ContainerInterface $container) { + return $container; + }, + \Zend\Expressive\Application::class => \DI\factory(\Zend\Expressive\Container\ApplicationFactory::class), + \Zend\Expressive\Container\ApplicationFactory::class => \DI\autowire(), + \Zend\Expressive\Helper\ServerUrlHelper::class => \DI\autowire(), + \Zend\Expressive\Helper\UrlHelper::class => \DI\factory(\Zend\Expressive\Helper\UrlHelperFactory::class), + ]); + } + + private function registerErrorHandler(bool $inProduction): void + { + $this->addDefinitions([ + \Zend\Expressive\Container\WhoopsErrorHandlerFactory::class => \DI\autowire()->lazy(), + \Zend\Expressive\Container\WhoopsFactory::class => \DI\autowire()->lazy(), + \Zend\Expressive\Container\WhoopsPageHandlerFactory::class => \DI\autowire()->lazy(), + 'Zend\Expressive\Whoops' => \DI\factory(\Zend\Expressive\Container\WhoopsFactory::class), + 'Zend\Expressive\WhoopsPageHandler' => \DI\factory(\Zend\Expressive\Container\WhoopsPageHandlerFactory::class), + 'Zend\Expressive\FinalHandler' => $inProduction ? \DI\factory(\Zend\Expressive\Container\TemplatedErrorHandlerFactory::class) : \DI\factory(\Zend\Expressive\Container\WhoopsErrorHandlerFactory::class), + ]); + } + + public function registerAuraRouter(): void + { + $this->addDefinitions([ + \Zend\Expressive\Router\RouterInterface::class => \DI\get(\Zend\Expressive\Router\AuraRouter::class), + \Zend\Expressive\Router\AuraRouter::class => \DI\autowire(), + ]); + } + + public function registerFastRouteRouter(): void + { + $this->addDefinitions([ + \Zend\Expressive\Router\RouterInterface::class => \DI\get(\Zend\Expressive\Router\FastRouteRouter::class), + \Zend\Expressive\Router\FastRouteRouter::class => \DI\autowire(), + ]); + } + + public function registerZendRouter(): void + { + $this->addDefinitions([ + \Zend\Expressive\Router\RouterInterface::class => \DI\get(\Zend\Expressive\Router\ZendRouter::class), + \Zend\Expressive\Router\ZendRouter::class => \DI\autowire(), + ]); + } + + public function registerPlatesRenderer(): void + { + $this->addDefinitions([ + \Zend\Expressive\Template\TemplateRendererInterface::class => \DI\factory(\Zend\Expressive\Plates\PlatesRendererFactory::class), + ]); + } + + public function registerTwigRenderer(): void + { + $this->addDefinitions([ + \Zend\Expressive\Template\TemplateRendererInterface::class => \DI\factory(\Zend\Expressive\Twig\TwigRendererFactory::class), + ]); + } + + /** + * Note that ZendViewRendererFactory::injectHelpers() seems to use an incorrect 'default' HelperPluginManager resulting in: + * Deprecated: Zend\ServiceManager\AbstractPluginManager::__construct now expects a Interop\Container\ContainerInterface instance representing the parent container; please update your code in + * + * @see \Zend\Expressive\ZendView\ZendViewRendererFactory::injectHelpers() + */ + public function registerZendViewRenderer(): void + { + $this->addDefinitions([ + \Zend\Expressive\Template\TemplateRendererInterface::class => \DI\factory(\Zend\Expressive\ZendView\ZendViewRendererFactory::class), + \Zend\View\HelperPluginManager::class => \DI\factory(\Zend\Expressive\ZendView\HelperPluginManagerFactory::class), + ]); + } + + private function registerMiddlewarePipeline(): void + { + $this->addDefinitions([ + \Zend\Expressive\Helper\ServerUrlMiddleware::class => \DI\factory(\Zend\Expressive\Helper\ServerUrlMiddlewareFactory::class), + \Zend\Expressive\Helper\UrlHelperMiddleware::class => \DI\factory(\Zend\Expressive\Helper\UrlHelperMiddlewareFactory::class), + ]); + } +}