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

PHP 제너레이터(Generator)와 이터레이터(Iterator) 객체 완벽 가이드

소개

PHP에서 제너레이터(generator) 함수를 호출하면 내부적으로 Generator 클래스의 새로운 객체가 반환됩니다. 이 객체는 Iterator 인터페이스를 구현하고 있으며, 해당 인터페이스는 다음과 같은 추상 메서드들을 정의합니다.

  • Iterator::current() — 현재 요소를 반환합니다.
  • Iterator::key() — 현재 요소의 키(key)를 반환합니다.
  • Iterator::next() — 다음 요소로 이동합니다.
  • Iterator::rewind() — 이터레이터를 첫 번째 요소로 되감습니다.
  • Iterator::valid() — 현재 위치가 유효한지 검사합니다.

제너레이터는 순방향 전용(forward-only) 이터레이터처럼 동작하며, 제너레이터의 상태를 조작할 수 있는 다양한 메서드를 제공합니다. 여기에는 제너레이터에 값을 전송하거나 그로부터 값을 받아오는 기능도 포함됩니다.

이터레이터로서의 제너레이터

다음 예제에서는 제너레이터 함수가 파일의 각 줄을 yield하여 제너레이터 객체를 생성하고, 이를 foreach 루프로 순회합니다. current(), next() 같은 이터레이터 메서드도 직접 호출할 수 있습니다. 하지만 제너레이터는 순방향 전용 이터레이터이므로, 이미 실행이 완료된 제너레이터에 대해 rewind() 메서드를 호출하면 예외(exception)가 발생합니다.

예제 코드

<?php
function filegenerator($name) {
    $fileHandle = fopen($name, 'r');
    while ($line = fgets($fileHandle)) {
        yield $line;
    }
    fclose($fileHandle);
}
$name = "test.txt";
$file = filegenerator($name);
foreach ($file as $line)
    echo $line;
$file->rewind();
echo $file->current();
$file->next();
echo $file->current();
?>

실행 결과

파일의 모든 줄을 순회한 후 rewind()를 호출하면 아래와 같은 치명적 오류(fatal error)가 발생합니다.

PHP User Defined Functions
PHP Function Arguments
PHP Variable Functions
PHP Internal (Built-in) Functions
PHP Anonymous functions
PHP Arrow Functions
PHP Fatal error: Uncaught Exception: Cannot rewind a generator that was already run

핵심 정리

제너레이터는 Iterator 인터페이스를 구현하지만 한 방향으로만 진행할 수 있습니다. 이미 끝까지 실행된 제너레이터는 되감을 수 없으므로, 처음부터 다시 데이터를 순회해야 하는 경우에는 제너레이터 함수를 새로 호출하여 새로운 제너레이터 객체를 생성해야 합니다. 대용량 파일 처리처럼 메모리 효율이 중요한 작업에서 제너레이터를 활용할 때 이 특성을 반드시 기억해 두어야 합니다.