Laravel Lazy Collection

Lazy Collection is a class that supplies generators for the items of array. If you are experienced with Laravel 5.x version then you can find the Collection class which is used to wrap array items. So basically in Laravel 6, in addition to, we have another collection that is called Lazy Collection class along with the Normal Collection Class.

Table of Content

  1. Usage of Lazy Collection Class
  2. Retrieving Records using Cursor Method
  3. How to Filter Records using Lazy Collection
  4. How to read log file using Lazy Collection Class:
  5. Lazy Collection Class Methods
  6. Conclusion
Collection class path -
\vendor\laravel\framework\src\Illuminate\Support\Collection.php
 
Lazy collection class - 
\vendor\laravel\framework\src\Illuminate\Support\LazyCollection.php

Usage of Lazy Collection Class

Lazy collection class is mainly designed to keep memory usage low by the Laravel applications. It is using the power of PHP Generators and allows us to work with large databases while using low memory usage.

Let’s assume that your application database table has a lot of data and you want to retrieve those records for your website requirement OR exporting to excel OR any file.

Imagine that your application is using all() method of Laravel Eloquent then you may face out of memory error and it is happening because we are retrieving all records in one go and it will store into memory so memory usage will be high at that time. If you are doing so then your application will be down for some time.

Laravel 6 comes up with some extremely strong features which allow website users to run smoothly by using low memory.

Retrieving Records using Cursor Method

Laravel Lazy collection cursor method that allows us to retrieve no of records from the given models and then it will return a Lazy Collection object. If you look at the below example then you can find that we are effortlessly generating all the models from the Lazy collection object.

$students = \App\student::cursor();
 
    foreach($students as $key => $value) {
        echo $value->name;
        echo "<br>";
    }

In the above example, SQL query is only going to be executed when each loop will start executing. Below code is reference to the cursor method definition in which yield is used for generators (and will return a Lazy collection object which is iterable using loops).

Please find the cursor method definition in the code below.

public function cursor()
{
    if (is_null($this->columns)) {
        $this->columns = ['*'];
    }
 
    return new LazyCollection(function () {
        yield from $this->connection->cursor(
            $this->toSql(), $this->getBindings(), ! $this->useWritePdo
        );
    });
}

How to Filter Records using Lazy Collection:

Lazy collection Cursor method provides facility to filter records and this one of the many advantages comes along with Laravel Framework . For example, if you want some specific records from the thousands of the rows then you can filter records by using the filter method of the cursor.

Here you can find example of filtering records using Lazy collection class:

$students = \App\student::cursor()->filter(function ($students) {
	return $students->id > 5000;
});
 
foreach ($students as $key => $value) {
	echo $key . "--" . $value->name;
}

In the above example, you can see that We have filter records from 5000 so that means We will get rows after 5000 rows.

How to read log file using Lazy Collection Class:

If you want to read any file OR let’s say a log file with the help of Lazy collection class then you can refer below code. Please note that we are reading log files with minimum usage of system memory.

Let’s take an example of 60,000 lines of log file. First we will need to initialize a lazy collection class to use make methods of that class.

use Illuminate\Support\LazyCollection;
 
$filelogs = LazyCollection::make(function () {
		$filehandle = fopen('./logfile.txt', 'r');
			while (($fileline = fgets($filehandle)) !== false) {
				yield $fileline;
		      }
	  });
foreach ($filelogs as $fileline) {
			echo $fileline . '<br>';
}

If you look at the above example then you can see we have called a lazy collection class to read a log file to read each line and yield it to print that line. Our goal to use a lazy collection class is to read big log file without application down. If we use array instead of yield then the application will go down while reading a large log file.

Lazy Collection Class Methods

Lazy collection class can access all the methods of collection class and additionally lazy collection class has tapEach() method. It is a similar method from Collection class but with a useful improvement.

In the default collection class, if you are using a callback function then it will call each element from the collection object immediately but tapEach() method will call the element when we are trying to ask the callback function to pull that element from the given list so normally it operates element one by one.

use Illuminate\Support\LazyCollection;
Route::get('/', function () {
    $lazyCollection = LazyCollection::times(INF)->tapEach(function ($value) {
        dump($value);
    });
$array = $lazyCollection->take(100)->all();
dump($array);
 
});

Here you can see that we are calling taking 100 from the list so it means that if we comment line $array = $lazyCollection-> take(100)->all();  then nothing will be executed or dumped yet. Lazy collection class take records from the tables when we call the method to execute otherwise it will return empty.

Conclusion

We’re pretty much sure that the Lazy collection class is going to be used by many Laravel applications and We hope this blog will surely help to get knowledge and speed up your application performance. Feel free to contact us regarding Laravel development.

Comments

  • Leave a message...

Related Posts

blog-related-post

Steps to Implement Event Handler in Laravel 5.x Development

November 30, 2018
blog-related-post

Micro framework of Laravel – Lumen

January 9, 2018
blog-related-post

Glance on Upgraded Features of Laravel 5

April 20, 2017