|
SPL-StandardPHPLibrary
|
00001 <?php 00019 class MultipleIterator implements Iterator 00020 { 00022 private $iterators; 00023 00025 private $flags; 00026 00028 const MIT_NEED_ANY = 0; 00029 00031 const MIT_NEED_ALL = 1; 00032 00034 const MIT_KEYS_NUMERIC = 0; 00035 00037 const MIT_KEYS_ASSOC = 2; 00038 00042 public function __construct($flags = self::MIT_NEED_ALL|self::MIT_KEYS_NUMERIC) 00043 { 00044 $this->iterators = new SplObjectStorage(); 00045 $this->flags = $flags; 00046 } 00047 00049 public function getFlags() 00050 { 00051 return $this->flags; 00052 } 00053 00055 public function setFlags($flags) 00056 { 00057 $this->flags = $flags; 00058 } 00059 00066 public function attachIterator(Iterator $iter, $inf = NULL) 00067 { 00068 00069 if (!is_null($inf)) 00070 { 00071 if (!is_int($inf) && !is_string($inf)) 00072 { 00073 throw new IllegalValueException('Inf must be NULL, integer or string'); 00074 } 00075 foreach($this->iterators as $iter) 00076 { 00077 if ($inf == $this->iterators->getInfo()) 00078 { 00079 throw new IllegalValueException('Key duplication error'); 00080 } 00081 } 00082 } 00083 $this->iterators->attach($iter, $inf); 00084 } 00085 00087 public function detachIterator(Iterator $iter) 00088 { 00089 $this->iterators->detach($iter); 00090 } 00091 00095 public function containsIterator(Iterator $iter) 00096 { 00097 return $this->iterator->contains($iter); 00098 } 00099 00101 public function countIterators() 00102 { 00103 return $this->iterators->count(); 00104 } 00105 00107 public function rewind() 00108 { 00109 foreach($this->iterators as $iter) 00110 { 00111 $iter->rewind(); 00112 } 00113 } 00114 00122 public function valid() 00123 { 00124 if (!sizeof($this->iterators)) { 00125 return false; 00126 } 00127 // The following code is an optimized version that executes as few 00128 // valid() calls as necessary and that only checks the flags once. 00129 $expect = $this->flags & self::MIT_NEED_ALL ? true : false; 00130 foreach($this->iterators as $iter) 00131 { 00132 if ($expect != $iter->valid()) 00133 { 00134 return !$expect; 00135 } 00136 } 00137 return $expect; 00138 } 00139 00143 public function next() 00144 { 00145 foreach($this->iterators as $iter) 00146 { 00147 $iter->next(); 00148 } 00149 } 00150 00157 public function current() 00158 { 00159 if (!sizeof($this->iterators)) 00160 { 00161 return false; 00162 } 00163 $retval = array(); 00164 foreach($this->iterators as $iter) 00165 { 00166 if ($it->valid()) 00167 { 00168 if ($this->flags & self::MIT_KEYS_ASSOC) 00169 { 00170 $key = $this->iterators->getInfo(); 00171 if (is_null($key)) 00172 { 00173 throw new IllegalValueException('Sub-Iterator is associated with NULL'); 00174 } 00175 $retval[$key] = $iter->current(); 00176 } 00177 else 00178 { 00179 $retval[] = $iter->current(); 00180 } 00181 } 00182 else if ($this->flags & self::MIT_NEED_ALL) 00183 { 00184 throw new RuntimeException('Called current() with non valid sub iterator'); 00185 } 00186 else 00187 { 00188 $retval[] = NULL; 00189 } 00190 } 00191 return $retval; 00192 } 00193 00199 public function key() 00200 { 00201 if (!sizeof($this->iterators)) 00202 { 00203 return false; 00204 } 00205 $retval = array(); 00206 foreach($this->iterators as $iter) 00207 { 00208 if ($it->valid()) 00209 { 00210 $retval[] = $iter->key(); 00211 } 00212 else if ($this->flags & self::MIT_NEED_ALL) 00213 { 00214 throw new LogicException('Called key() with non valid sub iterator'); 00215 } 00216 else 00217 { 00218 $retval[] = NULL; 00219 } 00220 } 00221 return $retval; 00222 } 00223 }
1.7.5.1