Menu

PHP 생성자: __construct와 속성 승격

PHP 생성자는 new ClassName(...)을 쓸 때 자동으로 실행되는 __construct() 메서드입니다. 생성자 속성 승격, 기본값과 이름 있는 인수, 검증, parent::__construct(), 정적 팩토리 메서드로 여러 생성자를 흉내 내는 방법을 알아봅니다.

이 페이지에는 실행 가능한 에디터가 있습니다 - 편집하고 실행하면 결과를 바로 볼 수 있습니다.

PHP 생성자는 __construct()라는 이름의 메서드입니다. new ClassName(...)을 쓰면 PHP가 자동으로 호출하고, 괄호 안의 인수가 그 매개변수가 되므로 객체가 값이 이미 설정된 채로 시작합니다.

생성자가 없으면 빈 객체를 만든 뒤 속성을 하나씩 설정해야 하고, 하나를 빠뜨려도 막을 방법이 없습니다. 생성자가 있으면 인수 없는 new User()는 ArgumentCountError입니다.

생성자 속성 승격

속성을 선언하고, 매개변수로 나열하고, $this->name = $name으로 대입하면 각 이름을 세 번 반복하게 됩니다. PHP 8.0부터는 생성자 매개변수 앞의 접근 제어 키워드가 세 가지를 한 번에 합니다.

승격된 매개변수는 readonly일 수도 있으며(public readonly string $id), 불변 값 객체를 쓰는 가장 짧은 방법입니다. 승격된 매개변수와 일반 매개변수를 섞을 수 있고, 생성자 본문에는 승격된 속성이 대입된 뒤 실행되는 코드를 여전히 넣을 수 있습니다.

기본값과 이름 있는 인수

생성자 매개변수는 다른 함수처럼 기본값을 받습니다. 기본값이 있는 매개변수는 필수 매개변수 뒤에 옵니다. 이름 있는 인수(PHP 8.0)를 쓰면 호출하는 쪽이 앞의 기본값을 모두 반복하는 대신 원하는 옵션으로 바로 건너뛸 수 있습니다.

실행해 보세요. 출력에 HTML이 있으므로 Page 탭에는 렌더링된 버튼 세 개가, Output 탭에는 PHP가 출력한 태그가 보입니다. (new Button('Save'))->render()의 괄호에 주목하세요. PHP 8.4부터는 생략할 수 있지만 PHP 8.3에서는 필요합니다.

생성자에서 인수 검증하기

생성자는 false나 에러 코드를 반환할 수 없습니다. 무엇을 반환하든 무시됩니다. 잘못된 입력을 거부하려면 예외를 던지세요. 그러면 객체가 만들어지지 않으므로 프로그램의 나머지 부분은 받는 모든 Temperature를 믿을 수 있습니다.

이런 예외를 잡는 방법은 try catch 페이지에서 더 자세히 다룹니다.

정적 팩토리 메서드로 여러 생성자 만들기

PHP에는 생성자 오버로딩이 없습니다. 클래스 하나에 __construct 하나입니다. 날짜 문자열, 배열, 타임스탬프처럼 여러 입력으로 객체를 만들 수 있다면, 인수를 준비하고 new static(...)을 호출하는 이름 있는 정적 메서드를 추가하세요. 생성자를 private으로 만들면 모두가 팩토리를 거치게 됩니다.

이제 클래스 바깥에서 new Color(1, 2, 3)을 쓰면 Error("Call to private Color::__construct() from global scope")를 던집니다. 여기서 new self 대신 new static을 쓰는 이유는 static 페이지에서 설명합니다.

parent::__construct로 부모 생성자 호출하기

자식 클래스가 자체 생성자를 정의하면 부모의 생성자는 저절로 실행되지 않습니다. 자식이 자신의 속성을 추가하기 전에 부모의 속성이 설정되도록 parent::__construct(...)로 호출하세요. 보통 가장 먼저 호출합니다.

자식에 생성자가 전혀 없으면 PHP는 부모의 것을 쓰고, new Truck('Volvo')는 인수를 Vehicle::__construct에 바로 넘깁니다. 자세한 내용은 상속에서 다룹니다.

parent::__construct 빠뜨리기

이 실수는 그것이 일어난 줄에서 에러를 내지 않습니다. 자식 생성자가 실행되고, 부모의 타입 있는 속성은 초기화되지 않은 채 남으며, 프로그램은 나중에 처음 읽는 곳에서 실패합니다.

Post::__construct의 첫 줄에 parent::__construct();를 추가하고 다시 실행하면 날짜가 출력됩니다. 관련 메서드인 __destruct()는 객체에 대한 마지막 참조가 사라지거나 스크립트가 끝날 때 실행됩니다. PHP가 매 요청 끝에 파일을 닫고 메모리를 스스로 해제하므로 일상적인 코드에서는 거의 필요 없습니다.

자주 묻는 질문

PHP에서 __construct는 무엇인가요?

__construct()는 생성자입니다. new가 객체를 만든 직후 PHP가 자동으로 호출하는 메서드입니다. new User('Ada', 36)에 넘긴 인수는 __construct(string $name, int $age)에 전달되며, 보통 이를 속성에 저장합니다.

PHP의 생성자 속성 승격은 무엇인가요?

PHP 8.0부터 생성자 매개변수에 접근 제어 키워드를 붙이면 속성 선언과 대입을 한 번에 합니다. public function __construct(private string $name) {}는 private string $name;을 선언하고 본문에 $this->name = $name;을 쓰는 것과 같습니다.

PHP 클래스에 생성자가 여러 개 있을 수 있나요?

아니요. PHP에는 메서드 오버로딩이 없으므로 클래스에는 __construct가 하나입니다. 기본값이 있는 선택적 매개변수를 쓰거나, 올바른 인수로 new static(...)을 호출하는 public static function fromArray(array $data): static 같은 정적 팩토리 메서드를 추가하세요.

PHP에서 부모 생성자는 자동으로 호출되나요?

자식 클래스에 자체 생성자가 없을 때만 그렇습니다. 자식이 __construct를 정의하면, 직접 parent::__construct(...)를 호출하지 않는 한 부모의 생성자는 실행되지 않습니다. 보통 첫 줄에서 호출합니다.

PHP 생성자가 값을 반환할 수 있나요?

아니요. new는 항상 객체를 주며, __construct가 반환하는 것은 무시됩니다. 문제를 알리려면 생성자에서 예외를 던지세요. 예: throw new InvalidArgumentException('Age must be positive').

Coddy 프로그래밍 언어 일러스트

Coddy로 코딩 배우기

시작하기