预定义接口
在线手册:中文  英文

ArrayAccess(数组式访问)接口

(No version information available, might only be in SVN)

简介

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

接口摘要

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

Example #1 Basic usage

<?php
class obj implements arrayaccess {
    private 
$container = array();
    public function 
__construct() {
        
$this->container = array(
            
"one"   => 1,
            
"two"   => 2,
            
"three" => 3,
        );
    }
    public function 
offsetSet($offset$value) {
        if (
is_null($offset)) {
            
$this->container[] = $value;
        } else {
            
$this->container[$offset] = $value;
        }
    }
    public function 
offsetExists($offset) {
        return isset(
$this->container[$offset]);
    }
    public function 
offsetUnset($offset) {
        unset(
$this->container[$offset]);
    }
    public function 
offsetGet($offset) {
        return isset(
$this->container[$offset]) ? $this->container[$offset] : null;
    }
}

$obj = new obj;

var_dump(isset($obj["two"]));
var_dump($obj["two"]);
unset(
$obj["two"]);
var_dump(isset($obj["two"]));
$obj["two"] = "A value";
var_dump($obj["two"]);
$obj[] = 'Append 1';
$obj[] = 'Append 2';
$obj[] = 'Append 3';
print_r($obj);
?>

以上例程的输出类似于:

bool(true)
int(2)
bool(false)
string(7) "A value"
obj Object
(
    [container:obj:private] => Array
        (
            [one] => 1
            [three] => 3
            [two] => A value
            [0] => Append 1
            [1] => Append 2
            [2] => Append 3
        )

)

Table of Contents


预定义接口
在线手册:中文  英文

用户评论:

ivan dot dossev at gmail dot com (2013-04-20 07:09:06)

Sadly you cannot assign by reference with the ArrayAccess (at least in PHP 5.3.23)
It's too bad there is no syntax for optionally passing variables by reference to functions (a feature in retro PHP).
That option would have let ArrayAccess fully mimic the functionality of normal array assignments:

<?php
$var 
'hello';
$arr = array();
$arr[0] = $var;
$arr[1] = &$var;
$var 'world';
var_dump($arr[0], $arr[1]);

// string(5) "hello"
// string(5) "world"
?>

Declaring "function offsetSet($offset, &$value)" will cause a fatal error.
So to assign by ref you can use an ugly function call, for example:

<?php
class obj implements ArrayAccess {

    
// ... ArrayAccess example code ...
    
    
public function &offsetSetRef($offset, &$value) {
        if (
is_null($offset)) {
            
$this->container[] = &$value;
        } else {
            
$this->container[$offset] = &$value;
        }
        return 
$value// should return in case called within an assignment chain
    
}
}

$var 'hello';
$obj = new obj();
$obj[0] = $var;
//$obj[1] = &$var; // Fatal error: Cannot assign by reference to overloaded object
$obj->offsetSetRef(1$var); // the work around
$var 'world';
var_dump($obj[0], $obj[1]);

// string(5) "hello"
// string(5) "world"

?>

Hayley Watson (2013-03-31 00:25:39)

The indexes used in an ArrayAccess object are not limited to strings and integers as they are for arrays: you can use any type for the index as long as you write your implementation to handle them. This fact is exploited by the SplObjectStorage class.

jojor at gmx dot net (2012-12-12 13:08:10)

Conclusion: Type hints \ArrayAccess and array are not compatible.

<?php

     
class MyArrayAccess implements \ArrayAccess
     
{
         public function 
offsetExists($offset)
         {

         }

         public function 
offsetSet($offset$value)
         {

         }

         public function 
offsetGet($offset)
         {

         }

         public function 
offsetUnset($offset)
         {

         }
     }


     function 
test(array $arr)
     {
     }

     function 
test2(\ArrayAccess $arr)
     {

     }


     
$arrObj = new MyArrayAccess();
     
test([]); //result: works!
     
test($arrObj); //result: does NOT work
     
test2([]); //result: does NOT work
     
test2($arrObj); // result: works!
?>

Per (2011-05-20 02:16:33)

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() wil NOT be called.

max at flashdroid dot com (2010-04-05 18:49:40)

Objects implementing ArrayAccess may return objects by references in PHP 5.3.0.
You can implement your ArrayAccess object like this:
class Reflectable implements ArrayAccess {
public function set($name, $value) {
$this->{$name} = $value;
}
public function &get($name) {
return $this->{$name};
}
public function offsetGet($offset) {
return $this->get($offset);
}
public function offsetSet($offset, $value) {
$this->set($offset, $value);
}
...
}
This base class allows you to get / set your object properties using the [] operator just like in Javascript:
class Boo extends Reflectable {
public $name;
}
$obj = new Boo();
$obj['name'] = "boo";
echo $obj['name']; // prints boo

易百教程