offsetExists($index) examines the cache, not the inner or outer iterator.<?php $cache = new \CachingIterator( new \ArrayIterator(['a', 'b', 'c', 'd']), \CachingIterator::FULL_CACHE); $shortRange = range(0, 1); $fullRange = range(0, 3); foreach ($shortRange as $index) { $cache->next(); } echo PHP_EOL . 'The cache' . PHP_EOL; var_export($cache->getCache()); echo PHP_EOL; foreach ($fullRange as $offset) { print_r("cache offset '$offset' " . ($cache->offsetExists("$offset") == 1 ? 'exists' : "doesn't exist" ) . PHP_EOL); }?>The cachearray ( 0 => 'a', 1 => 'b',)cache offset '0' existscache offset '1' existscache offset '2' doesn't existcache offset '3' doesn't exist