■ArrayAccess
以下のインターフェイスを実装することにより、配列のようにオブジェクトへアクセスができる。但し、ビルトインインターフェイスであり、以下のコードは記述する必要はない。
<?php interface ArrayAccess { function offsetSet($offset, $value); function offsetGet($offset); function offsetUnset($offset); function offsetExists($offset); } ?>
- offfsetSet
- 配列に値をセットする
- offsetGet
- 配列から値を得る
- offsetUnset
- 配列から値を削除する
- offsetExists
- 配列に要素が存在するか判定する
実例
<?php class MyArray implements ArrayAccess { protected $array(); public function offsetSet($offset, $value){ if(!is_int($offset)){ throw new Exception(); } $this->array[$offset] = $value; } public function offsetGet($offset){ return $this->array[$offset]; } public function offsetUnset($offset){ unset($this->array[$offset]); } public function offsetExists($offset){ return array_key_exists($this->array, $offset); } } $obj = new MyArray(); $obj[1] = 2; $obj['a'] = 1;//throws exception ?>
■Iterator
<?php interface Iterator { function current(); function next(); function rewind(); function key(); function valid(); } ?>
実例
<?php class MyData implements Iterator { private $myData = array( "Mike", "Jack", "Emily", "Naomi" ); private $current = 0; public function current(){ return $this->myData[$this->current]; } public function next(){ $this->current++; } public function rewind(){ $this->current = 0; } public function key(){ return $this->current; } public function valid(){ return isset($this->myData[$this->current]); } } $data = new MyData(); foreach($data as $key => $value){ print("{$key} : {$value}"); } ?>
■SeekableIterator
<?php interface SeekableIterator { function current(); function next(); function rewind(); function key(); function valid(); function seek($index); } ?>
■Recursive Iteration
<?php RecursiveIteratorIterator implements OuterIterator, Traversable, Iterator { public function current(void); public function getDepth(void); public function getSubIterator(void); public function key(void); public function next(void); public function rewind(void); public function valid(void); } ?>
実例
<?php class Company_Iterator extends RecursiveIteratorIterator { public function beginChildren(){ if($this->getDepth() >= 3){ print(str_repeat("t", $this->getDepth() - 1)); print('<ul>'); } } public function endChildren(){ if($this->getDepth() >= 3){ print(str_repeat("t", $this->getDepth() - 1)); print('</ul>'); } } } class RecursiveArrayObject extends ArrayObject { function getIterator(){ return new RecursiveArrayIterator($this); } } $company = array( array("Acme Anvil Co."), array( array( "Human Resources", array( 'Nick', 'Jack', 'Mike' ) ), array( "Accounting", array( 'John', 'Emily', 'Naomi' ) ) ) ); $it = new Company_Iterator(new RecursiveArrayObject($company)); foreach($it as $item){ print(str_replace("t", $it->getDepth())); switch($it->getDepth()){ case 1: print("<h1>Company: {$item}</h1>" . PHP_EOL); break; case 2: print("<h2>Department: {$item}</h2>" . PHP_EOL); break; default: print("<li>{$item}</li>" . PHP_EOL); } } /* <h1>Company: Acme Anvil Co.</h1> <h2>Department: Human Resources</h2> <ul> <li>Nick</li> <li>Jack</li> <li>Mike</li> </ul> <h2>Department: Accounting</h2> <ul> <li>John</li> <li>Emily</li> <li>Naomi</li> </ul> */ ?>
■Recursive Iteration
<?php class NumberFilter extends FilterIterator { const FILTER_EVEN = 1; const FILTER_ODD = 2; private $_type; public function __construct($iterator, $odd_or_even = self::FILTER_EVEN){ $this->_type = $odd_or_even; parent::__construct($iterator); } public function accept(){ if($this->_type === self::FILTER_EVEN){ return ($this->current() % 2 == 0); } else{ return ($this->current() % 2 == 1); } } } $numbers = new ArrayObject(range(0, 10)); $number_it = new ArrayIterator($numbers); $it = new NumberFilter($numbers_it, NumberFilter::FILTER_ODD) foreach($it as $number){ print("{$number}" . PHP_EOL); } ?>