생성자 속성 승격(Constructor Property Promotion)이란?
PHP 8에 새롭게 도입된 생성자 속성 승격은 간단한 객체를 생성할 때 반복해서 작성해야 했던 상용구(boilerplate) 코드를 크게 줄여 주는 기능입니다. 이 기능을 활용하면 클래스 속성 선언, 생성자 정의, 값 대입이라는 세 가지 작업을 생성자 매개변수 목록 안에서 한 번에 처리할 수 있습니다.
즉, 별도로 속성을 선언하고 생성자에서 일일이 대입하는 대신, 생성자 매개변수에 접근 제한자만 붙이면 모든 것을 하나의 문법으로 해결할 수 있습니다.
기존 방식: PHP 7 코드
<?php
class Account {
public float $a;
public float $b;
public float $c;
public function __construct(
float $a = 0.0,
float $b = 0.0,
float $c = 0.0,
) {
$this->a = $a;
$this->b = $b;
$this->c = $c;
}
}
?>
위 PHP 7 코드처럼 기존에는 속성을 먼저 선언한 뒤, 생성자에서 같은 의미의 매개변수를 받아 $this->로 다시 대입해야 했습니다. 속성이 많아질수록 코드가 길어지고, 변수명을 잘못 입력하는 등의 실수 가능성도 커집니다.
개선된 방식: PHP 8 코드
동일한 코드를 PHP 8의 생성자 속성 승격으로 다시 작성하면 다음과 같습니다.
<?php
class Account {
public function __construct(
public float $a = 0.0,
public float $b = 0.0,
public float $c = 0.0,
) {}
}
$account = new Account(10.90, 20.0, 30.80);
print_r($account->a);
print_r($account->b);
print_r($account->c);
?>
실행 결과
10.92030.8
매개변수 앞에 public 키워드만 붙이면 해당 매개변수가 곧바로 클래스 속성으로 승격됩니다. 별도의 속성 선언과 대입 코드가 모두 사라지면서 중복이 제거되고, 코드가 훨씬 간결해진 것을 확인할 수 있습니다.
실전 예제: Employee 클래스
<?php
class Employee {
public function __construct(
public int $id,
public string $name,
) {}
}
$employee = new Employee(11, 'Alex');
print_r($employee->id);
print_r($employee->name);
?>
실행 결과
11Alex
Employee 클래스는 생성자 딱 한 곳에서 속성 정의가 끝납니다. ID와 이름을 받아 객체를 만들고, 바로 외부에서 접근해 사용할 수 있습니다.
사용 시 알아두면 좋은 규칙
- 접근 제한자 필수: 속성을 승격하려면
public,protected,private중 하나를 반드시 명시해야 합니다. - 타입 선언: 타입은 선택 사항이지만, 명시하면 타입 안정성이 확보되어 더 안전한 코드가 됩니다.
- 기본값 설정: 매개변수에 기본값을 지정하면 객체 생성 시 해당 값을 생략할 수 있습니다.
- 제약 사항: 승격된 속성에는
callable타입을 사용할 수 없으며, 하나의 매개변수에 두 개 이상의 접근 제한자를 지정할 수 없습니다.
마무리
생성자 속성 승격은 DTO(데이터 전송 객체)나 값 객체처럼 데이터를 담는 용도의 클래스를 작성할 때 특히 빛을 발합니다. PHP 8 이상 환경이라면 반복적인 생성자 코드를 이 기능으로 정리해 가독성과 생산성을 동시에 높여 보세요.