Slim研读笔记五之依赖注入容器(补)

来源:互联网 发布:基站定位软件 编辑:程序博客网 时间:2024/06/04 17:40

上节,我们研读了Pimple容器的具体实现,这节我们来查看Slim默认容器的实现细节。简单浏览代码我们可知,Slim默认容器其实就是对Pimple容器进行的一层封装。前面我们已知Slim\Container完成了集成默认配置项,注册默认服务。现在,让我们接着看剩下的代码。 

    /**     * 通过标识符查找容器的条目并将其返回     * Finds an entry of the container by its identifier and returns it.     *     * @param string $id Identifier of the entry to look for.     *     * @throws ContainerValueNotFoundException  No entry was found for this identifier.     * @throws ContainerException               Error while retrieving the entry.     *     * @return mixed Entry.     */    public function get($id)    {        // 检查参数或对象是否存在        if (!$this->offsetExists($id)) {            throw new ContainerValueNotFoundException(sprintf('Identifier "%s" is not defined.', $id));        }        try {            // 根据$id返回一个参数或对象            return $this->offsetGet($id);        } catch (\InvalidArgumentException $exception) {            // 是否该类offsetGet()出现异常。            if ($this->exceptionThrownByContainer($exception)) {                throw new SlimContainerException(                    sprintf('Container error while retrieving "%s"', $id),                    null,                    $exception                );            } else {                throw $exception;            }        }    }

为了研读进度,我们暂时不会详细讲解异常,后面我们会专门准备一个章节来研读异常类。但大致对异常有个了解还是必须的。

PHP标准库提供了内置了异常类。
异常
  • BadFunctionCallException —错误函数调用异常
  • BadMethodCallException —错误方法调用异常
  • DomainException —作用域异常
  • InvalidArgumentException —非法参数异常
  • LengthException —长度异常
  • LogicException —逻辑异常
  • OutOfBoundsException —违背安全原则异常
  • OutOfRangeException —越界索引异常
  • OverflowException —上溢异常
  • RangeException —范围异常
  • RuntimeException —运行时异常
  • UnderflowException —下溢异常
  • UnexpectedValueException —意外数值异常
让我们了解容器是如何使用异常类的吧
    private function exceptionThrownByContainer(\InvalidArgumentException $exception)    {        // 跟踪异常(包括文件地址、报错类、函数信息等)        $trace = $exception->getTrace()[0];        return $trace['class'] === PimpleContainer::class && $trace['function'] === 'offsetGet';    }
$exception异常对象的getTrace()方法返回了一个数组,数组项中包括报错类,报错文件地址等信息。这里取第一条,然后返回是否该类的offsetGet方法出现异常。
为何要这样写呢?
其实不难理解,当程序出错时,我们一般要想确定异常报错位置,都会自定义一个异常类。但这里使用了SPL的标准异常类,报错信息中也可能存在多处有\InvalidArgumentException异常,那要如何确定当前方法就是出错位置呢?这里采用自定义判断函数根据跟踪信息来确定报错位置的方式。

OK,让我们一起浏览剩下的代码吧。
   /**     * 如果容器可以返回给定标识符的条目,则返回true。     * Returns true if the container can return an entry for the given identifier.     * Returns false otherwise.     *     * @param string $id Identifier of the entry to look for.     *     * @return boolean     */    public function has($id)    {        return $this->offsetExists($id);    }    /********************************************************************************     * Magic methods for convenience     *******************************************************************************/    // 魔术方法,读取不可访问的属性时__get会使用,然后调用get方法    public function __get($name)    {        return $this->get($name);    }    // 魔术方法,当对不可访问属性调用isset()或empty()时,__isset()会被调用    public function __isset($name)    {        return $this->has($name);    }

经过一段时间的努力,相信大家对容器已经有个清晰的了解啦。虽然路途艰险,但我们终究克服了困难,默默成长,取得了前进的一大步。柚子也相信每个坚持到这里的人都是执着的,值得夸赞的!哈哈!