导读:昨天我们学习了一下,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;
}
这里有两个知识点需要注意下:
- \InvalidArgumentException
- 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 )
返回异常追踪信息。