Если вы знакомы с Python или другими языками, вы должны быть знакомы с генераторами. Тем не менее, многие разработчики PHP могут не знать функции генератора, это может быть связано с тем, что генератор является функцией, представленной в PHP 5.5.0, или функция генератора не очень очевидна. Однако функция генератора действительно полезна.
преимущество
Подсчитано, что вы все еще в замешательстве после непосредственного прослушивания концепции, поэтому давайте сначала поговорим о преимуществах, которые могут пробудить ваш интерес. Итак, в чем преимущества генераторов, а именно:
- Генераторы могут оказать огромное влияние на производительность приложения PHP.
- Экономьте много памяти при запуске PHP-кода
- Больше подходит для обработки больших объемов данных
Итак, как именно работают эти магические функции? Сначала возьмем пример.
Введение концепции
Во-первых, давайте отбросим бремя концепции генератора и посмотрим на простую функцию PHP:
function createRange($number){
$data = [];
for($i=0;$i<$number;$i++){
$data[] = time();
}
return $data;
}
Это очень распространенная функция PHP, которую мы часто используем при работе с некоторыми массивами. Код здесь тоже очень простой:
- Создаем функцию.
- Функция содержит
for
Цикл, мы зацикливаем текущее время на$data
в -
for
После выполнения цикла поместите$data
Вернитесь назад.
Это не конец, продолжим. Давайте напишем еще одну функцию и выведем возвращаемое значение этой функции в цикле:
$result = createRange(10); // 这里调用上面我们创建的函数
foreach($result as $value){
sleep(1);//这里停顿1秒,我们后续有用
echo $value.'<br />';
}
Посмотрим на результаты в браузере:
Здесь все идеально, никаких проблем. (Конечноsleep(1)
Эффекта не видно)
подумать о проблеме
Заметим, что при вызове функцииcreateRange
при даче$number
Передано значение 10, очень маленькое число. Предположим, теперь передайте значение10000000
(10 миллионов).
Тогда в функцииcreateRange
в,for
Цикл должен быть выполнен1000
10 000 раз. и имеют1000
10 000 значений помещаются в$data
внутри, пока$data
Теперь массивы размещаются в памяти. Таким образом, при вызове функции будет занимать много памяти.
Здесь в игру вступают генераторы.
Создать генератор
Мы модифицируем код напрямую, обратите внимание на следующее:
function createRange($number){
for($i=0;$i<$number;$i++){
yield time();
}
}
Взгляните на этот код, который очень похож на тот, что был только что: мы удаляем массив$data
, и тоже ничего не возвращает, но вtime()
Ключевое слово использовалось ранееyield
использовать генератор
Давайте снова запустим второй фрагмент кода:
$result = createRange(10); // 这里调用上面我们创建的函数
foreach($result as $value){
sleep(1);
echo $value.'<br />';
}
Чудесным образом мы обнаружили, что выходное значение не такое, как в первый раз без использования генератора. Значения (временные метки) здесь отстоят друг от друга на 1 секунду.
Интервал в одну секунду здесь на самом делеsleep(1)
последствия. Но почему нет интервала в первый раз? это потому, что:
- Когда генераторы не используются:
createRange
внутри функцииfor
Результат цикла быстро помещается в$data
, и немедленно вернуться. так,foreach
Цикл представляет собой фиксированный массив. - При использовании генераторов:
createRange
Значение не генерируется быстро за один раз, а зависит отforeach
цикл.foreach
цикл один раз,for
Выполнить один раз.
На этом этапе вы должны иметь представление о генераторах.
Глубокое понимание генераторов
Анализ кода
Давайте проанализируем код прямо сейчас.
function createRange($number){
for($i=0;$i<$number;$i++){
yield time();
}
}
$result = createRange(10); // 这里调用上面我们创建的函数
foreach($result as $value){
sleep(1);
echo $value.'<br />';
}
Восстановим процесс выполнения кода.
- первый звонок
createRange
функция, передача параметров10
,ноfor
value выполняется один раз, затем останавливается и сообщаетforeach
Значения, которые можно использовать для первого цикла. -
foreach
начать правильно$result
петля, заходи первымsleep(1)
, затем начните использоватьfor
Выполняет вывод для заданного значения. -
foreach
Чтобы подготовиться ко второму циклу, перед началом второго циклаfor
Цикл спрашивает снова. -
for
Затем цикл выполняется снова, сообщая сгенерированную метку времениforeach
. -
foreach
Получите второе значение и выведите. потому чтоforeach
серединаsleep(1)
,так,for
Цикл задерживается на 1 секунду для генерации текущего времени
Поэтому во всем выполнении кода в цикле участвует всегда только одно значение записи, а в памяти находится только одна порция информации.
вне зависимости от входящего$number
Насколько большой, поскольку не все наборы результатов генерируются сразу, память всегда является значением цикла.
концептуальное понимание
К этому моменту у вас должно быть общее представление о том, что такое генератор. Теперь поговорим о принципе генератора.
Сначала определите понятие:Ключевое слово генератора yield не является возвращаемым значением, его технический термин называется выходным значением, он просто генерирует значение.
тогда в кодеforeach
Что такое цикл? На самом деле, когда PHP использует генератор, он возвращаетGenerator
объект класса.foreach
Этот объект можно повторять, каждую итерацию PHP будет проходитьGenerator
Экземпляр вычисляет значение, которое необходимо повторить следующим образом. такforeach
Просто знайте значение, которое необходимо повторить в следующий раз.
Более того, во время бегаfor
После выполнения цикла он немедленно останавливается. ждатьforeach
снова в следующем цикле сfor
При запросе следующего значенияfor
Цикл выполнится только один раз, а затем сразу же остановится. Не выполнять до тех пор, пока условие не будет выполнено.
актуальное приложение для разработки
Многие PHP-разработчики не понимают генераторы, главным образом потому, что они не понимают предметную область приложения. Итак, каковы применения генераторов в реальной разработке?
Чтение очень больших файлов
Разработчики PHP часто считывают большие файлы, такие как файлы csv, текстовые файлы или некоторые файлы журналов. Если эти файлы большие, например 5G. В настоящее время нецелесообразно напрямую считывать все содержимое в память для вычисления за один раз.
Здесь генератор можно использовать в полевых условиях. Просто посмотрите: Прочитайте текстовый файл
Мы создаем текстовый документ и вводим в него несколько строк текста для демонстрации чтения.
<?php
header("content-type:text/html;charset=utf-8");
function readTxt()
{
# code...
$handle = fopen("./test.txt", 'rb');
while (feof($handle)===false) {
# code...
yield fgets($handle);
}
fclose($handle);
}
foreach (readTxt() as $key => $value) {
# code...
echo $value.'<br />';
}
Из вывода на приведенном выше рисунке видно, что код совершенно нормальный.
Однако правила выполнения кода, стоящие за ним, ничем не отличаются. Используйте генератор для чтения файла, в первый раз читается первая строка, во второй раз вторая строка и так далее,В память загружается только одна строка текста за раз, что значительно снижает использование памяти.
Таким образом, вам не нужно беспокоиться о чтении текста на G, и вы можете писать код, как чтение небольшого файла.
над
Порекомендуйте URL-навигацию для разработчиков, разработанную нашей командой:Навигация с помощью пера — создавайте самую краткую навигацию по веб-сайту с душой