Laravel seeding using a yield generator

I was needing to improve the performance of a pivot table seeder recently and decided to use a generator to do it. Interestingly, one of the easiest to implement iterators is the yield syntax introduced in PHP 5.5. It allows for good abstraction between the data that is to be iterated and the source of said data. That can lead to significant performance increases as well since it might, depending on the use case, reduce database calls or the amount of data being stored in memory among other things.

Basically what the yield syntax does is it returns an instance of the Generator class for that sequence in the loop.
When next() is called on the Generator class (which yield is) PHP then resumes with the state from when the yield statement was called. It continues on until there is nothing left to yield.

could be:

protected function userIterator()
{
    $maxCount = \App\User::count();
    $take = 100;

    for ($i = $maxCount; $i > 0; $i = ($i - $take)) {
        $commentIds = \App\User::where('id', '>', $this->lastId)->take($take)->lists('id')->toArray();
        $this->lastId = last($userIds);

        foreach ($userIds as $userId) {
            yield $userId;
        }
    }
}

The consuming function might look like so:

/**
 * Run the database seeds.
 *
 * @return void
 */
public function run()
{
    foreach ($this->userIterator() as $userId) {
        $this->createUserPost($userId, $this->getRandomPostId());
    }
}
Written on October 27, 2015