LMLPHP后院

PHP数组式访问接口ArrayAccess技术

maybe yes 发表于 2015-04-23 22:34

ArrayAccess 提供像访问数组一样访问对象的能力的接口。看 Web Artisan Laravel 框架的 Illuminate\Container 就实现了 ArrayAccess 接口,这样就可以像操作数组的方式一样来操作对象。这样的语言预定义接口功能很少人知道,即使不知道也不会影响一个程序员开发设计PHP设计者们不直接实现这样的接口就是让程序员有更强的能力创造新的行为的对象。

实现了 ArrayAccess 的类需要实现四个抽象方法,分别是 offsetExists, offsetGet, offsetSet, offsetUnset 。当使用 isset($obj['index']), $obj['index'], $obj['index'] = $value, unset($obj['index']) 时,会分别触发这些方法。接口摘要如下:


<?php

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

需要注意的是,array_key_exists() 不会触发 ArrayAccess::offsetExists() 方法。来自 PHP 官网手册:It bit me today, so putting it here in the hope it will help others : If you call array_key_exists() on an object of a class that implements ArrayAccess, ArrayAccess::offsetExists() will NOT be called.

另外的一些注意事项 :
ArrayAccess 和数组是不兼容的,他们是不同的类型;
ArrayAccess 的 index 不局限于字符串和整形,它可以是任何类型;
ArrayAccess 对象以数组方式赋值时,不可以使用引用符号,这样会导致一个致命错误,Fatal error : Cannot assign by reference to overloaded object,可以通过使用定义一个方法来实现引用赋值。
ArrayAccess 对象不支持自增自减操作符,这样会导致一个错误,如下代码示例。

Objects implementing ArrayAccess do not support the increment/decrement operators ++ and --, unlike array() and ArrayObject()

<?php

class MyArray implements ArrayAccess
{
    // offsetSet, offsetGet etc implemented
}

$x = new MyArray() ;
$x[0] = 0 ;
$x[0]++ ; //error 'Indirect modification of overloaded element has no effect'

相关文章
2021-04-20 02:02:01 1618855321 0.031196