代码改变世界

PHP中的ArrayAccess用法详解

2021-06-09 17:55  天心PHP  阅读(188)  评论(0编辑  收藏  举报

在Laravel的源码当中,作者多次使用到了PHP SPL中的ArrayAccess接口,那么这个ArrayAccess接口到底有什么作用呢?我会用一个简单的例子跟大家说明。

请看下面的这段代码,Foo类实现了ArrayAccess接口中的四个方法,请仔细看这些方法内部的实现代码。看到了吗?这些代码是干什么用的,回答就是这些代码没有用,随便你怎么写,你想写什么就写什么。接口中这四个方法的内部的实现跟方法名字其实没有任何关系。啊!这。。。实际的作用是取决于你的调用。

复制代码
class Foo implements ArrayAccess
{
    public function offsetExists( $offset ) {
        echo "这里是 offsetExists() 方法 你输入的参数是 {$offset}";
    }

    public function offsetGet( $offset ) {
        echo "这里是 offsetGet() 方法 你输入的参数是 $offset";
    }

    public function offsetSet( $offset, $value ) {
        echo "这里是 offsetSet() 方法 你输入的 {$offset}={$value}";
    }

    public function offsetUnset( $offset ) {
        echo "这里是 offsetUnset() 方法 你输入的参数是 {$offset}";
    }
}
复制代码

好,我们调用一下看看。

我们使用isset这个函数去调用$foo['how'],那么实际上是调用了offsetExists这个方法,也就是说 $foo['xxxx'] 这种结构去调用哪个ArrayAccess的方法是取决于你是如何调用的 $foo['xxxx']。而方法内部的实现代码你想怎么写就怎么写。在这里一旦你使用isset去调用了这种结构,系统就会去调用offsetExists这个方法,在本例中方法里面有什么,仅仅是echo了一句话。为什么 var_dump($t); 会输出false呢?因为在我们实现的这个offsetExists方法里面,没有任何的返回值,没有返回值当然就是null了,也就是false了。

$foo = new Foo();
$t = isset($foo['how']);// 输出: 这里是 offsetExists() 方法 你输入的参数是 how
var_dump($t);// 输出: boolean false

接着看看这种 $foo['xxxx'] 结构还可以怎样被调用,不如我们这次直接使用$foo['xxxx']看看。原来直接使用 $foo['xxxx']  这种结构也可以调用一个方法啊,从输出当中得知调用了offsetGet方法,同样也获取到了参数。

$foo = new Foo();
$foo['what'];// 输出: 这里是 offsetGet() 方法 你输入的参数是 what

继续看还能怎么调用到其他的方法,我们给这个结构赋值看看,果然赋值的操作当然是调用offsetSet方法了,同样的方法内部的实现代码任然还是你想写什么就写什么。

$foo = new Foo();
$foo['when'] = 'today';// 输出: 这里是 offsetSet() 方法 你输入的 when=today

最后一个了,看方法名字也知道是通过unset方法才能被调用了。

$foo = new Foo();
unset($foo['wow']);// 输出: 这里是 offsetUnset() 方法 你输入的参数是 wow

 

总结

好了,总结一下吧:

如果你的类实现了ArrayAccess接口,那么这个类的对象就可以使用$foo['xxx']这种结构了。

$foo['xxx'] 对应调用offsetGet方法。

$foo['xxx'] = 'yyy' 对应调用offsetSet方法。

isset($foo['xxx']) 对应调用offsetExists方法。

unset($foo['xxx']) 对应调用offsetUnset方法。

再次强调,方法的实现代码,你想怎么写就怎么写。(当然代码的功能最好是贴近方法名啦)