The ArrayAccess interface

(PHP 5 >= 5.0.0)

Introducere

Interface to provide accessing objects as arrays.

Descrierea succintă a interfeței

ArrayAccess {
/* Metode */
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);
?>

Exemplul de mai sus va afișa ceva similar cu:

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
        )

)

Cuprins

add a note add a note

User Contributed Notes 7 notes

up
16
Yousef Ismaeil Cliprz
11 months ago
<?php

/**
* ArrayAndObjectAccess
* Yes you can access class as array and the same time as object
*
* @author Yousef Ismaeil <cliprz@gmail.com>
*/

class ArrayAndObjectAccess implements ArrayAccess {

   
/**
     * Data
     *
     * @var array
     * @access private
     */
   
private $data = [];

   
/**
     * Get a data by key
     *
     * @param string The key data to retrieve
     * @access public
     */
   
public function &__get ($key) {
        return
$this->data[$key];
    }

   
/**
     * Assigns a value to the specified data
     *
     * @param string The data key to assign the value to
     * @param mixed  The value to set
     * @access public
     */
   
public function __set($key,$value) {
       
$this->data[$key] = $value;
    }

   
/**
     * Whether or not an data exists by key
     *
     * @param string An data key to check for
     * @access public
     * @return boolean
     * @abstracting ArrayAccess
     */
   
public function __isset ($key) {
        return isset(
$this->data[$key]);
    }

   
/**
     * Unsets an data by key
     *
     * @param string The key to unset
     * @access public
     */
   
public function __unset($key) {
        unset(
$this->data[$key]);
    }

   
/**
     * Assigns a value to the specified offset
     *
     * @param string The offset to assign the value to
     * @param mixed  The value to set
     * @access public
     * @abstracting ArrayAccess
     */
   
public function offsetSet($offset,$value) {
        if (
is_null($offset)) {
           
$this->data[] = $value;
        } else {
           
$this->data[$offset] = $value;
        }
    }

   
/**
     * Whether or not an offset exists
     *
     * @param string An offset to check for
     * @access public
     * @return boolean
     * @abstracting ArrayAccess
     */
   
public function offsetExists($offset) {
        return isset(
$this->data[$offset]);
    }

   
/**
     * Unsets an offset
     *
     * @param string The offset to unset
     * @access public
     * @abstracting ArrayAccess
     */
   
public function offsetUnset($offset) {
        if (
$this->offsetExists($offset)) {
            unset(
$this->data[$offset]);
        }
    }

   
/**
     * Returns the value at specified offset
     *
     * @param string The offset to retrieve
     * @access public
     * @return mixed
     * @abstracting ArrayAccess
     */
   
public function offsetGet($offset) {
        return
$this->offsetExists($offset) ? $this->data[$offset] : null;
    }

}

?>

Usage

<?php
$foo
= new ArrayAndObjectAccess();
// Set data as array and object
$foo->fname = 'Yousef';
$foo->lname = 'Ismaeil';
// Call as object
echo 'fname as object '.$foo->fname."\n";
// Call as array
echo 'lname as array '.$foo['lname']."\n";
// Reset as array
$foo['fname'] = 'Cliprz';
echo
$foo['fname']."\n";

/** Outputs
fname as object Yousef
lname as array Ismaeil
Cliprz
*/

?>
up
17
Per
3 years ago
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.
up
11
max at flashdroid dot com
4 years ago
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
up
5
jojor at gmx dot net
1 year ago
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!
?>
up
3
Hayley Watson
1 year ago
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.
up
2
ivan dot dossev at gmail dot com
1 year ago
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"

?>
up
1
php at lanar dot com dot au
9 months ago
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'
$x[0] += 1 ; // this works OK.

?>
To Top