Этот пост представляет собой новую версию предыдущей зависимости контейнера, пытающуюся интегрировать отзывы людей, которые мне ответили, спасибо !!
предыдущий пост
Правильна ли эта версия и соблюдается ли минимум, необходимый для контейнера зависимостей в соответствии со стандартом PSR 11 и php 8? Что касается php 8 и эволюции ReflectionParameter :: getClass () Точно сказать не могу.
укажите, что я новичок, не стесняйтесь приводить примеры для лучшего понимания, для людей, которых интересует эволюция ReflectionParameter:
class Container implements ContainerInterface
{
/**
* @var array
*/
private array $parameters = [];
/**
* @var Definition[]
*/
private array $definitions = [];
/**
* @var array
*/
private array $instances = [];
/**
* @var array
*/
private array $aliases = [];
/**
* Retrieves the requested reflection class and registers it.
*
* @param $id The service identifier.
* @return $this This registered service.
*/
public function register(string $id): self
{
$reflectionClass = new ReflectionClass($id);
if ($reflectionClass->isInterface()) {
$this->register($this->aliases[$id]);
$this->definitions[$id] = &$this->definitions[$this->aliases[$id]];
return $this;
}
$dependencies = [];
if (null !== $reflectionClass->getConstructor()) {
$dependencies = array_map(
fn (ReflectionParameter $parameter) => $this->getDefinition($parameter->getType() && !$parameter->getType()->isBuiltin()
? new ReflectionClass($parameter->getType()->getName()) : null),
array_filter(
$reflectionClass->getConstructor()->getParameters(),
fn (ReflectionParameter $parameter) => $parameter->getType() && !$parameter->getType()->isBuiltin()
? new ReflectionClass($parameter->getType()->getName()) : null
)
);
}
$aliases = array_filter($this->aliases, fn (string $alias) => $id === $alias);
$this->definitions[$id] = new Definition($id, true, $aliases, $dependencies);
var_dump($this);
return $this;
}
/**
* Definition instance to gets for this service.
*
* @param $id The id of Definition instance.
* @return Definition Returns the definition value.
*/
public function getDefinition($id): Definition
{
if (!isset($this->definitions[$id])) {
$this->register($id);
}
return $this->definitions[$id];
}
/**
* Adds an parameter to pass to the service constructor method.
*
* @param $id The parameter name.
* @param $value The parameter value.
* @return $this Returns this parameter.
*/
public function addParameter($id, $value): self
{
$this->parameters[$id] = $value;
return $this;
}
/**
* Gets an parameter to pass to the service constructor method.
*
* @param $id The parameter name.
* @return array|bool|float|int|string|null Returns the parameter value.
* @throws NotFoundException When the parameter does not exist.
*/
public function getParameter($id)
{
if (!isset($this->parameters[$id])) {
throw new NotFoundException();
}
return $this->parameters[$id];
}
/**
* Gets a service.
*
* @param string $id The service identifier.
* @return mixed|object Returns the associated service.
* @throws NotFoundException When the service does not exist.
*/
public function get($id)
{
if (!$this->has($id)) {
if (!class_exists($id) && !interface_exists($id)) {
throw new NotFoundException();
}
$instance = $this->getDefinition($id)->make($this);
if (!$this->getDefinition($id)->isShared()) {
return $instance;
}
$this->instances[$id] = $instance;
}
return $this->instances[$id];
}
/**
* Determine if the given service is defined.
*
* @param string $id The service identifier.
* @return bool Returns true if the service is defined, false otherwise.
*/
public function has($id): bool
{
return isset($this->instances[$id]);
}
/**
* Adds a specific alias for this service.
*
* @param string $id The service identifier.
* @param string $class The associated class name.
* @return $this Returns this alias.
*/
public function addAlias(string $id, string $class): self
{
$this->aliases[$id] = $class;
return $this;
}
}
class Definition
{
/**
* @var string
*/
private string $id;
/**
* @var bool
*/
private bool $shared = true;
/**
* @var array
*/
private array $aliases = [];
/**
* @var Definition[]
*/
private array $dependencies = [];
/**
* @var ReflectionClass
*/
private ReflectionClass $class;
/**
* Definition constructor.
*
* @param string $id The service identifier.
* @param bool $shared the shared service.
* @param array $aliases this alias
* @param array $dependencies
*/
public function __construct(string $id, bool $shared = true, array $aliases = [], array $dependencies = [])
{
$this->id = $id;
$this->shared = $shared;
$this->aliases = $aliases;
$this->dependencies = $dependencies;
$this->class = new ReflectionClass($id);
}
/**
* Sets if the service must be shared or not.
*
* @param bool $shared True if the service is shared. False else.
* @return self Returns the shared service.
*/
public function setShared(bool $shared): self
{
$this->shared = $shared;
return $this;
}
/**
* Whether this service is shared.
*
* @return bool Returns true if the container is shared. False else.
*/
public function isShared(): bool
{
return $this->shared;
}
/**
* Creates a service.
*
* @param ContainerInterface $container Interface ContainerInterface allows to use it's methods
* @return object Returns a new instance for the current service.
*/
public function make(ContainerInterface $container): object
{
$constructor = $this->class->getConstructor();
if (null === $constructor) {
return $this->class->newInstance();
}
$parameters = $constructor->getParameters();
return $this->class->newInstanceArgs(
array_map(function (ReflectionParameter $param) use ($container) {
if ($param->getType() && !$param->getType()->isBuiltin()
? new ReflectionClass($param->getType()->getName()) : null === null) {
return $container->getParameter($param->getName());
}
return $container->get($param->getType() && !$param->getType()->isBuiltin()
? new ReflectionClass($param->getType()->getName()) : null);
}, $parameters)
);
}
}