Computer >> 컴퓨터 >  >> 프로그래밍 >> PHP

PHP 제너레이터(Generator) 클래스 완벽 가이드 – yield로 메모리 효율적인 반복 처리하기

개요

대량의 데이터를 foreach와 같은 반복문으로 순회하려면 많은 메모리와 상당한 처리 시간이 필요합니다. 하지만 제너레이터(generator)를 사용하면 이러한 오버헤드 없이도 데이터 집합을 반복(iterate)할 수 있습니다.

제너레이터 함수는 겉보기에 일반 함수와 매우 비슷합니다. 다만 return 문 대신 yield 키워드를 사용하여 함수가 반복적으로 실행되면서 순회할 값을 하나씩 제공한다는 점이 다릅니다.

yield 키워드는 제너레이터 메커니즘의 핵심입니다. return과 사용 방식이 비슷해 보이지만, yield는 함수의 실행을 종료하지 않습니다. 대신 다음 반복에 사용할 값을 제공한 뒤 함수의 실행을 일시 중지(pause)했다가, 다음 값이 요청될 때 중단된 지점부터 이어서 실행합니다.

클래스 시놉시스(Synopsis)

Generator implements Iterator {
    /* Methods */
    public current ( void ) : mixed
    public getReturn ( void ) : mixed
    public key ( void ) : mixed
    public next ( void ) : void
    public rewind ( void ) : void
    public send ( mixed $value ) : mixed
    public throw ( Throwable $exception ) : mixed
    public valid ( void ) : bool
    public __wakeup ( void ) : void
}

주요 메서드

public Generator::current ( void ) : mixed — 현재 yield된 값을 반환합니다.

public Generator::getReturn ( void ) : mixed — 제너레이터의 최종 반환 값을 가져옵니다.

public Generator::key ( void ) : mixed — 현재 yield된 값의 키(key)를 반환합니다.

public Generator::next ( void ) : void — 제너레이터의 실행을 재개합니다. NULL을 인자로 Generator::send()를 호출하는 것과 동일한 효과를 가집니다.

public Generator::rewind ( void ) : void — 이터레이터를 처음 상태로 되감습니다. 이미 반복이 시작된 상태에서 호출하면 예외(Exception)가 발생합니다.

public Generator::send ( mixed $value ) : mixed — 지정한 값을 현재 yield 표현식의 결과값으로 제너레이터에 전달하고, 실행을 재개합니다.

public Generator::throw ( Throwable $exception ) : mixed — 제너레이터 내부로 예외를 던진 뒤, 제너레이터의 실행을 재개합니다.

public Generator::valid ( void ) : bool — 이터레이터가 아직 유효한지, 즉 반복이 종료되었는지 여부를 확인합니다.

public Generator::__wakeup ( void ) : void — 제너레이터는 직렬화(serialization)할 수 없으므로 예외를 발생시킵니다.

제너레이터의 특징

Generator 클래스는 Iterator 인터페이스를 구현합니다. 따라서 제너레이터 객체는 new 키워드로 직접 인스턴스화할 수 없으며, yield 키워드를 포함하는 모든 사용자 정의 함수가 호출될 때 자동으로 Generator 클래스의 객체가 생성됩니다.

제너레이터 기본 예제

제너레이터는 Iterator 인터페이스를 구현하므로, foreach 문을 사용하여 yield된 값을 손쉽게 순회할 수 있습니다.

<?php
function squaregenerator(){
    for ($i=1; $i<=5; $i++){
        yield $i*$i;
    }
}
$gen=squaregenerator();
foreach ($gen as $val){
    echo $val . " ";
}
?>

실행 결과

위 프로그램을 실행하면 다음과 같은 출력이 나타납니다.

1 4 9 16 25

Iterator 메서드를 활용한 예제

다음 예제에서는 foreach 대신 제너레이터 클래스의 current()next() 메서드를 사용하여 yield된 값을 순회합니다. 반복 종료 조건은 valid() 메서드로 확인합니다.

<?php
function squaregenerator(){
    for ($i=1; $i<=5; $i++){
        yield $i*$i;
    }
}
$gen=squaregenerator();
while ( $gen->valid() ){
    echo "key: " . $gen->key(). " value: ". $gen->current() . "\n";
    $gen->next();
}
?>

실행 결과

위 프로그램을 실행하면 각 값의 키와 값이 함께 출력됩니다.

key: 0 value: 1
key: 1 value: 4
key: 2 value: 9
key: 3 value: 16
key: 4 value: 25

정리

PHP 제너레이터는 대용량 데이터를 처리할 때 메모리 사용량을 크게 줄여주는 강력한 도구입니다. 전체 배열을 메모리에 올리는 대신 필요할 때마다 값을 하나씩 생성하여 반환하기 때문에, 파일을 한 줄씩 읽거나 무한 시퀀스를 다루는 등의 작업에 특히 유용합니다. yield 키워드와 Iterator 메서드(current, key, next, valid, send 등)의 동작 원리를 이해하면 더욱 효율적인 PHP 코드를 작성할 수 있습니다.