Read Only Array

Put this together this morning as a foundation for a couple of other classes that I want to be very strict about how their data gets changed. On it’s own it’s an array that can’t be changed after instantiation. How useful could that be?

(Other then a short demonstration of a class that implements two interfaces).


<?php
namespace Gazelle;

class ReadOnlyArray implements \\Iterator, \\ArrayAccess {
	protected $index = 0;
	
    protected $storage = array();  

    public function __construct(array $array ) {
        $this->storage = $array;
        reset($this->storage);
        $this->index = key($this->storage);
    }

    public function rewind() {
        reset($this->storage);
    }

    public function current() {
        return $this->storage[ $this->index ];
    }

    public function key() {
        return $this->index;
    }

    public function next() {
 		next($this->storage);
 		$this->index = key($this->storage);
    }

    public function valid() {
        return isset($this->storage[$this->index]);
    }
    
	public function offsetSet($offset, $value) {
        throw new FatalException('You cannot write values to a Read Only Array after it is created.');
    }
    
    public function offsetExists($offset) {
        return isset( $this->storage[$offset] );
    }
    
    public function offsetUnset($offset) {
        throw new FatalException('You cannot delete values from a Read Only Array after it is created.');
    }
    
    public function offsetGet($offset) {
        if ( isset($this->storage[$offset] )) {
        	return $this->storage[$offset];
        } else {
        	throw new Exception("$offset does not exist");
        }
    }
}

Can I ask, what problems did you experience after using a static store class?

Since the number of items is fixed at instantiation, perhaps extend the SplFixedArray or least the ArrayIterator.

Out of interest, what child-classes do you plan for this class?

[list=1][]To prevent changing the state of the array you have to override more elements than this object has to implement, but more importantly…
[
]The storage of ArrayObject is private. I want the children I plan to write to have the ability to change the storage while the ability to modify the storage from the outside remains denied, so I need storage to be protected.
[/list]

The main Registry object. I’m following some of the Registry pattern but not all of it - following it exactly adds a layer of complexity for no benefit over using globals or a static core class (which is what I used to do).

I thought the same thing, but SplFixedArray only allows numeric indices - which may, or may not, suit the implementation.

Why not just extend ArrayObject and override the offsetSet method etc…?


<?php
class ReadOnlyArrayObject extends ArrayObject
{
  public function offsetSet($key, $value){
    #
  }
}
?>

Would it not be easier to extend ArrayObject, creating the relevant overrides?

There’s a brief overview here Cups, the comments are worth a read too.