이 페이지의 목적
이 페이지는,collect()의 사용법이 아니라, Laravel 본체의 구현 코드를 읽기 위한 지도를 제공합니다.
대상은, Collection의 메서드 목록은 이미 알고 있고, 다음으로 “왜 이 설계인가”를 이해하고 싶은 사람입니다.
역사적 변천
Collection의 구조는,LazyCollection 도입 시에 크게 정리되었습니다.
Laravel 5.8까지
Illuminate\Support\CollectionIlluminate\Database\Eloquent\Collection(Collection을 상속)
LazyCollection·Enumerable·EnumeratesValues는 존재하지 않습니다.
Laravel 6.0에서의 변경
LazyCollection 추가에 맞추어, 공통 API를 Enumerable(인터페이스)와 EnumeratesValues(트레이트)로 분리하는 구조가 되었습니다.
현재의 전체 구조 (Laravel 13)
참조: laravel/framework v13.x
현재의 실제 파일 경로는
src/Illuminate/Collections/*이지만, 네임스페이스는 Illuminate\\Support 그대로 유지되고 있습니다. 코드를 읽을 때는 “경로”와 “namespace”를 분리해 확인해 주세요.PHPDoc과 PHPStan 스타일의 Generics
PHP 본체에는 Generics가 없습니다. 그럼에도 Collection 주변에서는, PHPDoc으로 강한 타입 정보를 표현하고 있습니다. 주요 목적은 2가지입니다.- IDE 자동 완성을 정확히 하기
- PHPStan / Larastan 등의 정적 해석 정밀도를 높이기
자주 나오는 기법
| 기법 | 의미 |
|---|---|
@template TKey of array-key | 키 타입을 int|string으로 제약 |
@template-covariant TValue | 값 타입을 공변으로 취급(보다 구체적인 타입으로 안전하게 치환하기 쉬움) |
@implements ...<TKey, TValue> | 구현하는 인터페이스에 타입 인수를 전달 |
@extends ...<TKey, TModel> | 부모 클래스 상속 시의 타입 인수를 선언 |
@use ...<TKey, TValue> | 트레이트 적용 시의 타입 인수를 선언 |
Eloquent Collection에서의 모습
TValue가 TModel로 구체화되므로, map()·filter() 등의 타입 추론이 Eloquent 모델 쪽으로 강화됩니다.
구현을 읽을 때의 순서
1. 입구로서 Enumerable을 읽는다
우선은 “무엇을 제공하는 계약인가”를 파악합니다.
여기에서 메서드 목록을 파악하면, 이후 구현 읽기가 빨라집니다.
2. EnumeratesValues에서 공통 메서드를 따라간다
map·filter·reduce 등, 공통 로직의 대부분은 여기에 있습니다.
Collection과 LazyCollection의 차이만 나중에 보면, 읽어 넘기기가 줄어듭니다.
3. Collection과 LazyCollection의 차이를 본다
Collection: 배열을 보관하며 즉시 평가LazyCollection:Generator를 사용해 지연 평가
4. 마지막으로 Eloquent\Collection을 읽는다
find·load·modelKeys 등, 모델 집합용 확장에 집중합니다.
기저의 Collection을 이해한 뒤에 읽으면 의도가 보이기 쉬워집니다.