gpt4 book ai didi

php - PHP 7.4+ 中的 "Typed property must not be accessed before initialization"错误

转载 作者:行者123 更新时间:2023-12-05 02:03:02 28 4
gpt4 key购买 nike

我正在使用 PHP 7.4 和属性类型提示。

假设我有一个 A 类,有几个私有(private)属性。当我使用\SoapClient、Doctrine ORM 或任何绕过构造函数实例化类并直接使用反射获取/设置属性的工具时,我遇到错误 PHP Fatal error: Uncaught Error: Typed property A::$id must在 中初始化之前不被访问。

<?php

declare(strict_types=1);

class A
{
private int $id;
private string $name;

public function __construct(int $id, string $name)
{
$this->id = $id;
$this->name = $name;
}

public function getId(): int
{
return $this->id;
}

public function getName(): string
{
return $this->name;
}
}

$a = (new \ReflectionClass(A::class))->newInstanceWithoutConstructor();

var_dump($a->getId()); // Fatal error: Uncaught Error: Typed property A::$id must not be accessed before initialization in ...

我可以通过将属性声明为可空值并默认设置空值来缓解这个问题。

<?php

declare(strict_types=1);

class A
{
private ?int $id = null;
private ?string $name = null;

public function __construct(?int $id, ?string $name)
{
$this->id = $id;
$this->name = $name;
}

public function getId(): ?int
{
return $this->id;
}

public function getName(): ?string
{
return $this->name;
}
}

$a = (new \ReflectionClass(A::class))->newInstanceWithoutConstructor();

var_dump($a->getId()); // NULL
var_dump($a->getName()); // NULL

但是,我不喜欢这种解决方法。我的类(class)的重点是要符合领域并将领域约束封装在类设计中。在这种情况下,属性 name 不应为空。可能我可以将属性 name 声明为空字符串,但这似乎也不是一个干净的解决方案。

<?php

declare(strict_types=1);

class A
{
private ?int $id = null;
private string $name = '';

public function __construct(?int $id, string $name)
{
$this->id = $id;
$this->name = $name;
}

public function getId(): ?int
{
return $this->id;
}

public function getName(): string
{
return $this->name;
}
}

$a = (new \ReflectionClass(A::class))->newInstanceWithoutConstructor();

var_dump($a->getId()); // NULL
var_dump($a->getName()); // ''

$idProperty = new \ReflectionProperty($a, 'id');
$idProperty->setAccessible(true);
if (null === $idProperty->getValue($a)) {
$idProperty->setValue($a, 1001);
}

$nameProperty = new \ReflectionProperty($a, 'name');
$nameProperty->setAccessible(true);
if ('' === $nameProperty->getValue($a)) {
$nameProperty->setValue($a, 'Name');
}

var_dump($a->getId()); // 1001
var_dump($a->getName()); // Name

我的问题是:有没有办法保持正确的类设计并避免遇到 Typed property must not be accessed before initialization 错误?如果否,解决此问题的首选方法是什么? (例如,将所有属性定义为可为空的空值或将字符串属性定义为空字符串等)

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com