시작 오늘 분석할 코드 — 전체 구조
3개 파일이 협력하는 구조다. memberclass.php는 개별 회원 데이터를 담는 Member 클래스, membersclass.php는 Member를 여러 개 모아 관리하는 컬렉션 클래스, iterator.php는 이 둘을 불러와 실제 데이터를 만들고 foreach로 출력하는 실행 파일이다.
require_once 'memberclass.php'; // Member 클래스 로드 require_once 'membersclass.php'; // Members 클래스 로드 // 1. 회원 더미 데이터 5개 생성 $member1 = new Member(1,"성1","이름1","email1@example.com","password1"); $member2 = new Member(2,"성2","이름2","email2@example.com","password2"); // ... $member3, $member4, $member5 동일 패턴 // 2. Members 컬렉션에 추가 $members = new Members; $members->add($member1); $members->add($member2); // ... add($member3), add($member4), add($member5) // 3. 이터레이터 취득 후 foreach로 순회 $iterator = $members->getIterator(); foreach($iterator as $member) { print $member->getId() . " "; print $member->getLastname() . " "; print $member->getFirstname() . " "; print $member->getEmail() . " "; print $member->getPassword() . "<br>"; }
실제 출력 미리보기
1 성1 이름1 email1@example.com password1
2 성2 이름2 email2@example.com password2
3 성3 이름3 email3@example.com password3
4 성4 이름4 email4@example.com password4
5 성5 이름5 email5@example.com password5
→ foreach가 Members 컬렉션의 이터레이터를 통해 Member 객체를 순서대로 꺼내 getter로 출력
용어 핵심 용어 정리
이터레이터 패턴컬렉션 내부 구조를 노출하지 않고, 순회 방법만 외부에 제공하는 디자인 패턴
컬렉션같은 종류의 객체 여러 개를 모아 관리하는 객체. Members가 Member 객체들의 컬렉션
더미 데이터실제 DB 연동 없이 테스트용으로 코드에서 직접 만든 임시 데이터
require_once외부 PHP 파일을 로드. _once는 중복 로드 방지. 클래스 파일 분리 시 사용
getIterator()IteratorAggregate 구현 메서드. foreach가 호출하는 진입점. ArrayIterator를 반환
$members[]배열 끝에 값을 추가하는 PHP 문법. push와 동일. $this->members[] = $member
foreach as이터레이터에서 요소를 하나씩 꺼내 $member 변수에 대입하며 반복
디자인 패턴반복적으로 등장하는 설계 문제의 검증된 해결책. 이터레이터 패턴은 GoF 23가지 패턴 중 하나
1 3파일 구조 — 왜 클래스를 파일로 분리하는가
관심사를 나누고 재사용성을 높이기 위해
Member 클래스, Members 클래스, 실행 코드를 모두 한 파일에 넣을 수도 있다. 하지만 파일을 나누면 각 파일을 독립적으로 재사용할 수 있고, 수정할 때 영향 범위가 명확해진다. DB에서 데이터를 읽어오는 코드로 바꾸더라도 Member/Members 클래스 파일 자체는 그대로 쓸 수 있다.
memberclass.php
Member 클래스
→
membersclass.php
Members 컬렉션
→
iterator.php
실행 + 출력
※ require_once 'memberclass.php'는 현재 파일과 같은 폴더에 있는 memberclass.php를 한 번만 로드한다.
2 더미 데이터 생성 — 생성자로 한 줄에
new Member(인수들) 로 즉시 초기화하는 이유
Member 클래스에 __construct 생성자가 있기 때문에 객체 생성과 동시에 모든 멤버변수를 초기화할 수 있다. 5개 회원 데이터를 각각 1줄로 만들 수 있다. 생성자가 없었다면 각 객체마다 setter를 5번씩, 총 25번 호출해야 했다.
// 생성자 덕분에 각 회원이 1줄로 초기화됨 $member1 = new Member(1, "성1", "이름1", "email1@example.com", "password1"); $member2 = new Member(2, "성2", "이름2", "email2@example.com", "password2"); $member3 = new Member(3, "성3", "이름3", "email3@example.com", "password3"); $member4 = new Member(4, "성4", "이름4", "email4@example.com", "password4"); $member5 = new Member(5, "성5", "이름5", "email5@example.com", "password5");
3 컬렉션에 담기 — add()의 역할
Member 객체들을 Members라는 그릇에 모으는 이유
5개의 Member 객체가 각각 개별 변수($member1~5)에 흩어져 있다. 이것을 $members->add()로 Members 컬렉션에 모으면 하나의 단위로 관리할 수 있다. 이후 이 컬렉션 하나만 함수에 전달하면 5개 데이터를 한번에 넘길 수 있다.
$members = new Members; // 빈 컬렉션 생성 $members->add($member1); // 내부 배열에 Member 객체 추가 $members->add($member2); $members->add($member3); $members->add($member4); $members->add($member5); // $members 하나에 5개 Member 객체가 담김
4 getIterator() + foreach — 순회 실행
이터레이터를 명시적으로 꺼낸 뒤 foreach로 돌리는 패턴
$members->getIterator()로 ArrayIterator를 명시적으로 꺼낸 뒤 foreach에 넣는다. foreach는 이터레이터를 순회하며 매 반복마다 Member 객체를 $member 변수에 담아준다. 이 객체의 getter를 호출해서 각 필드를 출력한다.
$iterator = $members->getIterator(); // ArrayIterator 취득 foreach($iterator as $member) { // $member는 Member 객체 — getter로 각 필드 조회 print $member->getId() . " "; print $member->getLastname() . " "; print $member->getFirstname() . " "; print $member->getEmail() . " "; print $member->getPassword() . "<br>"; }
※ foreach($members->getIterator() as $member)로 한 줄로 써도 동일하다. 이터레이터를 변수에 담는 것은 재사용이 필요할 때 유용하다.
5 이터레이터 패턴의 실용적 의미
내부 구조를 숨기고 순회 방법만 노출한다
foreach를 쓰는 코드는 Members 내부가 배열인지, 링크드 리스트인지, DB 결과인지 알 필요가 없다. getIterator()가 순회 가능한 객체를 반환하기만 하면 된다. 나중에 Members의 내부를 DB 쿼리 결과로 바꿔도 foreach를 쓰는 코드는 수정할 필요가 없다.
패턴 없이 직접 접근
내부 배열에 직접 접근
for($i=0; $i<count($arr); $i++)
내부가 바뀌면 순회 코드도 모두 수정 필요.
이터레이터 패턴
foreach($members->getIterator() as $m)
내부 구조가 바뀌어도 순회 코드는 그대로. 유지보수 용이.
6 3클래스 역할 분담 정리
Member, Members, iterator.php 각자의 책임
| 파일 |
클래스 |
역할 |
핵심 메서드 |
| memberclass.php |
Member |
개별 회원 데이터 저장·조회 |
__construct, getId/setId, getEmail/setEmail 등 |
| membersclass.php |
Members |
Member 객체를 모아 관리하는 컬렉션 |
add(Member $m), getIterator() |
| iterator.php |
(실행 파일) |
두 클래스를 불러와 데이터 생성·출력 |
require_once, new Member(), add(), foreach |
7 자주 하는 실수
| 실수 |
증상 |
해결 |
| require_once 파일명 오타 |
Class 'Member' not found 오류 |
파일명과 경로가 대소문자까지 정확한지 확인 |
| $members에 add() 전 foreach 실행 |
아무것도 출력되지 않음 |
add()로 데이터를 모두 추가한 뒤 foreach 실행 |
| $member->id 직접 접근 |
Cannot access private property 오류 |
private 멤버변수는 getter $member->getId()로만 접근 |
| foreach 안에서 $member 재사용 |
루프 종료 후 마지막 $member 값이 남아 혼동 |
foreach 블록 밖에서 $member 사용 주의. 별도 변수에 결과 저장 권장 |
| new Members() 대신 new Members로 실행 |
정상 동작하지만 일관성 저하 |
생성자 인수가 없어도 new Members() 괄호 붙이는 것이 관례 |
핵심 한 줄 요약
이터레이터 패턴컬렉션 내부를 숨기고 getIterator()로만 순회 방법 제공 — 내부 변경에 강함
3파일 분리Member(데이터) / Members(컬렉션) / iterator(실행) — 관심사 분리로 재사용 가능
생성자 + add()new Member(1줄 초기화) → $members->add()로 컬렉션에 추가 → foreach로 순회
foreach as $member이터레이터가 Member 객체를 하나씩 건네줌 — getter로 각 필드 출력
Tags
#PHP 이터레이터 패턴 #foreach 객체 순회 #IteratorAggregate #ArrayIterator #PHP 디자인 패턴 #PHP OOP 실습 #Member 컬렉션 #require_once #PHP foreach #PHP 객체지향 #컬렉션 패턴 #웹개발 #티스토리
▼ 티스토리 태그 입력란 복사용
PHP 이터레이터 패턴, foreach 객체 순회, IteratorAggregate, ArrayIterator, PHP 디자인 패턴, PHP OOP 실습, require_once, PHP foreach, PHP 객체지향, 컬렉션 패턴
댓글