Slim 框架学习,第七天 _Container(四)

导读:昨天我们学习了一下,container 的 registerDefaultServices方法。今天学习剩下的内容。

先看一下 get 函数

vendor/pimple/pimple/src/Pimple/Container.php

public function get($id)
    {
        if (!$this->offsetExists($id)) {
            throw new ContainerValueNotFoundException(sprintf('Identifier "%s" is not defined.', $id));
        }
        try {
            return $this->offsetGet($id);
        } catch (\InvalidArgumentException $exception) {
            if ($this->exceptionThrownByContainer($exception)) {
                throw new SlimContainerException(
                    sprintf('Container error while retrieving "%s"', $id),
                    null,
                    $exception
                );
            } else {
                throw $exception;
            }
        }
    }

注意下这里的$this->offsetExists() 方法
该方法继承自父类 Container 中的 offsetExists 方法,代码如下:

vendor/pimple/pimple/src/Pimple/Container.php
 public function offsetExists($id)
 {
    return isset($this->keys[$id]);
 }

而这里的offsetExists() 方法,却是实现了\ArrayAccess而来的

下面我们一起揭开 \ArrayAccess 的神秘面纱

提供像访问数组一样访问对象的能力的接口。

 ArrayAccess {
/* 方法 */
//检查一个偏移位置是否存在
abstract public boolean offsetExists ( mixed $offset )
//获取一个偏移位置的值
abstract public mixed offsetGet ( mixed $offset )
//设置一个偏移位置的值
abstract public void offsetSet ( mixed $offset , mixed $value )
//复位一个偏移位置的值
abstract public void offsetUnset ( mixed $offset )
} 

这里就不举例子了,总之,就是可以把对象可以当做像数组一样来访问


回到我们 vendor/pimple/pimple/src/Pimple/Container.php 的get方法中。

if (!$this->offsetExists($id)) {
            throw new ContainerValueNotFoundException(sprintf('Identifier "%s" is not defined.', $id));
        }

该方法就是检查一下,容器中,是否存在该对象。接下来,再看剩余的。

try {
            return $this->offsetGet($id); //返回该对象
        } catch (\InvalidArgumentException $exception) {
            if ($this->exceptionThrownByContainer($exception)) {
                throw new SlimContainerException(
                    sprintf('Container error while retrieving "%s"', $id),
                    null,
                    $exception
                );
            } else {
                throw $exception;
            }

这里有两个知识点需要注意下:

  1. \InvalidArgumentException
  2. this>exceptionThrownByContainer( exception)

先看下 \InvalidArgumentException,异常类

Exception thrown if an argument is not of the expected type. (如果参数不是我们想要类型,就抛出异常)

/* 继承的属性 */
protected string $message ;
protected int $code ;
protected string $file ;
protected int $line ;

/* 继承的方法 */
final public string Exception::getMessage ( void )
final public Throwable Exception::getPrevious ( void )
final public int Exception::getCode ( void )
final public string Exception::getFile ( void )
final public int Exception::getLine ( void )
final public array Exception::getTrace ( void )
final public string Exception::getTraceAsString ( void )
public string Exception::__toString ( void )
final private void Exception::__clone ( void )

例如:
function tripleInteger($int)
{
  if(!is_int($int))
    throw new InvalidArgumentException('tripleInteger function only accepts integers. Input was: '.$int);
  return $int * 3;
}

在看一下,exceptionThrownByContainer 方法

private function exceptionThrownByContainer(\InvalidArgumentException $exception)
    {
    //这里的getTrace,就是InvalidArgumentException中的一个方法。
        $trace = $exception->getTrace()[0]; 

    //这句没有看懂,明天继续分享
        return $trace['class'] === PimpleContainer::class && $trace['function'] === 'offsetGet';
    }

getTrace方法说明

Exception::getTrace

(PHP 5 >= 5.1.0, PHP 7)

Exception::getTrace — 获取异常追踪信息
说明
final public array Exception::getTrace ( void )
返回异常追踪信息。

你可能感兴趣的:(Slim)