1

我确信这个问题已经被问过很多次了,但我似乎找不到一个好的/令人满意的答案,所以请多多包涵。

使用 PHP 7.4+,我倾向于输入我能输入的所有内容。但是我对 Doctrine 实体属性有一些问题。

如果我输入正确,我通常会得到很多像这样的错误。

类型化属性 App\Entity\User::$createdAt 在初始化之前不能被访问

该类型错误的代码示例看起来像这样

/**
 * @var DateTimeInterface
 * @ORM\Column(type="datetime")
 */
protected DateTimeInterface $createdAt;

所以,我曾经使属性可以为空,即使数据库字段不是。所以它看起来像这样。

/**
 * @var DateTimeInterface|null
 * @ORM\Column(type="datetime")
 */
protected ?DateTimeInterface $createdAt = null;

但是,现在我有另一个问题。我决定在我的项目中实现一个静态代码分析器,现在我正在使用 PHPStan。所以现在,当我扫描我的代码时,我会遇到类似的错误。


行 src/Entity/Trait/TimestampableEntityPropertiesTrait.php(在 App\Entity\Article 类的上下文中)


16 属性 App\Entity\Article::$createdAt 类型映射不匹配:属性可以包含 DateTimeInterface|null 但数据库需要 DateTimeInterface。


那么,处理这种情况的正确方法是什么?

任何建议将不胜感激。

编辑

我应该提到有时,我不想/不能初始化构造函数中的属性,因为我还没有正确的值。

4

2 回答 2

1

我不确定这是否是一种不好的做法,但事实证明我只需要从 phpstan 配置中删除该检查。

# phpstan.neon
parameters:
  doctrine:
    allowNullablePropertyForRequiredField: true

编辑:

经过一番挖掘,我意识到我应该使用允许空值的 DTO,然后在准备好(并且有效)后将其传输到我的实体。这样,我的实体总是有效的,我不会冒险刷新数据库中的一些无效数据。

于 2021-10-17T02:30:38.917 回答
0

phpstan代码气味可能没有那么错……
实际的 Doctrine 注释将是nullable=true

/**
 * @ORM\Column(type="datetime", nullable=true)
 */

然后 ORM 将停止抱怨意外的NULL值。
没有它,created_at就会NOT NULL设置;因此它是“必需的”。

关键是,当它是 时nullable=true,就不再需要它了。
而当它不再需要时,phpstan也会停下来抱怨。

而另一方面,当phpstan在应用程序级别忽略这些冲突时allowNullablePropertyForRequiredField: true,这对基础数据库的影响为零,这将根据用于生成数据库表的注释拒绝记录。

于 2021-10-17T03:24:45.027 回答