Deep dive into Laravel Pagination - PHP IteratorAggregate

Deep dive into Laravel Pagination - PHP IteratorAggregate

Regarding to Laravel pagination doc, when calling the paginate method, you will receive an instance of Illuminate\Pagination\LengthAwarePaginator. When calling the simplePaginate method, you will receive an instance of Illuminate\Pagination\Paginator. These objects provide several methods that describe the result set. In addition to these helpers methods, the paginator instances are iterators and may be looped as an array.

There is a basic example of Laravel pagination in your project

public function index(Request $request)
   {
       $users = User::paginate(15);
       return view('user.index', ['users' => $users]);
   }
<div class="container">
   @foreach ($users as $user)
       {{ $user->name }}
   @endforeach
</div>

Here is what you see in detail of $users variable

Image description

Now let look at inside LengthAwarePaginator class, we can see that it implements several interfaces such as ArrayAccess, Countable, IteratorAggregate, JsonSerializable which are known as predefined interfaces in PHP. This class also extends AbstractPaginator which has getIterator() to return ArrayIterator

In this case, we consider the IteratorAggregate is an interface to create an external Iterator which allows you to traverse your custom class objects using foreach. With the Interface synopsis, IteratorAggregate extends Traversable interface itself is an abstract base interface (with no methods as shown in the interface synopsis) that cannot be instantiated. However, it can be used to check whether a class is traversable using foreach or not.

class Food implements IteratorAggregate
{
   public array $arr;

   public function __construct() {
       $this->arr = ['Milk', 'Cake', 'Coke'];
   }

   public function getIterator() {
       return new ArrayIterator($this->arr);
   }
}

$obj = new Food();

foreach($obj as $key => $value) {
  echo $key ." =>" . $value . "\n";
}

======================================
OUTPUT

0 => 'Milk'
1 => 'Cake'
2 => 'Coke'

IteratorAggregate is an easy way to implement an Iterator. The advantage with IteratorAggregate is the speed, it is much faster than its alternatives. The problem with it it's that... despite the name it's not an iterator but a traversable (so again, no next, key, current, valid, rewind methods).