From e823052340fb906a47ab98fe5b7c000d7b884b66 Mon Sep 17 00:00:00 2001 From: Rougin Gutib Date: Tue, 28 Nov 2023 09:59:58 +0800 Subject: [PATCH] Change details in Container package --- CHANGELOG.md | 1 + src/Container/AurynContainer.php | 47 ++++--------- src/Container/Container.php | 68 +++++++++++-------- src/Container/ContainerException.php | 17 +++++ src/Container/ContainerInterface.php | 2 +- .../Exception/ContainerException.php | 8 +-- src/Container/Exception/NotFoundException.php | 2 +- src/Container/LeagueContainer.php | 13 +--- src/Container/NotFoundException.php | 2 +- src/Container/Parameter.php | 16 ++--- src/Container/ReflectionContainer.php | 48 +++++++------ src/Container/VanillaContainer.php | 2 +- 12 files changed, 110 insertions(+), 116 deletions(-) create mode 100644 src/Container/ContainerException.php diff --git a/CHANGELOG.md b/CHANGELOG.md index a382c951..132f3f76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ All notable changes to `Slytherin` will be documented in this file. ### Added - `preferred` property in integrations +- `ContainerException` in `Container` ### Fixed - Type hinting of all classes using `PHPStan` (up to `level 9`) diff --git a/src/Container/AurynContainer.php b/src/Container/AurynContainer.php index 15733b56..c986f820 100644 --- a/src/Container/AurynContainer.php +++ b/src/Container/AurynContainer.php @@ -32,7 +32,7 @@ class AurynContainer extends Injector implements ContainerInterface /** * @var array */ - protected $instances = array(); + protected $items = array(); /** * Initializes the container instance. @@ -80,17 +80,19 @@ public function add($id, $concrete = null) */ public function get($id) { - $entry = null; - - $this->has($id) && $entry = $this->resolve($id); - - if (! is_null($entry)) return $entry; + if (! $this->has($id)) + { + $message = 'Alias (%s) is not being managed by the container'; - $message = 'Alias (%s) is not being managed by the container'; + throw new Exception\NotFoundException(sprintf($message, $id)); + } - $message = (string) sprintf($message, $id); + if (array_key_exists($id, $this->items)) + { + return $this->items[$id]; + } - throw new Exception\NotFoundException($message); + return $this->injector->make($id); } /** @@ -101,9 +103,7 @@ public function get($id) */ public function has($id) { - $exists = isset($this->has[$id]) ? $this->has[$id] : false; - - if (isset($this->has[$id])) return $exists; + if (array_key_exists($id, $this->has)) return $this->has[$id]; $filter = Injector::I_BINDINGS | Injector::I_DELEGATES; @@ -115,9 +115,7 @@ public function has($id) $definitions = array_filter($definitions); - $exists = ! empty($definitions) ?: class_exists($id); - - return $exists; + return ! empty($definitions) ?: class_exists($id); } /** @@ -129,25 +127,8 @@ public function has($id) */ public function set($id, $concrete) { - $this->instances[$id] = $concrete; + $this->items[$id] = $concrete; return $this; } - - /** - * Resolves the specified identifier to an instance. - * - * @param string $id - * @return mixed - */ - protected function resolve($id) - { - $entry = null; - - isset($this->instances[$id]) && $entry = $this->instances[$id]; - - isset($entry) === false && $entry = $this->injector->make($id); - - return $entry; - } } \ No newline at end of file diff --git a/src/Container/Container.php b/src/Container/Container.php index 2107a348..ae3d854a 100644 --- a/src/Container/Container.php +++ b/src/Container/Container.php @@ -37,8 +37,13 @@ class Container implements ContainerInterface public function __construct(array $instances = array(), PsrContainerInterface $container = null) { $this->instances = $instances; + + if (! $container) + { + $container = new ReflectionContainer; + } - $this->extra = $container ?: new ReflectionContainer; + $this->extra = $container; } /** @@ -77,18 +82,25 @@ public function alias($id, $original) */ public function arguments(\ReflectionFunctionAbstract $reflector, $parameters = array()) { - $arguments = array(); + $items = $reflector->getParameters(); - foreach ($reflector->getParameters() as $key => $parameter) + $result = array(); + + foreach ($items as $key => $item) { - $argument = $this->argument($parameter); + $argument = $this->argument($item); - $name = $parameter->getName(); + $name = (string) $item->getName(); - $arguments[$key] = $argument ?: $parameters[$name]; + if (array_key_exists($name, $parameters)) + { + $result[$key] = $parameters[$name]; + } + + if ($argument) $result[$key] = $argument; } - return $arguments; + return $result; } /** @@ -155,16 +167,16 @@ public function resolve($id, ServerRequestInterface $request = null) return $this->extra->get($id); } - $arguments = array(); + $result = array(); foreach ($constructor->getParameters() as $parameter) { $argument = $this->argument($parameter); - $arguments[] = $this->request($argument, $request); + $result[] = $this->handle($argument, $request); } - return $reflection->newInstanceArgs($arguments); + return $reflection->newInstanceArgs($result); } /** @@ -210,19 +222,15 @@ protected function argument(\ReflectionParameter $parameter) } /** - * Returns the manipulated ServerRequest (from middleware) to an argument. + * Handles the manipulated ServerRequest (from middleware) to an argument. * * @param mixed $argument * @param \Psr\Http\Message\ServerRequestInterface|null $request * @return mixed */ - protected function request($argument, ServerRequestInterface $request = null) + protected function handle($argument, ServerRequestInterface $request = null) { - $instanceof = $argument instanceof ServerRequestInterface; - - $instanceof === true && $argument = $request ?: $argument; - - return $argument; + return $argument instanceof ServerRequestInterface && $request ? $request : $argument; } /** @@ -240,21 +248,21 @@ protected function value($name) $object = $this->get($name); } - if (! $object && $this->extra->has($name)) + if ($object || ! $this->extra->has($name)) { - // If the identifier does not exists from extra, --- - // Try to get again from the parent container - try - { - return $this->extra->get($name); - } - catch (NotFoundExceptionInterface $error) - { - return $this->get($name); - } - // ------------------------------------------------- + return $object; } - return $object; + // If the identifier does not exists from extra, --- + // Try to get again from the parent container + try + { + return $this->extra->get($name); + } + catch (NotFoundExceptionInterface $error) + { + return $this->get($name); + } + // ------------------------------------------------- } } \ No newline at end of file diff --git a/src/Container/ContainerException.php b/src/Container/ContainerException.php new file mode 100644 index 00000000..7c7d361c --- /dev/null +++ b/src/Container/ContainerException.php @@ -0,0 +1,17 @@ + + */ +class ContainerException extends \Exception implements ContainerExceptionInterface +{ +} \ No newline at end of file diff --git a/src/Container/ContainerInterface.php b/src/Container/ContainerInterface.php index 53e96f28..18d2173f 100644 --- a/src/Container/ContainerInterface.php +++ b/src/Container/ContainerInterface.php @@ -22,4 +22,4 @@ interface ContainerInterface extends PsrContainerInterface * @return self */ public function set($id, $concrete); -} +} \ No newline at end of file diff --git a/src/Container/Exception/ContainerException.php b/src/Container/Exception/ContainerException.php index a174b644..72ff79b3 100644 --- a/src/Container/Exception/ContainerException.php +++ b/src/Container/Exception/ContainerException.php @@ -2,17 +2,17 @@ namespace Rougin\Slytherin\Container\Exception; -use Psr\Container\ContainerExceptionInterface; +use Rougin\Slytherin\Container\ContainerException as BaseException; /** * Container Exception * * A specified exception in handling errors in containers. - * NOTE: To be removed in v1.0.0. Use NotFoundException instead. + * NOTE: To be removed in v1.0.0. Use Container\ContainerException instead. * * @package Slytherin * @author Rougin Gutib */ -class ContainerException extends \Exception implements ContainerExceptionInterface +class ContainerException extends BaseException { -} +} \ No newline at end of file diff --git a/src/Container/Exception/NotFoundException.php b/src/Container/Exception/NotFoundException.php index 5470a2e1..cf828d0c 100644 --- a/src/Container/Exception/NotFoundException.php +++ b/src/Container/Exception/NotFoundException.php @@ -15,4 +15,4 @@ */ class NotFoundException extends BaseException { -} +} \ No newline at end of file diff --git a/src/Container/LeagueContainer.php b/src/Container/LeagueContainer.php index cf3d0808..057a529d 100644 --- a/src/Container/LeagueContainer.php +++ b/src/Container/LeagueContainer.php @@ -31,17 +31,6 @@ public function get($id, array $arguments = array()) return parent::get($id, $arguments); } - /** - * Returns true if the container can return an entry for the given identifier. - * - * @param string $id - * @return boolean - */ - public function has($id) - { - return parent::has($id); - } - /** * Sets a new instance to the container. * @@ -56,4 +45,4 @@ public function set($id, $concrete, $share = false) return $this; } -} +} \ No newline at end of file diff --git a/src/Container/NotFoundException.php b/src/Container/NotFoundException.php index 2028fbd2..58f8cd67 100644 --- a/src/Container/NotFoundException.php +++ b/src/Container/NotFoundException.php @@ -14,4 +14,4 @@ */ class NotFoundException extends \InvalidArgumentException implements NotFoundExceptionInterface { -} +} \ No newline at end of file diff --git a/src/Container/Parameter.php b/src/Container/Parameter.php index 0db1d4c5..dd872dea 100644 --- a/src/Container/Parameter.php +++ b/src/Container/Parameter.php @@ -39,22 +39,16 @@ public function getClass() if (! $php8) { - $method = array($this->param, 'getClass'); - - return call_user_func((array) $method); + return call_user_func(array($this->param, 'getClass')); } - $method = array($this->param, 'getType'); - - $type = call_user_func((array) $method); + $type = call_user_func(array($this->param, 'getType')); $builtIn = true; if ($type) { - $method = array($type, 'isBuiltin'); - - $builtIn = call_user_func((array) $method); + $builtIn = call_user_func(array($type, 'isBuiltin')); } if ($builtIn) return null; @@ -62,8 +56,6 @@ public function getClass() /** @var callable */ $class = array($type, 'getName'); - $class = call_user_func($class); - - return new \ReflectionClass($class); + return new \ReflectionClass(call_user_func($class)); } } \ No newline at end of file diff --git a/src/Container/ReflectionContainer.php b/src/Container/ReflectionContainer.php index 253aff83..b1d6458a 100644 --- a/src/Container/ReflectionContainer.php +++ b/src/Container/ReflectionContainer.php @@ -27,11 +27,11 @@ class ReflectionContainer implements PsrContainerInterface */ public function get($id) { - if ($this->has($id) === false) + if (! $this->has($id)) { - $message = sprintf('Class (%s) does not exists', $id); + $message = 'Alias (%s) is not being managed by the container'; - throw new Exception\NotFoundException($message); + throw new Exception\NotFoundException(sprintf($message, $id)); } /** @var class-string $id */ @@ -39,7 +39,7 @@ public function get($id) if ($constructor = $reflection->getConstructor()) { - $arguments = $this->arguments($constructor); + $arguments = $this->resolve($constructor); return $reflection->newInstanceArgs($arguments); } @@ -69,42 +69,48 @@ protected function argument(\ReflectionParameter $parameter, $name) { try { - $argument = $parameter->getDefaultValue(); + return $parameter->getDefaultValue(); } catch (\ReflectionException $exception) { - $argument = $this->get($name); + return $this->get((string) $name); } - - return $argument; } /** * Resolves the specified parameters from a container. * - * @param \ReflectionFunction|\ReflectionMethod $reflector + * @param \ReflectionFunction|\ReflectionMethod $reflection * @param array $parameters * @return array */ - protected function arguments($reflector, $parameters = array()) + protected function resolve($reflection, $parameters = array()) { - $arguments = array(); + $items = $reflection->getParameters(); - foreach ($reflector->getParameters() as $key => $parameter) - { - $param = new Parameter($parameter); + $result = array(); - $class = $param->getClass(); + foreach ($items as $key => $item) + { + $name = (string) $item->getName(); - $name = $class ? $class->getName() : $parameter->getName(); + // Backward compatibility for ReflectionParameter --- + $param = new Parameter($item); - $argument = $this->argument($parameter, $name); + if ($param->getClass()) + { + $name = $param->getClass()->getName(); + } + // -------------------------------------------------- - $exists = array_key_exists($name, $parameters); + $result[$key] = $this->argument($item, $name); - $arguments[$key] = $exists ? $parameters[$name] : $argument; + if (array_key_exists($name, $parameters)) + { + $result[$key] = $parameters[(string) $name]; + } } - return $arguments; + return $result; } -} +} \ No newline at end of file diff --git a/src/Container/VanillaContainer.php b/src/Container/VanillaContainer.php index b24e14e6..f26045a3 100644 --- a/src/Container/VanillaContainer.php +++ b/src/Container/VanillaContainer.php @@ -13,4 +13,4 @@ */ class VanillaContainer extends Container { -} +} \ No newline at end of file