Skip to main content

PHP 어트리뷰트란

PHP 어트리뷰트(PHP Attributes)는 PHP 8.0에서 도입된 네이티브 메타데이터 문법입니다. 클래스, 메서드, 프로퍼티, 함수 등에 대해 #[AttributeName] 형식으로 메타 정보를 부여할 수 있습니다. Laravel은 프레임워크 본체에서 PHP 어트리뷰트를 적극적으로 채택하고 있으며, 잡이나 Eloquent 모델의 설정을 선언적으로 작성할 수 있습니다. Laravel 13(v13.2.0)에서는 큐 어트리뷰트가 enum을 받을 수 있게 되었습니다. 기존의 클래스 프로퍼티나 메서드 오버라이드 대신 어트리뷰트를 사용하여 더 읽기 쉽고 간결한 코드를 작성할 수 있습니다.
어트리뷰트는 PHP 8.0 이상에서 사용할 수 있습니다. Laravel 13은 PHP 8.3 이상을 요구하기 때문에 모든 환경에서 어트리뷰트를 사용할 수 있습니다.

큐 관련 어트리뷰트

큐 잡과 관련된 어트리뷰트는 모두 Illuminate\Queue\Attributes 네임스페이스에 있습니다.

#[Queue] — 큐 이름 지정

잡이 전송되는 기본 큐 이름을 지정합니다.
v13.2.0부터는 문자열 대신 enum을 전달할 수도 있습니다.
#[Queue] 어트리뷰트는 Attribute::TARGET_CLASS를 대상으로 설정되어 있으므로 클래스에만 적용할 수 있습니다.

#[Connection] — 연결 지정

잡이 사용하는 기본 큐 연결을 지정합니다.
이쪽도 enum을 사용할 수 있습니다.

#[Backoff] — 재시도 백오프 시간 지정

잡이 실패했을 때 재시도까지의 대기 시간(초)을 지정합니다. 여러 값을 전달하면 재시도마다 다른 대기 시간을 설정할 수 있습니다(가변 인자 지원).
Backoff 클래스의 구현을 보면 가변 인자를 받도록 설계되어 있습니다.
단일 값인 경우 int로, 여러 개인 경우 array로 저장됩니다.

#[Tries] — 재시도 횟수 지정

잡이 실패했을 때의 최대 재시도 횟수를 지정합니다.

#[Timeout] — 타임아웃 지정

잡의 최대 실행 시간(초)을 지정합니다. 이 시간을 초과하면 잡이 강제 종료됩니다.

#[MaxExceptions] — 허용 예외 수 지정

지정한 횟수 이상의 예외가 발생한 경우 잡을 실패로 간주합니다. #[Tries]와 조합하여 사용합니다.

#[UniqueFor] — 유니크 기간 지정

잡의 중복 실행을 방지하는 잠금 기간(초)을 지정합니다. ShouldBeUnique와 조합하여 사용합니다.

#[DeleteWhenMissingModels] — 모델이 존재하지 않을 때 삭제

잡이 의존하는 Eloquent 모델이 발견되지 않는 경우, 잡을 실패가 아닌 삭제(스킵)로 처리합니다.

#[WithoutRelations] — 릴레이션 제외

잡을 직렬화할 때 모델의 릴레이션을 포함하지 않도록 합니다. 큐로 전송되는 데이터를 경량화할 수 있습니다.

#[FailOnTimeout] — 타임아웃 시 실패로 처리

타임아웃이 발생한 경우 잡을 실패로 기록합니다(기본적으로 타임아웃은 실패로 기록되지 않습니다).

여러 큐 어트리뷰트 조합하기

이러한 어트리뷰트들을 조합하여 잡의 동작을 선언적으로 설정할 수 있습니다.

Eloquent 관련 어트리뷰트

Eloquent 모델의 어트리뷰트는 Illuminate\Database\Eloquent\Attributes 네임스페이스에 있습니다. Laravel 13에서는 다수의 어트리뷰트가 추가되었습니다.

#[ScopedBy] — 글로벌 스코프 지정

모델에 자동으로 적용할 글로벌 스코프 클래스를 어트리뷰트로 지정합니다. 상속을 지원하며, IS_REPEATABLE 플래그로 여러 스코프를 지정할 수 있습니다.
여러 스코프를 부여할 경우, 어트리뷰트를 반복하거나 배열로 전달합니다.
기존 booted() 메서드와의 비교입니다.

#[ObservedBy] — 옵저버 지정

모델에 연결할 옵저버 클래스를 어트리뷰트로 지정합니다. ScopedBy와 마찬가지로 IS_REPEATABLE입니다.
여러 옵저버도 지정할 수 있습니다.
기존의 AppServiceProvider에서의 등록이 필요 없어집니다.

#[UseEloquentBuilder] — 커스텀 쿼리 빌더 지정

모델이 사용하는 커스텀 Eloquent 빌더를 어트리뷰트로 지정합니다.

#[CollectedBy] — 커스텀 컬렉션 지정

모델의 컬렉션으로 사용할 커스텀 컬렉션 클래스를 어트리뷰트로 지정합니다.

#[Table] — 테이블 설정을 일괄 지정

테이블 이름, 기본 키, 타임스탬프 등 여러 테이블 관련 설정을 하나의 어트리뷰트로 지정할 수 있습니다.
Table 어트리뷰트에서 설정할 수 있는 옵션은 다음과 같습니다.

#[Scope] — 메서드를 로컬 스코프로 정의

scope 접두사 없는 메서드를 Eloquent의 로컬 스코프로 정의할 수 있습니다.

#[UseFactory] — 팩토리 클래스 지정

모델이 사용하는 커스텀 팩토리 클래스를 어트리뷰트로 지정합니다.

그 밖의 Eloquent 어트리뷰트

Enum 지원(v13.2.0에서 추가)

v13.2.0에서는 #[Queue]#[Connection]이 enum을 받을 수 있게 되었습니다. 이를 통해 문자열 리터럴 대신 PHP enum을 사용하여 타입 안전하게 큐와 연결을 지정할 수 있습니다.
enum을 사용하면 큐 이름이나 연결 이름의 오타를 방지하고 IDE 자동 완성도 활용할 수 있습니다. 애플리케이션 전체에서 큐 이름과 연결 이름을 일원화하여 관리하기에 편리합니다.

기존 클래스 프로퍼티와의 비교

어트리뷰트의 장점

  • 선언적 — 클래스의 상단만 봐도 잡의 동작을 한눈에 파악할 수 있음
  • 타입 안전 — enum을 사용하면 IDE 자동 완성과 타입 검사가 동작함
  • 상속과의 친화성 — 부모 클래스의 어트리뷰트를 자식 클래스에서 덮어쓸 수 있음
  • 코드 감소 — 프로퍼티 선언이나 메서드 오버라이드가 불필요

어트리뷰트의 단점

  • 동적 값을 설정할 수 없음 — 어트리뷰트의 인자는 컴파일 시 상수만 가능. 변수나 설정 파일의 값은 사용할 수 없음
  • 익숙해질 시간이 필요 — 팀에서 PHP 8의 어트리뷰트 문법에 익숙해질 필요가 있는 경우도 있음

동적 값이 필요한 경우

실행 시에 값을 결정하고 싶은 경우에는 기존의 메서드 오버라이드를 사용합니다.
어트리뷰트는 PHP 컴파일 시에 분석됩니다. config()env()와 같은 런타임 값을 사용할 수는 없습니다. 동적인 설정이 필요한 경우에는 계속해서 클래스 프로퍼티나 메서드를 사용하세요.

구현 방식

Laravel은 내부적으로 Reflection API를 사용하여 어트리뷰트를 읽어 옵니다. 큐 워커가 잡을 디스패치할 때 ReadsQueueAttributes 트레이트(InteractsWithQueue에 포함되어 있음)가 리플렉션으로 어트리뷰트를 검출하여 해당하는 프로퍼티에 값을 설정합니다.
Eloquent 모델의 어트리뷰트도 마찬가지로 Model::booted()에 해당하는 시점에 리플렉션에 의해 읽힙니다.

다음 단계

중급: 큐와 잡

Laravel 큐 시스템의 기본적인 사용법을 배웁니다.

PHP Reflection API

Laravel이 어트리뷰트를 읽어 오기 위해 사용하는 Reflection API의 구조를 자세히 설명합니다.
마지막 수정일 2026년 7월 13일