cache = new ArrayIterator(); $this->generator = $this->yieldTraversable($traversable); $this->limit = $limit; } /** * Create a new result set from the given query * * @param Query $query * * @return static */ public static function fromQuery(Query $query) { return new static($query->yieldResults(), $query->getLimit()); } /** * Do not cache query result * * ResultSet instance can only be iterated once * * @return $this */ public function disableCache() { $this->isCacheDisabled = true; return $this; } public function hasMore() { return $this->generator->valid(); } public function hasResult() { return $this->generator->valid(); } #[\ReturnTypeWillChange] public function current() { if ($this->position === null) { $this->advance(); } return $this->isCacheDisabled ? $this->generator->current() : $this->cache->current(); } public function next(): void { if (! $this->isCacheDisabled) { $this->cache->next(); } if ($this->isCacheDisabled || ! $this->cache->valid()) { $this->generator->next(); $this->advance(); } else { $this->position += 1; } } public function key(): int { if ($this->position === null) { $this->advance(); } return $this->isCacheDisabled ? $this->generator->key() : $this->cache->key(); } public function valid(): bool { if ($this->limit !== null && $this->position === $this->limit) { return false; } return $this->cache->valid() || $this->generator->valid(); } public function rewind(): void { if (! $this->isCacheDisabled) { $this->cache->rewind(); } if ($this->position === null) { $this->advance(); } else { $this->position = 0; } } protected function advance() { if (! $this->generator->valid()) { return; } if (! $this->isCacheDisabled) { $this->cache[$this->generator->key()] = $this->generator->current(); // Only required on PHP 5.6, 7+ does it automatically $this->cache->seek($this->generator->key()); } if ($this->position === null) { $this->position = 0; } else { $this->position += 1; } } protected function yieldTraversable(Traversable $traversable) { foreach ($traversable as $key => $value) { yield $key => $value; } } }