зависимость от контейнера и обновление psr 11

Этот пост представляет собой новую версию предыдущей зависимости контейнера, пытающуюся интегрировать отзывы людей, которые мне ответили, спасибо !!

предыдущий пост

Правильна ли эта версия и соблюдается ли минимум, необходимый для контейнера зависимостей в соответствии со стандартом PSR 11 и php 8? Что касается php 8 и эволюции ReflectionParameter :: getClass () Точно сказать не могу.

укажите, что я новичок, не стесняйтесь приводить примеры для лучшего понимания, для людей, которых интересует эволюция ReflectionParameter:

ReflectionParameter с php 8

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)
        );
    }
}

0

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *