From 572896685f9b56a8db206eaa3a418750d6cc3de5 Mon Sep 17 00:00:00 2001 From: lubiana Date: Sat, 21 May 2022 00:57:02 +0200 Subject: [PATCH] update implementation of chapter 9 --- implementation/09/composer.json | 4 +- implementation/09/composer.lock | 282 +++++++++++++++++- implementation/09/config/container.php | 26 +- implementation/09/src/Action/Hello.php | 9 +- implementation/09/src/Bootstrap.php | 17 +- implementation/09/src/Service/Time/Clock.php | 6 +- .../09/src/Service/Time/SystemClock.php | 9 +- 7 files changed, 329 insertions(+), 24 deletions(-) diff --git a/implementation/09/composer.json b/implementation/09/composer.json index 74e3551..335b122 100644 --- a/implementation/09/composer.json +++ b/implementation/09/composer.json @@ -16,7 +16,9 @@ "filp/whoops": "^2.14", "laminas/laminas-diactoros": "^2.11", "nikic/fast-route": "^1.3", - "psr/http-server-handler": "^1.0" + "psr/http-server-handler": "^1.0", + "psr/container": "^1.0", + "php-di/php-di": "^6.4" }, "require-dev": { "phpstan/phpstan": "^1.6", diff --git a/implementation/09/composer.lock b/implementation/09/composer.lock index a9f5b96..386eb40 100644 --- a/implementation/09/composer.lock +++ b/implementation/09/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5f281d245eeab688c1904bf024aeff4f", + "content-hash": "0b6833b8fa6869bd212824769648e667", "packages": [ { "name": "filp/whoops", @@ -176,6 +176,65 @@ ], "time": "2022-05-17T10:57:52+00:00" }, + { + "name": "laravel/serializable-closure", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/serializable-closure.git", + "reference": "09f0e9fb61829f628205b7c94906c28740ff9540" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/09f0e9fb61829f628205b7c94906c28740ff9540", + "reference": "09f0e9fb61829f628205b7c94906c28740ff9540", + "shasum": "" + }, + "require": { + "php": "^7.3|^8.0" + }, + "require-dev": { + "pestphp/pest": "^1.18", + "phpstan/phpstan": "^0.12.98", + "symfony/var-dumper": "^5.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Laravel\\SerializableClosure\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + }, + { + "name": "Nuno Maduro", + "email": "nuno@laravel.com" + } + ], + "description": "Laravel Serializable Closure provides an easy and secure way to serialize closures in PHP.", + "keywords": [ + "closure", + "laravel", + "serializable" + ], + "support": { + "issues": "https://github.com/laravel/serializable-closure/issues", + "source": "https://github.com/laravel/serializable-closure" + }, + "time": "2022-05-16T17:09:47+00:00" + }, { "name": "nikic/fast-route", "version": "v1.3.0", @@ -226,6 +285,227 @@ }, "time": "2018-02-13T20:26:39+00:00" }, + { + "name": "php-di/invoker", + "version": "2.3.3", + "source": { + "type": "git", + "url": "https://github.com/PHP-DI/Invoker.git", + "reference": "cd6d9f267d1a3474bdddf1be1da079f01b942786" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-DI/Invoker/zipball/cd6d9f267d1a3474bdddf1be1da079f01b942786", + "reference": "cd6d9f267d1a3474bdddf1be1da079f01b942786", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "psr/container": "^1.0|^2.0" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "mnapoli/hard-mode": "~0.3.0", + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Invoker\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Generic and extensible callable invoker", + "homepage": "https://github.com/PHP-DI/Invoker", + "keywords": [ + "callable", + "dependency", + "dependency-injection", + "injection", + "invoke", + "invoker" + ], + "support": { + "issues": "https://github.com/PHP-DI/Invoker/issues", + "source": "https://github.com/PHP-DI/Invoker/tree/2.3.3" + }, + "funding": [ + { + "url": "https://github.com/mnapoli", + "type": "github" + } + ], + "time": "2021-12-13T09:22:56+00:00" + }, + { + "name": "php-di/php-di", + "version": "6.4.0", + "source": { + "type": "git", + "url": "https://github.com/PHP-DI/PHP-DI.git", + "reference": "ae0f1b3b03d8b29dff81747063cbfd6276246cc4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-DI/PHP-DI/zipball/ae0f1b3b03d8b29dff81747063cbfd6276246cc4", + "reference": "ae0f1b3b03d8b29dff81747063cbfd6276246cc4", + "shasum": "" + }, + "require": { + "laravel/serializable-closure": "^1.0", + "php": ">=7.4.0", + "php-di/invoker": "^2.0", + "php-di/phpdoc-reader": "^2.0.1", + "psr/container": "^1.0" + }, + "provide": { + "psr/container-implementation": "^1.0" + }, + "require-dev": { + "doctrine/annotations": "~1.10", + "friendsofphp/php-cs-fixer": "^2.4", + "mnapoli/phpunit-easymock": "^1.2", + "ocramius/proxy-manager": "^2.11.2", + "phpstan/phpstan": "^0.12", + "phpunit/phpunit": "^9.5" + }, + "suggest": { + "doctrine/annotations": "Install it if you want to use annotations (version ~1.2)", + "ocramius/proxy-manager": "Install it if you want to use lazy injection (version ~2.0)" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "DI\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "The dependency injection container for humans", + "homepage": "https://php-di.org/", + "keywords": [ + "PSR-11", + "container", + "container-interop", + "dependency injection", + "di", + "ioc", + "psr11" + ], + "support": { + "issues": "https://github.com/PHP-DI/PHP-DI/issues", + "source": "https://github.com/PHP-DI/PHP-DI/tree/6.4.0" + }, + "funding": [ + { + "url": "https://github.com/mnapoli", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/php-di/php-di", + "type": "tidelift" + } + ], + "time": "2022-04-09T16:46:38+00:00" + }, + { + "name": "php-di/phpdoc-reader", + "version": "2.2.1", + "source": { + "type": "git", + "url": "https://github.com/PHP-DI/PhpDocReader.git", + "reference": "66daff34cbd2627740ffec9469ffbac9f8c8185c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-DI/PhpDocReader/zipball/66daff34cbd2627740ffec9469ffbac9f8c8185c", + "reference": "66daff34cbd2627740ffec9469ffbac9f8c8185c", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "require-dev": { + "mnapoli/hard-mode": "~0.3.0", + "phpunit/phpunit": "^8.5|^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "PhpDocReader\\": "src/PhpDocReader" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PhpDocReader parses @var and @param values in PHP docblocks (supports namespaced class names with the same resolution rules as PHP)", + "keywords": [ + "phpdoc", + "reflection" + ], + "support": { + "issues": "https://github.com/PHP-DI/PhpDocReader/issues", + "source": "https://github.com/PHP-DI/PhpDocReader/tree/2.2.1" + }, + "time": "2020-10-12T12:39:22+00:00" + }, + { + "name": "psr/container", + "version": "1.1.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", + "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/1.1.2" + }, + "time": "2021-11-05T16:50:12+00:00" + }, { "name": "psr/http-factory", "version": "1.0.1", diff --git a/implementation/09/config/container.php b/implementation/09/config/container.php index 87eb322..ceb20dc 100644 --- a/implementation/09/config/container.php +++ b/implementation/09/config/container.php @@ -1,9 +1,23 @@ fn () => new \Lubian\NoFramework\Action\Hello($response, $clock), - \Lubian\NoFramework\Action\Other::class => fn () => new \Lubian\NoFramework\Action\Other($response), -]; +use function FastRoute\simpleDispatcher; + +$builder = new ContainerBuilder; + +$builder->addDefinitions([ + ServerRequestInterface::class => fn () => ServerRequestFactory::fromGlobals(), + ResponseInterface::class => fn () => new Response, + Dispatcher::class => fn () => simpleDispatcher(require __DIR__ . '/routes.php'), + Clock::class => fn () => new SystemClock, +]); + +return $builder->build(); diff --git a/implementation/09/src/Action/Hello.php b/implementation/09/src/Action/Hello.php index 6b4d24a..ec2e00c 100644 --- a/implementation/09/src/Action/Hello.php +++ b/implementation/09/src/Action/Hello.php @@ -9,8 +9,10 @@ use Psr\Http\Server\RequestHandlerInterface; final class Hello implements RequestHandlerInterface { - public function __construct(private readonly ResponseInterface $response, private readonly Clock $clock) - { + public function __construct( + private readonly ResponseInterface $response, + private readonly Clock $clock + ) { } public function handle(ServerRequestInterface $request): ResponseInterface @@ -18,7 +20,8 @@ final class Hello implements RequestHandlerInterface $name = $request->getAttribute('name', 'Stranger'); $body = $this->response->getBody(); - $time = $this->clock->now()->format('H:i:s'); + $time = $this->clock->now() + ->format('H:i:s'); $body->write('Hello ' . $name . '!
'); $body->write('The Time is: ' . $time); diff --git a/implementation/09/src/Bootstrap.php b/implementation/09/src/Bootstrap.php index 98a3952..023c8c0 100644 --- a/implementation/09/src/Bootstrap.php +++ b/implementation/09/src/Bootstrap.php @@ -4,10 +4,11 @@ namespace Lubian\NoFramework; use FastRoute\Dispatcher; use Laminas\Diactoros\Response; -use Laminas\Diactoros\ServerRequestFactory; use Lubian\NoFramework\Exception\InternalServerError; use Lubian\NoFramework\Exception\MethodNotAllowed; use Lubian\NoFramework\Exception\NotFound; +use Psr\Container\ContainerInterface; +use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\RequestHandlerInterface; use Throwable; use Whoops\Handler\PrettyPageHandler; @@ -16,7 +17,6 @@ use Whoops\Run; use function assert; use function error_log; use function error_reporting; -use function FastRoute\simpleDispatcher; use function getenv; use function header; use function sprintf; @@ -43,12 +43,15 @@ if ($environment === 'dev') { $whoops->register(); -$request = ServerRequestFactory::fromGlobals(); -$response = new Response; +$container = require __DIR__ . '/../config/container.php'; +assert($container instanceof ContainerInterface); +$request = $container->get(ServerRequestInterface::class); +assert($request instanceof ServerRequestInterface); + +$dispatcher = $container->get(Dispatcher::class); +assert($dispatcher instanceof Dispatcher); -$routeDefinitionCallback = require __DIR__ . '/../config/routes.php'; -$dispatcher = simpleDispatcher($routeDefinitionCallback); $routeInfo = $dispatcher->dispatch($request->getMethod(), $request->getUri() ->getPath(),); @@ -56,7 +59,7 @@ try { switch ($routeInfo[0]) { case Dispatcher::FOUND: $className = $routeInfo[1]; - $handler = new $className($response); + $handler = $container->get($className); assert($handler instanceof RequestHandlerInterface); foreach ($routeInfo[2] as $attributeName => $attributeValue) { $request = $request->withAttribute($attributeName, $attributeValue); diff --git a/implementation/09/src/Service/Time/Clock.php b/implementation/09/src/Service/Time/Clock.php index 50897dc..204ccb4 100644 --- a/implementation/09/src/Service/Time/Clock.php +++ b/implementation/09/src/Service/Time/Clock.php @@ -2,7 +2,9 @@ namespace Lubian\NoFramework\Service\Time; +use DateTimeImmutable; + interface Clock { - public function now(): \DateTimeImmutable; -} \ No newline at end of file + public function now(): DateTimeImmutable; +} diff --git a/implementation/09/src/Service/Time/SystemClock.php b/implementation/09/src/Service/Time/SystemClock.php index f0d0d0a..705d81f 100644 --- a/implementation/09/src/Service/Time/SystemClock.php +++ b/implementation/09/src/Service/Time/SystemClock.php @@ -2,11 +2,12 @@ namespace Lubian\NoFramework\Service\Time; +use DateTimeImmutable; + final class SystemClock implements Clock { - public function now(): \DateTimeImmutable + public function now(): DateTimeImmutable { - return new \DateTimeImmutable(); + return new DateTimeImmutable; } - -} \ No newline at end of file +}