생성자와 소멸자
생성자
__construct(mixed ...$values = ""): void
PHP를 사용하면 개발자가 클래스에 대한 생성자 메서드를 선언할 수 있습니다. 생성자 메서드가 있는 클래스는 새로 생성된 각 개체에서 이 메서드를 호출하므로 개체가 사용되기 전에 필요할 수 있는 초기화에 적합합니다.
메모: 자식 클래스가 생성자를 정의하는 경우 부모 생성자는 암시적으로 호출되지 않습니다. 부모 생성자를 실행하려면 자식 생성자 내에서 parent::__construct()를 호출해야 합니다. 자식이 생성자를 정의하지 않으면 일반 클래스 메서드와 마찬가지로 부모 클래스에서 상속될 수 있습니다(private으로 선언되지 않은 경우).
예제 #1 상속의 생성자
이 예제는 MyClass1.php 및 MyClass2.php 파일에서 각각 MyClass1 및 MyClass2 클래스를 로드하려고 시도합니다.
<?php
class BaseClass {
function __construct() {
print "In BaseClass constructor\n";
}
}
class SubClass extends BaseClass {
function __construct() {
parent::__construct();
print "In SubClass constructor\n";
}
}
class OtherSubClass extends BaseClass {
// inherits BaseClass's constructor
}
// In BaseClass constructor
$obj = new BaseClass();
// In BaseClass constructor
// In SubClass constructor
$obj = new SubClass();
// In BaseClass constructor
$obj = new OtherSubClass();
?>
다른 메서드와 달리 __construct()는 확장될 때 일반적인 서명 호환성 규칙에서 제외됩니다.
생성자는 해당 객체를 인스턴스화하는 동안 호출되는 일반적인 메서드입니다. 따라서, 그들은 필요할 수 있고, 유형을 가질 수 있고, 기본값을 가질 수 있는 임의의 수의 인수를 정의할 수 있습니다. 생성자 인수는 클래스 이름 뒤의 괄호 안에 인수를 배치하여 호출됩니다.
예제 #2 생성자 인수 사용
<?php
class Point {
protected int $x;
protected int $y;
public function __construct(int $x, int $y = 0) {
$this->x = $x;
$this->y = $y;
}
}
// Pass both parameters.
$p1 = new Point(4, 5);
// Pass only the required parameter. $y will take its default value of 0.
$p2 = new Point(4);
// With named parameters (as of PHP 8.0):
$p3 = new Point(y: 5, x: 4);
?>
클래스에 생성자가 없거나 생성자에 필수 인수가 없으면 괄호를 생략할 수 있습니다.
구식 생성자
PHP 8.0.0 이전에는 전역 네임스페이스의 클래스가 클래스와 동일한 이름의 메서드를 구식 생성자로 해석합니다. 해당 구문은 더 이상 사용되지 않으며 E_DEPRECATED
오류가 발생하지만 여전히 해당 함수를 생성자로 호출합니다. __construct()와 같은 이름의 메서드가 모두 정의되어 있으면 __construct()가 호출됩니다.
네임스페이스가 있는 클래스 또는 PHP 8.0.0의 모든 클래스에서 클래스와 동일한 이름의 메서드는 특별한 의미가 없습니다.
새 코드에서는 항상 __construct()를 사용하십시오.
Constructor Promotion
PHP 8.0.0부터 생성자 매개변수도 객체 속성에 해당하도록 승격될 수 있습니다. 생성자 매개변수가 생성자의 속성에 할당되지만 그렇지 않으면 작동되지 않는 것은 매우 일반적입니다. 생성자 승격은 해당 사용 사례에 대한 약칭을 제공합니다. 위의 예는 다음과 같이 다시 작성할 수 있습니다.
예제 #3 생성자 속성 승격 사용
<?php
class Point {
public function __construct(protected int $x, protected int $y = 0) {
}
}
생성자 인수에 가시성 수정자가 포함되어 있으면 PHP는 이를 객체 속성과 생성자 인수로 해석하고 속성에 인수 값을 할당합니다. 그러면 생성자 본문이 비어 있거나 다른 명령문이 포함될 수 있습니다. 인수 값이 해당 속성에 할당된 후에 추가 명령문이 실행됩니다.
모든 인수를 승격할 필요는 없습니다. 승격된 인수와 승격되지 않은 인수를 순서에 관계없이 혼합하여 일치시킬 수 있습니다. 승격된 인수는 생성자를 호출하는 코드에 영향을 주지 않습니다.
메모: 도입할 엔진 모호성으로 인해 개체 속성을 호출 가능한 형식으로 지정할 수 없습니다. 따라서 승격된 인수도 호출 가능하지 않을 수 있습니다. 그러나 다른 모든 유형 선언이 허용됩니다.
메모: 승격된 생성자 인수에 배치된 Attributes은 속성과 인수 모두에 복제됩니다.
정적 생성 방법
PHP는 클래스당 하나의 생성자만 지원합니다. 그러나 어떤 경우에는 개체가 다른 입력을 사용하여 다른 방식으로 구성되도록 하는 것이 바람직할 수 있습니다. 권장되는 방법은 정적 메서드를 생성자 래퍼로 사용하는 것입니다.
예제 #4 정적 생성 방법 사용
<?php
class Product {
private ?int $id;
private ?string $name;
private function __construct(?int $id = null, ?string $name = null) {
$this->id = $id;
$this->name = $name;
}
public static function fromBasicData(int $id, string $name): static {
$new = new static($id, $name);
return $new;
}
public static function fromJson(string $json): static {
$data = json_decode($json);
return new static($data['id'], $data['name']);
}
public static function fromXml(string $xml): static {
// Custom logic here.
$data = convert_xml_to_array($xml);
$new = new static();
$new->id = $data['id'];
$new->name = $data['name'];
return $new;
}
}
$p1 = Product::fromBasicData(5, 'Widget');
$p2 = Product::fromJson($some_json_string);
$p3 = Product::fromXml($some_xml_string);
생성자는 비공개로 만들거나 외부에서 호출되는 것을 방지하기 위해 보호될 수 있습니다. 그렇다면 정적 메서드만 클래스를 인스턴스화할 수 있습니다. 동일한 클래스 정의에 있기 때문에 동일한 개체 인스턴스가 아니더라도 개인 메서드에 액세스할 수 있습니다. 개인 생성자는 선택 사항이며 사용 사례에 따라 의미가 있을 수도 있고 그렇지 않을 수도 있습니다.
그런 다음 세 가지 공용 정적 메서드가 개체를 인스턴스화하는 다양한 방법을 보여줍니다.
-
fromBasicData()
는 필요한 정확한 매개변수를 취한 다음 생성자를 호출하고 결과를 반환하여 객체를 생성합니다. -
fromJson()
은 JSON 문자열을 받아들이고 자체적으로 사전 처리를 수행하여 생성자가 원하는 형식으로 변환합니다. 그런 다음 새 개체를 반환합니다. -
fromXml()
은 XML 문자열을 받아 사전 처리한 다음 베어 객체를 생성합니다. 생성자는 여전히 호출되지만 모든 매개변수가 선택사항이므로 메소드는 이를 건너뜁니다. 그런 다음 결과를 반환하기 직전에 개체 속성에 값을 할당합니다.
세 가지 경우 모두 static
키워드는 코드가 있는 클래스의 이름으로 변환됩니다. 이 경우에는 Product
.
소멸자(Destructor)
__destruct(): void
PHP는 C++와 같은 다른 객체 지향 언어와 유사한 소멸자 개념을 가지고 있습니다. 소멸자 메서드는 특정 개체에 대한 다른 참조가 없는 즉시 또는 종료 시퀀스 중에 임의의 순서로 호출됩니다.
예제 #3 소멸자 예제
<?php
class MyDestructableClass
{
function __construct() {
print "In constructor\n";
}
function __destruct() {
print "Destroying " . __CLASS__ . "\n";
}
}
$obj = new MyDestructableClass();
생성자와 마찬가지로 부모 소멸자는 엔진에 의해 암시적으로 호출되지 않습니다. 부모 소멸자를 실행하려면 소멸자 본문에서 명시적으로 parent::__destruct()를 호출해야 합니다. 또한 생성자와 마찬가지로 자식 클래스는 자체적으로 구현하지 않는 경우 부모의 소멸자를 상속할 수 있습니다.
소멸자는 exit()를 사용하여 스크립트 실행이 중지된 경우에도 호출됩니다. 소멸자에서 exit()를 호출하면 나머지 종료 루틴이 실행되지 않습니다.
메모: 스크립트 종료 중에 호출된 소멸자는 HTTP 헤더가 이미 전송되었습니다. 스크립트 종료 단계의 작업 디렉토리는 일부 SAPI(예: Apache)와 다를 수 있습니다.
메모: 소멸자(스크립트 종료 시 호출됨)에서 예외를 throw하려고 하면 치명적인 오류가 발생합니다.