속성 유형 힌트를 소개할 때 갑자기 “초기화 전에 Typed properties must accessed before initialization” 오류가 나타나는 이유는 무엇입니까?

새로 도입된 속성 유형 힌트를 활용하기 위해 클래스 정의를 다음과 같이 업데이트했습니다.

class Foo {
private int $id;
private ?string $val;
private DateTimeInterface $createdAt;
private ?DateTimeInterface $updatedAt;
public function __construct(int $id) {
$this->id = $id;
}
public function getId(): int { return $this->id; }
public function getVal(): ?string { return $this->val; }
public function getCreatedAt(): ?DateTimeInterface { return $this->createdAt; }
public function getUpdatedAt(): ?DateTimeInterface { return $this->updatedAt; }
public function setVal(?string $val) { $this->val = $val; }
public function setCreatedAt(DateTimeInterface $date) { $this->createdAt = $date; }
public function setUpdatedAt(DateTimeInterface $date) { $this->updatedAt = $date; } } 

그러나 독트린에서 엔티티를 구하려고 하면 다음과 같은 오류가 발생합니다.

초기화 전에 입력된 속성에 액세스해서는 안 됩니다.

이 문제는 다음 작업에서만 발생하는 것이 아닙니다.$id또는$createdAt에도 발생합니다.$value또는$updatedAt는 늘 가능한 속성입니다.



질문에 대한 답변



PHP 7.4에는 속성에 대한 유형 힌트가 도입되어 있기 때문에 모든 속성에 대해 유효한 값을 제공하는 것이 특히 중요합니다.그러면 모든 속성이 선언된 유형과 일치하는 값을 가질 수 있습니다.

할당되지 않은 속성에는 다음이 없습니다.null가치, 단, 가치,undefinedstate: 선언된 유형과 일치하지 않습니다. undefined !== null.

위의 코드의 경우, 다음을 수행합니다.

$f = new Foo(1); $f->getVal(); 

다음과 같은 것이 있습니다.

치명적인 오류:검출되지 않은 오류:초기화하기 전에 Foo::$val에 액세스할 수 없습니다.

부터$val둘 다 아니다string도 아니다null액세스 할 때 사용합니다.

이를 회피하는 방법은 선언된 유형과 일치하는 모든 속성에 값을 할당하는 것입니다.기본 설정 및 속성 유형에 따라 특성에 대한 기본값으로 또는 구성 중에 이 작업을 수행할 수 있습니다.

예를 들어 위의 경우 다음을 수행할 수 있습니다.

class Foo {
private int $id;
private ?string $val = null; // <-- declaring default null value for the property
private Collection $collection;
private DateTimeInterface $createdAt;
private ?DateTimeInterface $updatedAt;
public function __construct(int $id) {
// and on the constructor we set the default values for all the other
// properties, so now the instance is on a valid state
$this->id = $id;
$this->createdAt = new DateTimeImmutable();
$this->updatedAt = new DateTimeImmutable();
$this->collection = new ArrayCollection();
} 

모든 속성이 유효한 값을 가지며 인스턴스가 유효한 상태가 됩니다.

이것은 특히 엔티티 값을 DB에서 가져온 값에 의존하는 경우에 자주 발생할 수 있습니다.예를 들어, 자동 생성된 ID 또는 생성 및/또는 업데이트된 값입니다. 이러한 ID는 종종 DB 문제로 남습니다.

자동 생성된 ID의 경우 유형 선언을 다음과 같이 변경하는 것이 좋습니다.

private ?int $id = null 

나머지 모든 경우 속성 유형에 적합한 값을 선택하십시오.




null 유형 속성의 경우 구문을 사용해야 합니다.

private ?string $val = null;

그렇지 않으면 치명적인 오류가 발생합니다.

이 컨셉은 불필요한 치명적인 오류로 이어지기 때문에 버그리포트 https://bugs.php.net/bug.php?id=79620를 작성했습니다.실패는 없었지만, 적어도 시도는 했습니다.