제너레이터


모든 함수의 실행은 한 번의 호출과 한 번의 함수 처리를 하게 됩니다.
하지만 특이하게도 제너레이터는 yield 키워드를 사용한 PHP 함수로 분할하여 실행할 수 있습니다. 특수한 형태의 함수입니다.

또한 제너레이터는 특성상 반환값을 갖지 안습니다. 제너레이터는 PHP 5.5 업그레이드되면서 적용된 기능입니다.


yield


제너레이터 함수의 핵심은 yield 키워드입니다.

yield 키워드는 return과 비슷한 것 같지만 다릅니다. 프로그램의 return문은 함수를 끝내는 역할을 하지만 yield는 함수를 잠시 멈추는 역할을 합니다. 즉, 함수는 잠시 멈춘 상태를 저장해 놓은 상태에서 함수를 재호출할 때 동작을 이어서 처리합니다.

제너레이터 함수에서 yield키워드를 사용하는 개수의 제한은 없습니다. 하나의 제너레이터 함수에 한 개 또는 여러 개의 yield 함수를 넣어서 잠시 멈출 수 있는 횟수를 지정할 수 있습니다. 제너레이터 함수를 호출하면 첫 번째 yield 명령이 나올 때까지 실행을 하고 잠시 멈춥니다.

또 다시 제너레이터 함수를 실행을 하면 이전에 멈춘 위치부터 다음 위치의 yield 명령문까지 실행합니다.

이런 형태로 멈춤 기능을 통해 함수를 분할하여 실행을 할 수 있습니다. 제너레이터는 함수의 마지막 끝까지 또는 return;문이 나올 때까지 반복합니다.

예제 파일 generator-01.php

<?php

// yield 키워드는 값을 반환한다는 측면에서 return 키워드와 비슷하면서도 다르다. 

function myGen(){
	// 호출 시 첫 번째 yield 키워드까지 실행한다.
	echo "첫 번째 호출=";
	yield "test1";

	// 호출 시 두 번째 yield 키워드까지 실행한다.
	echo "두 번째호출=";
	yield "test2";

	// 호출 시 세 번째 yield 키워드까지 실행한다.
	echo "세 번째 호출=";
	yield "test3";
	
}

foreach (myGen() as $value) {
	echo $value."<br>";
}

?>

결과

첫 번째 호출=test1
두 번째 호출=test2
세 번째 호출=test3

위의 예를 보면 제너레이터는 반환값이 없는 대신에 yield 뒤에 값을 입력하면 foreach문으로 특정 데이터를 가지고 올 수 있습니다.


제너레이터 델리게이션


제너레이터 함수 실행 시 from 키워드를 추가하여 또 다른 제너레이터 함수로 연결 실행할 수 있습니다. 즉, 제너레이터 함수 안에 또 다른 제너레이터 함수를 추가하여 실행할 수 있습니다.

예제 파일 generator-02.php

<?php
function gen(){
	yield "gen() 1 실행";
	yield "gen() 2 실행";

	// 3번째 yield는 gen2() 제너레이터로 연결
	yield from gen2();
}

function gen2(){
	yield "gen2() 3 실행";
	yield "gen2() 4 실행";
}

foreach (gen() as $val){
	echo $val."<br>";
}
?>

결과

gen() 1 실행
gen() 2 실행
gen2() 3 실행
gen2() 4 실행

위의 예제는 두 개의 제너레이터 함수를 연결하여 사용하는 예제입니다.
gen() 함수에 yield 키워드 두 개와 gen2() 함수에 yield 키워드 두 개를 연결하여 총 네 개의 yield 키워드가 삽입되어 있습니다.

gen() 함수는 총 네 번으로 나누어 실행하게 됩니다.


제너레이터 예

예제 파일 generator-03.php

<?php
	function rowsCount($count){
		for ($i=0;$i<$count;$i++){
			// 반복문 안에도 yield를 넣어서 반복할 수 있습니다.
			yield $i;
		}
	}

	foreach (rowsCount(10) as $i){
		echo " 실행 =". $i . "<br>";
	}
?>

결과

실행 =0
실행 =1
실행 =2
실행 =3
실행 =4
실행 =5
실행 =6
실행 =7
실행 =8
실행 =9

위의 예는 제너레이터 함수 안에 반복문을 통해 yield 키워드를 동적으로 삽입합니다.
또한 제너레이터 함수를 호출할 때 매개변수로 반복 횟수를 전달합니다.
즉, 제너레이터 함수는 반복 횟수만큼 함수를 분할하여 실행하게 됩니다.