traitを使って何か作ってみようと思い立ち、読み取り専用の配列を実装してみました。配列として扱いたい(例えばforeachで回したいとか)けど外側からの変更は受け付けたくないというシチュエーションで使えます。
<?php
trait ReadOnlyArray
{
private $items = [];
public function offsetGet($key)
{
if (!array_key_exists($key, $this->items)) {
throw new OutOfRangeException();
}
return $this->items[$key];
}
public function offsetSet($key, $value)
{
throw new BadMethodCallException();
}
public function offsetExists($key)
{
return isset($this->items[$key]);
}
public function offsetUnset($key)
{
throw new BadMethodCallException();
}
public function getIterator()
{
return new ArrayIterator($this->items);
}
public function count()
{
return count($this->items);
}
}
使い方は以下の通り。
<?php
class ExampleArray implements ArrayAccess, IteratorAggregate, Countable
{
use ReadOnlyArray;
public function __construct()
{
$this->items["foo"] = "bar";
}
}
$example = new ExampleArray();
$example["foo"]; // => "bar"
$example["foo"] = "buu"; // => BadMethodCallException
$example->count(); // => 1