Generators 개요

(PHP 5 >= 5.5.0, PHP 7, PHP 8)

Generator는 Iterator 인터페이스를 구현하는 클래스를 구현하는 오버헤드나 복잡성 없이 간단한 Iterator를 구현하는 쉬운 방법을 제공합니다.

Generator를 사용하면 메모리에 배열을 구축할 필요 없이 foreach를 사용하여 데이터 세트를 반복하는 코드를 작성할 수 있습니다. 이로 인해 메모리 제한을 초과하거나 생성하는 데 상당한 처리 시간이 필요할 수 있습니다. 대신 일반 함수와 동일한 생성기 함수를 작성할 수 있습니다. 단, 생성기는 한 번 반환하는 대신 반복할 값을 제공하기 위해 필요한 만큼 생성할 수 있습니다.

이에 대한 간단한 예는 range() 함수를 생성기로 다시 구현하는 것입니다. 표준 range() 함수는 모든 값이 포함된 배열을 생성하고 반환해야 하므로 배열이 커질 수 있습니다. 예를 들어 range(0, 1000000)을 호출하면 100MB가 훨씬 넘는 메모리가 사용됩니다.

대안으로 xrange() 생성기를 구현할 수 있습니다. 이 생성기는 Iterator 객체를 생성하고 내부적으로 생성기의 현재 상태를 추적하는 데 충분한 메모리만 필요하며, 이는 1킬로바이트 미만입니다.

예제 #1 생성기로 range() 구현하기

                  
<?php
function xrange($start, $limit, $step = 1) {
    if ($start <= $limit) {
        if ($step <= 0) {
            throw new LogicException('Step must be positive');
        }

        for ($i = $start; $i <= $limit; $i += $step) {
            yield $i;
        }
    } else {
        if ($step >= 0) {
            throw new LogicException('Step must be negative');
        }

        for ($i = $start; $i >= $limit; $i += $step) {
            yield $i;
        }
    }
}

/*
 * Note that both range() and xrange() result in the same
 * output below.
 */

echo 'Single digit odd numbers from range():  ';
foreach (range(1, 9, 2) as $number) {
    echo "$number ";
}
echo "\n";

echo 'Single digit odd numbers from xrange(): ';
foreach (xrange(1, 9, 2) as $number) {
    echo "$number ";
}
?>
                  
                

위의 예는 다음을 출력합니다.

Single digit odd numbers from range():  1 3 5 7 9
Single digit odd numbers from xrange(): 1 3 5 7 9
                

생성기 객체

generator 함수가 호출되면 내부 Generator 클래스의 새 객체가 반환됩니다. 이 객체는 순방향 전용 iterator 객체와 거의 동일한 방식으로 Iterator 인터페이스를 구현하고 값을 보내고 반환하는 것을 포함하여 생성기의 상태를 조작하기 위해 호출할 수 있는 메서드를 제공합니다.