1. Overview
The generator is a new feature introduced in PHP 5.5, but it's a very useful feature that few people use to visually.
Generators and iterators are somewhat similar, but unlike standard PHP iterators, the PHP generator does not require classes to implement iterator interfaces, which eases the overhead and burden of classes. The generator calculates and outputs the values that need to be iterated each time according to the requirements, this has a great impact on the performance of the application: imagine that if the standard PHP iterator performs iterative operations in memory, it will have to compute the dataset in advance, with low performance; If you want to compute a large amount of data in a particular way, such as manipulating Excel table data, has more impact on performance. At this point we can use the generator to instantly compute and output subsequent values without consuming valuable memory space.
2, create the generator
The builder is very simple to create, because the builder is the PHP function, except to use the yield keyword one or more times in the function. Unlike ordinary PHP functions, the generator never returns a value, but only outputs a value. The following is a simple generator implementation:
function Getlaravelacademy () {
Yield www.111cn.net ';
Yield ' Laravel college ';
Yield ' laravel Academy ';
}
It's simple! When you call this builder function, PHP returns an object that belongs to the generator class, which can be iterated using the Foreach function, and each iteration, PHP requires the generator instance to compute and provide the next value to iterate. The elegance of the builder shows that the internal state of the generator pauses after each output of a value, and the internal state is restored when the next value is requested from the builder. The state inside the generator will always switch between pauses and recoveries until the end of the function definition body is reached or an empty return statement is encountered. We can use the following code to call and iterate through the builder defined above:
foreach (Getlaravelacademy () as $yieldedValue) {
Echo $yieldedValue, Php_eol;
}
The above code output is as follows:
Laravel Academy
3. Using generators
Here we implement a simple function to generate a range of values to show how the generator saves memory. First we implement the iterator:
function Makerange ($length) {
$dataSet = [];
for ($i =0; $i < $length; $i + +) {
$dataSet [] = $i;
}
return $dataSet;
}
$customRange = Makerange (1000000);
foreach ($customRange as $i) {
Echo $i. Php_eol;
}
An error occurs at this time, indicating that the memory limit for a single PHP process is exceeded (to provide memory space for 1 million digits):
Memery-overflow-iterator
Here's what we can do to improve the implementation, using the builder to implement the following:
function Makerange ($length) {
for ($i =0; $i < $length; $i + +) {
Yield $i;
}
}
foreach (Makerange (1000000) as $i) {
Echo $i. Php_eol;
}
Again, you can print out the results without pressure because the generator only needs to allocate memory for one integer at a time.
In addition, a common use case is to use the generator to iterate through the stream resources (files, audio, and so on). Let's say we want to iterate over a CSV file size 4GB, and the Virtual Private server (VPS) only allows PHP to use 1GB memory, so the entire file cannot be loaded into memory, and the following code shows how to do this using the builder:
function GetRows ($file) {
$handle = fopen ($file, ' RB ');
if ($handle = = FALSE) {
throw new Exception ();
}
while (feof ($handle) = = FALSE) {
Yield Fgetcsv ($handle);
}
Fclose ($handle);
}
foreach ($getRows ($file) as $row) {
Print_r ($row);
}
The example above allocates memory for only one row in the CSV file at a time, and does not read the entire 4GB CSV file into memory.
4, summary
The generator is a compromise between functional diversity and simplicity, and the generator is just to the forward iterator, which means that you cannot use the generator to perform backward, fast forward, or lookup operations in the dataset, allowing the generator to calculate and output the next value. It is best to use a builder when iterating over large datasets or series, because this consumes the least amount of system memory. The generator can also accomplish simple tasks that the iterator can accomplish, and uses less code.